Skip to content

Commit

Permalink
Set Headers when using gRPC
Browse files Browse the repository at this point in the history
  • Loading branch information
marctc committed Feb 26, 2025
1 parent b91e8c2 commit d593f9b
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
7 changes: 7 additions & 0 deletions pkg/export/otel/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ type otlpOptions struct {
URLPath string
SkipTLSVerify bool
HTTPHeaders map[string]string
GRPCHeaders map[string]string
}

func (o *otlpOptions) AsMetricHTTP() []otlpmetrichttp.Option {
Expand Down Expand Up @@ -261,6 +262,9 @@ func (o *otlpOptions) AsMetricGRPC() []otlpmetricgrpc.Option {
if o.SkipTLSVerify {
opts = append(opts, otlpmetricgrpc.WithTLSCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})))
}
if len(o.GRPCHeaders) > 0 {
opts = append(opts, otlpmetricgrpc.WithHeaders(o.GRPCHeaders))
}
return opts
}

Expand Down Expand Up @@ -293,6 +297,9 @@ func (o *otlpOptions) AsTraceGRPC() []otlptracegrpc.Option {
if o.SkipTLSVerify {
opts = append(opts, otlptracegrpc.WithTLSCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})))
}
if len(o.GRPCHeaders) > 0 {
opts = append(opts, otlptracegrpc.WithHeaders(o.GRPCHeaders))
}
return opts
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/export/otel/traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ func getTracesExporter(ctx context.Context, cfg TracesConfig, ctxInfo *global.Co
Insecure: opts.Insecure,
InsecureSkipVerify: cfg.InsecureSkipVerify,
},
Headers: convertHeaders(opts.GRPCHeaders),
}
set := getTraceSettings(ctxInfo, t)
return factory.CreateTraces(ctx, set, config)
Expand Down Expand Up @@ -797,7 +798,7 @@ func getHTTPTracesEndpointOptions(cfg *TracesConfig) (otlpOptions, error) {
}

func getGRPCTracesEndpointOptions(cfg *TracesConfig) (otlpOptions, error) {
opts := otlpOptions{}
opts := otlpOptions{GRPCHeaders: map[string]string{}}
log := tlog().With("transport", "grpc")
murl, _, err := parseTracesEndpoint(cfg)
if err != nil {
Expand All @@ -816,7 +817,8 @@ func getGRPCTracesEndpointOptions(cfg *TracesConfig) (otlpOptions, error) {
log.Debug("Setting InsecureSkipVerify")
opts.SkipTLSVerify = true
}

maps.Copy(opts.GRPCHeaders, headersFromEnv(envHeaders))
maps.Copy(opts.GRPCHeaders, headersFromEnv(envTracesHeaders))
return opts, nil
}

Expand Down
57 changes: 52 additions & 5 deletions pkg/export/otel/traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func TestGRPCTracesEndpointOptions(t *testing.T) {
}

t.Run("testing with two endpoints", func(t *testing.T) {
testTracesGRPOptions(t, otlpOptions{Endpoint: "localhost:3232"}, &tcfg)
testTracesGRPCOptions(t, otlpOptions{Endpoint: "localhost:3232", GRPCHeaders: map[string]string{}}, &tcfg)
})

tcfg = TracesConfig{
Expand All @@ -209,7 +209,7 @@ func TestGRPCTracesEndpointOptions(t *testing.T) {
}

t.Run("testing with only common endpoint", func(t *testing.T) {
testTracesGRPOptions(t, otlpOptions{Endpoint: "localhost:3131"}, &tcfg)
testTracesGRPCOptions(t, otlpOptions{Endpoint: "localhost:3131", GRPCHeaders: map[string]string{}}, &tcfg)
})

tcfg = TracesConfig{
Expand All @@ -218,7 +218,7 @@ func TestGRPCTracesEndpointOptions(t *testing.T) {
Instrumentations: []string{instrumentations.InstrumentationALL},
}
t.Run("testing with insecure endpoint", func(t *testing.T) {
testTracesGRPOptions(t, otlpOptions{Endpoint: "localhost:3232", Insecure: true}, &tcfg)
testTracesGRPCOptions(t, otlpOptions{Endpoint: "localhost:3232", Insecure: true, GRPCHeaders: map[string]string{}}, &tcfg)
})

tcfg = TracesConfig{
Expand All @@ -228,11 +228,58 @@ func TestGRPCTracesEndpointOptions(t *testing.T) {
}

t.Run("testing with skip TLS verification", func(t *testing.T) {
testTracesGRPOptions(t, otlpOptions{Endpoint: "localhost:3232", SkipTLSVerify: true}, &tcfg)
testTracesGRPCOptions(t, otlpOptions{Endpoint: "localhost:3232", SkipTLSVerify: true, GRPCHeaders: map[string]string{}}, &tcfg)
})
}

func testTracesGRPOptions(t *testing.T, expected otlpOptions, tcfg *TracesConfig) {
func TestGRPCTracesEndpointHeaders(t *testing.T) {
type testCase struct {
Description string
Env map[string]string
ExpectedHeaders map[string]string
Grafana GrafanaOTLP
}
for _, tc := range []testCase{
{Description: "No headers",
ExpectedHeaders: map[string]string{}},
{Description: "defining common OTLP_HEADERS",
Env: map[string]string{"OTEL_EXPORTER_OTLP_HEADERS": "Foo=Bar ==,Authorization=Base 2222=="},
ExpectedHeaders: map[string]string{"Foo": "Bar ==", "Authorization": "Base 2222=="}},
{Description: "defining common OTLP_TRACES_HEADERS",
Env: map[string]string{"OTEL_EXPORTER_OTLP_TRACES_HEADERS": "Foo=Bar ==,Authorization=Base 1234=="},
ExpectedHeaders: map[string]string{"Foo": "Bar ==", "Authorization": "Base 1234=="}},
{Description: "OTLP_TRACES_HEADERS takes precedence over OTLP_HEADERS",
Env: map[string]string{
"OTEL_EXPORTER_OTLP_HEADERS": "Foo=Bar ==,Authorization=Base 3210==",
"OTEL_EXPORTER_OTLP_TRACES_HEADERS": "Authorization=Base 1111==",
},
ExpectedHeaders: map[string]string{"Foo": "Bar ==", "Authorization": "Base 1111=="}},
} {
// mutex to avoid running testcases in parallel so we don't mess up with env vars
mt := sync.Mutex{}
t.Run(fmt.Sprint(tc.Description), func(t *testing.T) {
mt.Lock()
restore := restoreEnvAfterExecution()
defer func() {
restore()
mt.Unlock()
}()
for k, v := range tc.Env {
require.NoError(t, os.Setenv(k, v))
}

opts, err := getGRPCTracesEndpointOptions(&TracesConfig{
TracesEndpoint: "https://localhost:1234/v1/traces",
Grafana: &tc.Grafana,
Instrumentations: []string{instrumentations.InstrumentationALL},
})
require.NoError(t, err)
assert.Equal(t, tc.ExpectedHeaders, opts.GRPCHeaders)
})
}
}

func testTracesGRPCOptions(t *testing.T, expected otlpOptions, tcfg *TracesConfig) {
defer restoreEnvAfterExecution()()
opts, err := getGRPCTracesEndpointOptions(tcfg)
require.NoError(t, err)
Expand Down

0 comments on commit d593f9b

Please sign in to comment.