Skip to content

Commit b665425

Browse files
authored
otlpmetrichttp: Add WithHTTPClient option (#6752)
Follows #6688 Towards (for OTLP metric exporter): - #4536 - #5129 - #2632
1 parent d468af2 commit b665425

File tree

10 files changed

+147
-24
lines changed

10 files changed

+147
-24
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1616
See the [migration documentation](./semconv/v1.31.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.30.0`(#6479)
1717
- Add `Recording`, `Scope`, and `Record` types in `go.opentelemetry.io/otel/log/logtest`. (#6507)
1818
- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6688)
19+
- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#6752)
1920

2021
### Removed
2122

exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go

Lines changed: 13 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options_test.go

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporters/otlp/otlpmetric/otlpmetrichttp/client.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,23 @@ var ourTransport = &http.Transport{
5555

5656
// newClient creates a new HTTP metric client.
5757
func newClient(cfg oconf.Config) (*client, error) {
58-
httpClient := &http.Client{
59-
Transport: ourTransport,
60-
Timeout: cfg.Metrics.Timeout,
61-
}
58+
httpClient := cfg.Metrics.HTTPClient
59+
if httpClient == nil {
60+
httpClient = &http.Client{
61+
Transport: ourTransport,
62+
Timeout: cfg.Metrics.Timeout,
63+
}
6264

63-
if cfg.Metrics.TLSCfg != nil || cfg.Metrics.Proxy != nil {
64-
clonedTransport := ourTransport.Clone()
65-
httpClient.Transport = clonedTransport
65+
if cfg.Metrics.TLSCfg != nil || cfg.Metrics.Proxy != nil {
66+
clonedTransport := ourTransport.Clone()
67+
httpClient.Transport = clonedTransport
6668

67-
if cfg.Metrics.TLSCfg != nil {
68-
clonedTransport.TLSClientConfig = cfg.Metrics.TLSCfg
69-
}
70-
if cfg.Metrics.Proxy != nil {
71-
clonedTransport.Proxy = cfg.Metrics.Proxy
69+
if cfg.Metrics.TLSCfg != nil {
70+
clonedTransport.TLSClientConfig = cfg.Metrics.TLSCfg
71+
}
72+
if cfg.Metrics.Proxy != nil {
73+
clonedTransport.Proxy = cfg.Metrics.Proxy
74+
}
7275
}
7376
}
7477

exporters/otlp/otlpmetric/otlpmetrichttp/client_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,28 @@ func TestConfig(t *testing.T) {
254254
})
255255

256256
t.Run("WithProxy", func(t *testing.T) {
257+
headerKeySetInProxy := http.CanonicalHeaderKey("X-Using-Proxy")
258+
headerValueSetInProxy := "true"
259+
exp, coll := factoryFunc("", nil, WithHTTPClient(&http.Client{
260+
Transport: &http.Transport{
261+
Proxy: func(r *http.Request) (*url.URL, error) {
262+
r.Header.Set(headerKeySetInProxy, headerValueSetInProxy)
263+
return r.URL, nil
264+
},
265+
},
266+
}))
267+
ctx := context.Background()
268+
t.Cleanup(func() { require.NoError(t, coll.Shutdown(ctx)) })
269+
require.NoError(t, exp.Export(ctx, &metricdata.ResourceMetrics{}))
270+
// Ensure everything is flushed.
271+
require.NoError(t, exp.Shutdown(ctx))
272+
273+
got := coll.Headers()
274+
require.Contains(t, got, headerKeySetInProxy)
275+
assert.Equal(t, []string{headerValueSetInProxy}, got[headerKeySetInProxy])
276+
})
277+
278+
t.Run("WithHTTPClient", func(t *testing.T) {
257279
headerKeySetInProxy := http.CanonicalHeaderKey("X-Using-Proxy")
258280
headerValueSetInProxy := "true"
259281
exp, coll := factoryFunc("", nil, WithProxy(func(r *http.Request) (*url.URL, error) {

exporters/otlp/otlpmetric/otlpmetrichttp/config.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,19 @@ func WithAggregationSelector(selector metric.AggregationSelector) Option {
222222
func WithProxy(pf HTTPTransportProxyFunc) Option {
223223
return wrappedOption{oconf.WithProxy(oconf.HTTPTransportProxyFunc(pf))}
224224
}
225+
226+
// WithHTTPClient sets the HTTP client to used by the exporter.
227+
//
228+
// This option will take precedence over [WithProxy], [WithTimeout],
229+
// [WithTLSClientConfig] options as well as OTEL_EXPORTER_OTLP_CERTIFICATE,
230+
// OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, OTEL_EXPORTER_OTLP_TIMEOUT,
231+
// OTEL_EXPORTER_OTLP_METRICS_TIMEOUT environment variables.
232+
//
233+
// Timeout and all other fields of the passed [http.Client] are left intact.
234+
//
235+
// Be aware that passing an HTTP client with transport like
236+
// [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewTransport] can
237+
// cause the client to be instrumented twice and cause infinite recursion.
238+
func WithHTTPClient(c *http.Client) Option {
239+
return wrappedOption{oconf.WithHTTPClient(c)}
240+
}

exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go

Lines changed: 13 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options_test.go

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/shared/otlp/otlpmetric/oconf/options.go.tmpl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ type (
5757
Timeout time.Duration
5858
URLPath string
5959

60-
// gRPC configurations
61-
GRPCCredentials credentials.TransportCredentials
62-
6360
TemporalitySelector metric.TemporalitySelector
6461
AggregationSelector metric.AggregationSelector
6562

66-
Proxy HTTPTransportProxyFunc
63+
// gRPC configurations
64+
GRPCCredentials credentials.TransportCredentials
65+
66+
// HTTP configurations
67+
Proxy HTTPTransportProxyFunc
68+
HTTPClient *http.Client
6769
}
6870

6971
Config struct {
@@ -373,3 +375,10 @@ func WithProxy(pf HTTPTransportProxyFunc) GenericOption {
373375
return cfg
374376
})
375377
}
378+
379+
func WithHTTPClient(c *http.Client) GenericOption {
380+
return newGenericOption(func(cfg Config) Config {
381+
cfg.Metrics.HTTPClient = c
382+
return cfg
383+
})
384+
}

internal/shared/otlp/otlpmetric/oconf/options_test.go.tmpl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,24 @@ func TestConfigs(t *testing.T) {
533533
assert.Nil(t, c.Metrics.Proxy)
534534
},
535535
},
536+
537+
// HTTP Client Tests
538+
{
539+
name: "Test With HTTP Client",
540+
opts: []GenericOption{
541+
WithHTTPClient(http.DefaultClient),
542+
},
543+
asserts: func(t *testing.T, c *Config, grpcOption bool) {
544+
assert.Equal(t, http.DefaultClient, c.Metrics.HTTPClient)
545+
},
546+
},
547+
{
548+
name: "Test Without HTTP Client",
549+
opts: []GenericOption{},
550+
asserts: func(t *testing.T, c *Config, grpcOption bool) {
551+
assert.Nil(t, c.Metrics.HTTPClient)
552+
},
553+
},
536554
}
537555

538556
for _, tt := range tests {

0 commit comments

Comments
 (0)