1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-08-10 22:31:50 +02:00
Robert Pająk
2025-05-13 20:58:06 +02:00
committed by GitHub
parent d468af20c9
commit b66542529a
10 changed files with 148 additions and 25 deletions

View File

@@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
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)
- Add `Recording`, `Scope`, and `Record` types in `go.opentelemetry.io/otel/log/logtest`. (#6507)
- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6688)
- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#6752)
### Removed

View File

@@ -57,13 +57,15 @@ type (
Timeout time.Duration
URLPath string
// gRPC configurations
GRPCCredentials credentials.TransportCredentials
TemporalitySelector metric.TemporalitySelector
AggregationSelector metric.AggregationSelector
Proxy HTTPTransportProxyFunc
// gRPC configurations
GRPCCredentials credentials.TransportCredentials
// HTTP configurations
Proxy HTTPTransportProxyFunc
HTTPClient *http.Client
}
Config struct {
@@ -373,3 +375,10 @@ func WithProxy(pf HTTPTransportProxyFunc) GenericOption {
return cfg
})
}
func WithHTTPClient(c *http.Client) GenericOption {
return newGenericOption(func(cfg Config) Config {
cfg.Metrics.HTTPClient = c
return cfg
})
}

View File

@@ -533,6 +533,24 @@ func TestConfigs(t *testing.T) {
assert.Nil(t, c.Metrics.Proxy)
},
},
// HTTP Client Tests
{
name: "Test With HTTP Client",
opts: []GenericOption{
WithHTTPClient(http.DefaultClient),
},
asserts: func(t *testing.T, c *Config, grpcOption bool) {
assert.Equal(t, http.DefaultClient, c.Metrics.HTTPClient)
},
},
{
name: "Test Without HTTP Client",
opts: []GenericOption{},
asserts: func(t *testing.T, c *Config, grpcOption bool) {
assert.Nil(t, c.Metrics.HTTPClient)
},
},
}
for _, tt := range tests {

View File

@@ -55,20 +55,23 @@ var ourTransport = &http.Transport{
// newClient creates a new HTTP metric client.
func newClient(cfg oconf.Config) (*client, error) {
httpClient := &http.Client{
Transport: ourTransport,
Timeout: cfg.Metrics.Timeout,
}
if cfg.Metrics.TLSCfg != nil || cfg.Metrics.Proxy != nil {
clonedTransport := ourTransport.Clone()
httpClient.Transport = clonedTransport
if cfg.Metrics.TLSCfg != nil {
clonedTransport.TLSClientConfig = cfg.Metrics.TLSCfg
httpClient := cfg.Metrics.HTTPClient
if httpClient == nil {
httpClient = &http.Client{
Transport: ourTransport,
Timeout: cfg.Metrics.Timeout,
}
if cfg.Metrics.Proxy != nil {
clonedTransport.Proxy = cfg.Metrics.Proxy
if cfg.Metrics.TLSCfg != nil || cfg.Metrics.Proxy != nil {
clonedTransport := ourTransport.Clone()
httpClient.Transport = clonedTransport
if cfg.Metrics.TLSCfg != nil {
clonedTransport.TLSClientConfig = cfg.Metrics.TLSCfg
}
if cfg.Metrics.Proxy != nil {
clonedTransport.Proxy = cfg.Metrics.Proxy
}
}
}

View File

@@ -254,6 +254,28 @@ func TestConfig(t *testing.T) {
})
t.Run("WithProxy", func(t *testing.T) {
headerKeySetInProxy := http.CanonicalHeaderKey("X-Using-Proxy")
headerValueSetInProxy := "true"
exp, coll := factoryFunc("", nil, WithHTTPClient(&http.Client{
Transport: &http.Transport{
Proxy: func(r *http.Request) (*url.URL, error) {
r.Header.Set(headerKeySetInProxy, headerValueSetInProxy)
return r.URL, nil
},
},
}))
ctx := context.Background()
t.Cleanup(func() { require.NoError(t, coll.Shutdown(ctx)) })
require.NoError(t, exp.Export(ctx, &metricdata.ResourceMetrics{}))
// Ensure everything is flushed.
require.NoError(t, exp.Shutdown(ctx))
got := coll.Headers()
require.Contains(t, got, headerKeySetInProxy)
assert.Equal(t, []string{headerValueSetInProxy}, got[headerKeySetInProxy])
})
t.Run("WithHTTPClient", func(t *testing.T) {
headerKeySetInProxy := http.CanonicalHeaderKey("X-Using-Proxy")
headerValueSetInProxy := "true"
exp, coll := factoryFunc("", nil, WithProxy(func(r *http.Request) (*url.URL, error) {

View File

@@ -222,3 +222,19 @@ func WithAggregationSelector(selector metric.AggregationSelector) Option {
func WithProxy(pf HTTPTransportProxyFunc) Option {
return wrappedOption{oconf.WithProxy(oconf.HTTPTransportProxyFunc(pf))}
}
// WithHTTPClient sets the HTTP client to used by the exporter.
//
// This option will take precedence over [WithProxy], [WithTimeout],
// [WithTLSClientConfig] options as well as OTEL_EXPORTER_OTLP_CERTIFICATE,
// OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, OTEL_EXPORTER_OTLP_TIMEOUT,
// OTEL_EXPORTER_OTLP_METRICS_TIMEOUT environment variables.
//
// Timeout and all other fields of the passed [http.Client] are left intact.
//
// Be aware that passing an HTTP client with transport like
// [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewTransport] can
// cause the client to be instrumented twice and cause infinite recursion.
func WithHTTPClient(c *http.Client) Option {
return wrappedOption{oconf.WithHTTPClient(c)}
}

View File

@@ -57,13 +57,15 @@ type (
Timeout time.Duration
URLPath string
// gRPC configurations
GRPCCredentials credentials.TransportCredentials
TemporalitySelector metric.TemporalitySelector
AggregationSelector metric.AggregationSelector
Proxy HTTPTransportProxyFunc
// gRPC configurations
GRPCCredentials credentials.TransportCredentials
// HTTP configurations
Proxy HTTPTransportProxyFunc
HTTPClient *http.Client
}
Config struct {
@@ -373,3 +375,10 @@ func WithProxy(pf HTTPTransportProxyFunc) GenericOption {
return cfg
})
}
func WithHTTPClient(c *http.Client) GenericOption {
return newGenericOption(func(cfg Config) Config {
cfg.Metrics.HTTPClient = c
return cfg
})
}

View File

@@ -533,6 +533,24 @@ func TestConfigs(t *testing.T) {
assert.Nil(t, c.Metrics.Proxy)
},
},
// HTTP Client Tests
{
name: "Test With HTTP Client",
opts: []GenericOption{
WithHTTPClient(http.DefaultClient),
},
asserts: func(t *testing.T, c *Config, grpcOption bool) {
assert.Equal(t, http.DefaultClient, c.Metrics.HTTPClient)
},
},
{
name: "Test Without HTTP Client",
opts: []GenericOption{},
asserts: func(t *testing.T, c *Config, grpcOption bool) {
assert.Nil(t, c.Metrics.HTTPClient)
},
},
}
for _, tt := range tests {

View File

@@ -57,13 +57,15 @@ type (
Timeout time.Duration
URLPath string
// gRPC configurations
GRPCCredentials credentials.TransportCredentials
TemporalitySelector metric.TemporalitySelector
AggregationSelector metric.AggregationSelector
Proxy HTTPTransportProxyFunc
// gRPC configurations
GRPCCredentials credentials.TransportCredentials
// HTTP configurations
Proxy HTTPTransportProxyFunc
HTTPClient *http.Client
}
Config struct {
@@ -373,3 +375,10 @@ func WithProxy(pf HTTPTransportProxyFunc) GenericOption {
return cfg
})
}
func WithHTTPClient(c *http.Client) GenericOption {
return newGenericOption(func(cfg Config) Config {
cfg.Metrics.HTTPClient = c
return cfg
})
}

View File

@@ -533,6 +533,24 @@ func TestConfigs(t *testing.T) {
assert.Nil(t, c.Metrics.Proxy)
},
},
// HTTP Client Tests
{
name: "Test With HTTP Client",
opts: []GenericOption{
WithHTTPClient(http.DefaultClient),
},
asserts: func(t *testing.T, c *Config, grpcOption bool) {
assert.Equal(t, http.DefaultClient, c.Metrics.HTTPClient)
},
},
{
name: "Test Without HTTP Client",
opts: []GenericOption{},
asserts: func(t *testing.T, c *Config, grpcOption bool) {
assert.Nil(t, c.Metrics.HTTPClient)
},
},
}
for _, tt := range tests {