Plugins: Pass OTEL sampling config to plugins (#76834)
* Pass OTEL sampling config to plugins * fix capital letters * Do not pass sampler env vars if sampling is not configured * Add tests * PR review feedback * Simplify tracing env vars logic * Update test to reflect pkg/infra/tracing behaviour
This commit is contained in:
@@ -9,6 +9,10 @@ type Tracing struct {
|
||||
type OpenTelemetryCfg struct {
|
||||
Address string
|
||||
Propagation string
|
||||
|
||||
Sampler string
|
||||
SamplerParam float64
|
||||
SamplerRemoteURL string
|
||||
}
|
||||
|
||||
// IsEnabled returns true if OTLP tracing is enabled (address set)
|
||||
|
||||
@@ -179,6 +179,10 @@ func (s *Service) tracingEnvVars(plugin *plugins.Plugin) []string {
|
||||
vars := []string{
|
||||
fmt.Sprintf("GF_INSTANCE_OTLP_ADDRESS=%s", s.cfg.Tracing.OpenTelemetry.Address),
|
||||
fmt.Sprintf("GF_INSTANCE_OTLP_PROPAGATION=%s", s.cfg.Tracing.OpenTelemetry.Propagation),
|
||||
|
||||
fmt.Sprintf("GF_INSTANCE_OTLP_SAMPLER_TYPE=%s", s.cfg.Tracing.OpenTelemetry.Sampler),
|
||||
fmt.Sprintf("GF_INSTANCE_OTLP_SAMPLER_PARAM=%.6f", s.cfg.Tracing.OpenTelemetry.SamplerParam),
|
||||
fmt.Sprintf("GF_INSTANCE_OTLP_SAMPLER_REMOTE_URL=%s", s.cfg.Tracing.OpenTelemetry.SamplerRemoteURL),
|
||||
}
|
||||
if plugin.Info.Version != "" {
|
||||
vars = append(vars, fmt.Sprintf("GF_PLUGIN_VERSION=%s", plugin.Info.Version))
|
||||
|
||||
@@ -173,6 +173,11 @@ func TestInitializer_tracingEnvironmentVariables(t *testing.T) {
|
||||
OpenTelemetry: config.OpenTelemetryCfg{
|
||||
Address: "127.0.0.1:4317",
|
||||
Propagation: "w3c",
|
||||
|
||||
// Sensible default values for the sampler set by pkg/infra/tracing while reading config.ini
|
||||
Sampler: "",
|
||||
SamplerParam: 1.0,
|
||||
SamplerRemoteURL: "",
|
||||
},
|
||||
},
|
||||
PluginSettings: map[string]map[string]string{
|
||||
@@ -181,12 +186,15 @@ func TestInitializer_tracingEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
plugin: defaultPlugin,
|
||||
exp: func(t *testing.T, envVars []string) {
|
||||
assert.Len(t, envVars, 5)
|
||||
assert.Len(t, envVars, 8)
|
||||
assert.Equal(t, "GF_PLUGIN_TRACING=true", envVars[0])
|
||||
assert.Equal(t, "GF_VERSION=", envVars[1])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_ADDRESS=127.0.0.1:4317", envVars[2])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_PROPAGATION=w3c", envVars[3])
|
||||
assert.Equal(t, "GF_PLUGIN_VERSION=1.0.0", envVars[4])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_SAMPLER_TYPE=", envVars[4])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_SAMPLER_PARAM=1.000000", envVars[5])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_SAMPLER_REMOTE_URL=", envVars[6])
|
||||
assert.Equal(t, "GF_PLUGIN_VERSION=1.0.0", envVars[7])
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -196,6 +204,11 @@ func TestInitializer_tracingEnvironmentVariables(t *testing.T) {
|
||||
OpenTelemetry: config.OpenTelemetryCfg{
|
||||
Address: "127.0.0.1:4317",
|
||||
Propagation: "w3c,jaeger",
|
||||
|
||||
// Sensible default values for the sampler set by pkg/infra/tracing while reading config.ini
|
||||
Sampler: "",
|
||||
SamplerParam: 1.0,
|
||||
SamplerRemoteURL: "",
|
||||
},
|
||||
},
|
||||
PluginSettings: map[string]map[string]string{
|
||||
@@ -204,12 +217,15 @@ func TestInitializer_tracingEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
plugin: defaultPlugin,
|
||||
exp: func(t *testing.T, envVars []string) {
|
||||
assert.Len(t, envVars, 5)
|
||||
assert.Len(t, envVars, 8)
|
||||
assert.Equal(t, "GF_PLUGIN_TRACING=true", envVars[0])
|
||||
assert.Equal(t, "GF_VERSION=", envVars[1])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_ADDRESS=127.0.0.1:4317", envVars[2])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_PROPAGATION=w3c,jaeger", envVars[3])
|
||||
assert.Equal(t, "GF_PLUGIN_VERSION=1.0.0", envVars[4])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_SAMPLER_TYPE=", envVars[4])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_SAMPLER_PARAM=1.000000", envVars[5])
|
||||
assert.Equal(t, "GF_INSTANCE_OTLP_SAMPLER_REMOTE_URL=", envVars[6])
|
||||
assert.Equal(t, "GF_PLUGIN_VERSION=1.0.0", envVars[7])
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -297,6 +313,111 @@ func TestInitializer_tracingEnvironmentVariables(t *testing.T) {
|
||||
plugin: pluginWithoutVersion,
|
||||
exp: expGfPluginVersionNotPresent,
|
||||
},
|
||||
{
|
||||
name: "no sampling (neversample)",
|
||||
cfg: &config.Cfg{
|
||||
Tracing: config.Tracing{
|
||||
OpenTelemetry: config.OpenTelemetryCfg{
|
||||
Address: "127.0.0.1:4317",
|
||||
Propagation: "jaeger",
|
||||
Sampler: "",
|
||||
SamplerParam: 0.0,
|
||||
SamplerRemoteURL: "",
|
||||
},
|
||||
},
|
||||
PluginSettings: map[string]map[string]string{pluginID: {"tracing": "true"}},
|
||||
},
|
||||
plugin: defaultPlugin,
|
||||
exp: func(t *testing.T, envVars []string) {
|
||||
require.Empty(t, getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_TYPE"))
|
||||
require.Equal(t, "0.000000", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_PARAM"))
|
||||
require.Empty(t, getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_REMOTE_URL"))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty sampler with param",
|
||||
cfg: &config.Cfg{
|
||||
Tracing: config.Tracing{
|
||||
OpenTelemetry: config.OpenTelemetryCfg{
|
||||
Address: "127.0.0.1:4317",
|
||||
Propagation: "jaeger",
|
||||
Sampler: "",
|
||||
SamplerParam: 0.5,
|
||||
SamplerRemoteURL: "",
|
||||
},
|
||||
},
|
||||
PluginSettings: map[string]map[string]string{pluginID: {"tracing": "true"}},
|
||||
},
|
||||
plugin: defaultPlugin,
|
||||
exp: func(t *testing.T, envVars []string) {
|
||||
require.Equal(t, "", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_TYPE"))
|
||||
require.Equal(t, "0.500000", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_PARAM"))
|
||||
require.Equal(t, "", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_REMOTE_URL"))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "const sampler with param",
|
||||
cfg: &config.Cfg{
|
||||
Tracing: config.Tracing{
|
||||
OpenTelemetry: config.OpenTelemetryCfg{
|
||||
Address: "127.0.0.1:4317",
|
||||
Propagation: "jaeger",
|
||||
Sampler: "const",
|
||||
SamplerParam: 0.5,
|
||||
SamplerRemoteURL: "",
|
||||
},
|
||||
},
|
||||
PluginSettings: map[string]map[string]string{pluginID: {"tracing": "true"}},
|
||||
},
|
||||
plugin: defaultPlugin,
|
||||
exp: func(t *testing.T, envVars []string) {
|
||||
require.Equal(t, "const", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_TYPE"))
|
||||
require.Equal(t, "0.500000", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_PARAM"))
|
||||
require.Equal(t, "", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_REMOTE_URL"))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "rateLimiting sampler",
|
||||
cfg: &config.Cfg{
|
||||
Tracing: config.Tracing{
|
||||
OpenTelemetry: config.OpenTelemetryCfg{
|
||||
Address: "127.0.0.1:4317",
|
||||
Propagation: "jaeger",
|
||||
Sampler: "rateLimiting",
|
||||
SamplerParam: 0.5,
|
||||
SamplerRemoteURL: "",
|
||||
},
|
||||
},
|
||||
PluginSettings: map[string]map[string]string{pluginID: {"tracing": "true"}},
|
||||
},
|
||||
plugin: defaultPlugin,
|
||||
exp: func(t *testing.T, envVars []string) {
|
||||
require.Equal(t, "rateLimiting", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_TYPE"))
|
||||
require.Equal(t, "0.500000", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_PARAM"))
|
||||
require.Equal(t, "", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_REMOTE_URL"))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remote sampler",
|
||||
cfg: &config.Cfg{
|
||||
Tracing: config.Tracing{
|
||||
OpenTelemetry: config.OpenTelemetryCfg{
|
||||
Address: "127.0.0.1:4317",
|
||||
Propagation: "jaeger",
|
||||
Sampler: "remote",
|
||||
SamplerParam: 0.5,
|
||||
SamplerRemoteURL: "127.0.0.1:10001",
|
||||
},
|
||||
},
|
||||
PluginSettings: map[string]map[string]string{pluginID: {"tracing": "true"}},
|
||||
},
|
||||
plugin: defaultPlugin,
|
||||
exp: func(t *testing.T, envVars []string) {
|
||||
require.Equal(t, "remote", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_TYPE"))
|
||||
require.Equal(t, "0.500000", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_PARAM"))
|
||||
require.Equal(t, "127.0.0.1:10001", getEnvVar(envVars, "GF_INSTANCE_OTLP_SAMPLER_REMOTE_URL"))
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
envVarsProvider := NewProvider(tc.cfg, nil)
|
||||
@@ -306,6 +427,32 @@ func TestInitializer_tracingEnvironmentVariables(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// getEnvVarWithExists takes a slice of strings in this format: "K=V" (env vars), and returns the "V" where K = wanted.
|
||||
// If there's no such key, it returns false as the second argument.
|
||||
func getEnvVarWithExists(vars []string, wanted string) (string, bool) {
|
||||
for _, v := range vars {
|
||||
parts := strings.SplitN(v, "=", 2)
|
||||
if parts[0] != wanted {
|
||||
continue
|
||||
}
|
||||
var r string
|
||||
if len(parts) < 2 {
|
||||
r = ""
|
||||
} else {
|
||||
r = parts[1]
|
||||
}
|
||||
return r, true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// getEnvVar is like getEnvVarWithExists, but it returns just one string, without the boolean "ok" value.
|
||||
// If the wanted environment variable does not exist, it returns an empty string.
|
||||
func getEnvVar(vars []string, wanted string) string {
|
||||
v, _ := getEnvVarWithExists(vars, wanted)
|
||||
return v
|
||||
}
|
||||
|
||||
func TestInitializer_authEnvVars(t *testing.T) {
|
||||
t.Run("backend datasource with auth registration", func(t *testing.T) {
|
||||
p := &plugins.Plugin{
|
||||
|
||||
Reference in New Issue
Block a user