You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-08-10 22:31:50 +02:00
otlploghttp: Add WithHTTPClient option (#6688)
Towards (for OTLP logs exporter): - https://github.com/open-telemetry/opentelemetry-go/issues/4536 - https://github.com/open-telemetry/opentelemetry-go/issues/5129 - https://github.com/open-telemetry/opentelemetry-go/issues/2632 Per https://github.com/open-telemetry/opentelemetry-go/pull/6362/files#r1978191352 Providing `WithHTTPClient` option allows easy interoperability e.g. with https://pkg.go.dev/golang.org/x/oauth2/clientcredentials#Config.Client and also see https://github.com/open-telemetry/opentelemetry-go/issues/2632. The options is also similar to: https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc#WithGRPCConn I favor this over https://github.com/open-telemetry/opentelemetry-go/pull/6686 The option for OTLP span and metrics exporters will be added in separate PRs.
This commit is contained in:
@@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
The package contains semantic conventions from the `v1.31.0` version of the OpenTelemetry Semantic Conventions.
|
The package contains semantic conventions from the `v1.31.0` version of the OpenTelemetry Semantic Conventions.
|
||||||
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)
|
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 `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)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@@ -44,20 +44,23 @@ func newNoopClient() *client {
|
|||||||
|
|
||||||
// newHTTPClient creates a new HTTP log client.
|
// newHTTPClient creates a new HTTP log client.
|
||||||
func newHTTPClient(cfg config) (*client, error) {
|
func newHTTPClient(cfg config) (*client, error) {
|
||||||
hc := &http.Client{
|
hc := cfg.httpClient
|
||||||
Transport: ourTransport,
|
if hc == nil {
|
||||||
Timeout: cfg.timeout.Value,
|
hc = &http.Client{
|
||||||
}
|
Transport: ourTransport,
|
||||||
|
Timeout: cfg.timeout.Value,
|
||||||
if cfg.tlsCfg.Value != nil || cfg.proxy.Value != nil {
|
|
||||||
clonedTransport := ourTransport.Clone()
|
|
||||||
hc.Transport = clonedTransport
|
|
||||||
|
|
||||||
if cfg.tlsCfg.Value != nil {
|
|
||||||
clonedTransport.TLSClientConfig = cfg.tlsCfg.Value
|
|
||||||
}
|
}
|
||||||
if cfg.proxy.Value != nil {
|
|
||||||
clonedTransport.Proxy = cfg.proxy.Value
|
if cfg.tlsCfg.Value != nil || cfg.proxy.Value != nil {
|
||||||
|
clonedTransport := ourTransport.Clone()
|
||||||
|
hc.Transport = clonedTransport
|
||||||
|
|
||||||
|
if cfg.tlsCfg.Value != nil {
|
||||||
|
clonedTransport.TLSClientConfig = cfg.tlsCfg.Value
|
||||||
|
}
|
||||||
|
if cfg.proxy.Value != nil {
|
||||||
|
clonedTransport.Proxy = cfg.proxy.Value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -783,6 +783,28 @@ func TestConfig(t *testing.T) {
|
|||||||
assert.Equal(t, []string{headerValueSetInProxy}, 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, 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, make([]log.Record, 1)))
|
||||||
|
// 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("non-retryable errors are propagated", func(t *testing.T) {
|
t.Run("non-retryable errors are propagated", func(t *testing.T) {
|
||||||
exporterErr := errors.New("missing required attribute aaaa")
|
exporterErr := errors.New("missing required attribute aaaa")
|
||||||
rCh := make(chan exportResult, 1)
|
rCh := make(chan exportResult, 1)
|
||||||
|
@@ -95,6 +95,7 @@ type config struct {
|
|||||||
timeout setting[time.Duration]
|
timeout setting[time.Duration]
|
||||||
proxy setting[HTTPTransportProxyFunc]
|
proxy setting[HTTPTransportProxyFunc]
|
||||||
retryCfg setting[retry.Config]
|
retryCfg setting[retry.Config]
|
||||||
|
httpClient *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConfig(options []Option) config {
|
func newConfig(options []Option) config {
|
||||||
@@ -344,6 +345,25 @@ func WithProxy(pf HTTPTransportProxyFunc) Option {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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_LOGS_CERTIFICATE, OTEL_EXPORTER_OTLP_TIMEOUT,
|
||||||
|
// OTEL_EXPORTER_OTLP_LOGS_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 fnOpt(func(cfg config) config {
|
||||||
|
cfg.httpClient = c
|
||||||
|
return cfg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// setting is a configuration setting value.
|
// setting is a configuration setting value.
|
||||||
type setting[T any] struct {
|
type setting[T any] struct {
|
||||||
Value T
|
Value T
|
||||||
|
Reference in New Issue
Block a user