Repository: traefik/traefik (language: go)

Issue:
the forward span.kind should be `client` rather than `internal`
### Welcome!

- [X] Yes, I've searched similar issues on [GitHub](https://github.com/traefik/traefik/issues) and didn't find any.
- [X] Yes, I've searched similar issues on the [Traefik community forum](https://community.traefik.io) and didn't find any.

### What did you do?

Enable OTEL tracing

### What did you see instead?

When traefik eventually makes a `forward` call the span kind should be `client` rather than `internal`

![image](https://github.com/traefik/traefik/assets/110627/1f10bee0-358a-4cb3-9698-c1b63eb5f423)


### What version of Traefik are you using?

3.0 beta 4

### What is your environment & configuration?

```yaml
# (paste your configuration here)
```

Add more configuration information here.


### If applicable, please paste the log output in DEBUG level

_No response_


Discussion / hints:

Fix patch:
diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go
index f3e01f7b81..0ac89fb46b 100644
--- a/cmd/traefik/traefik.go
+++ b/cmd/traefik/traefik.go
@@ -5,6 +5,7 @@ import (
 	"crypto/x509"
 	"encoding/json"
 	"fmt"
+	"io"
 	stdlog "log"
 	"net/http"
 	"os"
@@ -43,9 +44,9 @@ import (
 	"github.com/traefik/traefik/v3/pkg/tcp"
 	traefiktls "github.com/traefik/traefik/v3/pkg/tls"
 	"github.com/traefik/traefik/v3/pkg/tracing"
-	"github.com/traefik/traefik/v3/pkg/tracing/jaeger"
 	"github.com/traefik/traefik/v3/pkg/types"
 	"github.com/traefik/traefik/v3/pkg/version"
+	"go.opentelemetry.io/otel/trace"
 )
 
 func main() {
@@ -265,10 +266,9 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
 	managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry, roundTripperManager, acmeHTTPHandler)
 
 	// Router factory
-
 	accessLog := setupAccessLog(staticConfiguration.AccessLog)
-	tracer := setupTracing(staticConfiguration.Tracing)
 
+	tracer, tracerCloser := setupTracing(staticConfiguration.Tracing)
 	chainBuilder := middleware.NewChainBuilder(metricsRegistry, accessLog, tracer)
 	routerFactory := server.NewRouterFactory(*staticConfiguration, managerFactory, tlsManager, chainBuilder, pluginBuilder, metricsRegistry, dialerManager)
 
@@ -351,7 +351,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
 		}
 	})
 
-	return server.NewServer(routinesPool, serverEntryPointsTCP, serverEntryPointsUDP, watcher, chainBuilder, accessLog), nil
+	return server.NewServer(routinesPool, serverEntryPointsTCP, serverEntryPointsUDP, watcher, chainBuilder, accessLog, tracerCloser), nil
 }
 
 func getHTTPChallengeHandler(acmeProviders []*acme.Provider, httpChallengeProvider http.Handler) http.Handler {
@@ -564,78 +564,18 @@ func setupAccessLog(conf *types.AccessLog) *accesslog.Handler {
 	return accessLoggerMiddleware
 }
 
-func setupTracing(conf *static.Tracing) *tracing.Tracing {
+func setupTracing(conf *static.Tracing) (trace.Tracer, io.Closer) {
 	if conf == nil {
-		return nil
-	}
-
-	var backend tracing.Backend
-
-	if conf.Jaeger != nil {
-		backend = conf.Jaeger
-	}
-
-	if conf.Zipkin != nil {
-		if backend != nil {
-			log.Error().Msg("Multiple tracing backend are not supported: cannot create Zipkin backend.")
-		} else {
-			backend = conf.Zipkin
-		}
-	}
-
-	if conf.Datadog != nil {
-		if backend != nil {
-			log.Error().Msg("Multiple tracing backend are not supported: cannot create Datadog backend.")
-		} else {
-			backend = conf.Datadog
-		}
-	}
-
-	if conf.Instana != nil {
-		if backend != nil {
-			log.Error().Msg("Multiple tracing backend are not supported: cannot create Instana backend.")
-		} else {
-			backend = conf.Instana
-		}
+		return nil, nil
 	}
 
-	if conf.Haystack != nil {
-		if backend != nil {
-			log.Error().Msg("Multiple tracing backend are not supported: cannot create Haystack backend.")
-		} else {
-			backend = conf.Haystack
-		}
-	}
-
-	if conf.Elastic != nil {
-		if backend != nil {
-			log.Error().Msg("Multiple tracing backend are not supported: cannot create Elastic backend.")
-		} else {
-			backend = conf.Elastic
-		}
-	}
-
-	if conf.OpenTelemetry != nil {
-		if backend != nil {
-			log.Error().Msg("Tracing backends are all mutually exclusive: cannot create OpenTelemetry backend.")
-		} else {
-			backend = conf.OpenTelemetry
-		}
-	}
-
-	if backend == nil {
-		log.Debug().Msg("Could not initialize tracing, using Jaeger by default")
-		defaultBackend := &jaeger.Config{}
-		defaultBackend.SetDefaults()
-		backend = defaultBackend
-	}
-
-	tracer, err := tracing.NewTracing(conf.ServiceName, conf.SpanNameLimit, backend)
+	tracer, closer, err := tracing.NewTracing(conf)
 	if err != nil {
 		log.Warn().Err(err).Msg("Unable to create tracer")
-		return nil
+		return nil, nil
 	}
-	return tracer
+
+	return tracer, closer
 }
 
 func checkNewVersion() {
diff --git a/docs/content/migration/v2-to-v3.md b/docs/content/migration/v2-to-v3.md
index dcc7505a18..70b27f8209 100644
--- a/docs/content/migration/v2-to-v3.md
+++ b/docs/content/migration/v2-to-v3.md
@@ -394,3 +394,24 @@ One should use the `ContentType` middleware to enable the `Content-Type` header
 #### gRPC Metrics
 
 In v3, the reported status code for gRPC requests is now the value of the `Grpc-Status` header.  
+
+#### Tracing
+
+In v3, the tracing feature has been revamped and is now powered exclusively by [OpenTelemetry](https://opentelemetry.io/ "Link to website of OTel") (OTel).
+!!! warning "Important"
+
+    Traefik v3 **no** longer supports direct output formats for specific vendors such as Instana, Jaeger, Zipkin, Haystack, Datadog, and Elastic.
+Instead, it focuses on pure OpenTelemetry implementation, providing a unified and standardized approach for observability.
+
+Here are two possible transition strategies:
+
+1. OTLP Ingestion Endpoints:
+
+    Most vendors now offer OpenTelemetry Protocol (OTLP) ingestion endpoints.
+    You can seamlessly integrate Traefik v3 with these endpoints to continue leveraging tracing capabilities.
+
+2. Legacy Stack Compatibility:
+
+    For legacy stacks that cannot immediately upgrade to the latest vendor agents supporting OTLP ingestion,
+    using OpenTelemetry (OTel) collectors with appropriate exporters configuration is a viable solution.
+    This allows continued compatibility with the existing infrastructure.
diff --git a/docs/content/observability/tracing/datadog.md b/docs/content/observability/tracing/datadog.md
deleted file mode 100644
index fe14bc72f6..0000000000
--- a/docs/content/observability/tracing/datadog.md
+++ /dev/null
@@ -1,139 +0,0 @@
----
-title: "Traefik Datadog Tracing Documentation"
-description: "Traefik Proxy supports Datadog for tracing. Read the technical documentation to enable Datadog for observability."
----
-
-# Datadog
-
-To enable the Datadog tracer:
-
-```yaml tab="File (YAML)"
-tracing:
-  datadog: {}
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.datadog]
-```
-
-```bash tab="CLI"
---tracing.datadog=true
-```
-
-#### `localAgentHostPort`
-
-_Optional, Default="localhost:8126"_
-
-Local Agent Host Port instructs the reporter to send spans to the Datadog Agent at this address (host:port).
-
-```yaml tab="File (YAML)"
-tracing:
-  datadog:
-    localAgentHostPort: localhost:8126
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.datadog]
-    localAgentHostPort = "localhost:8126"
-```
-
-```bash tab="CLI"
---tracing.datadog.localAgentHostPort=localhost:8126
-```
-
-#### `localAgentSocket`
-
-_Optional, Default=""_
-
-Local Agent Socket instructs the reporter to send spans to the Datadog Agent at this UNIX socket.
-
-```yaml tab="File (YAML)"
-tracing:
-  datadog:
-    localAgentSocket: /var/run/datadog/apm.socket
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.datadog]
-    localAgentSocket = "/var/run/datadog/apm.socket"
-```
-
-```bash tab="CLI"
---tracing.datadog.localAgentSocket=/var/run/datadog/apm.socket
-```
-
-#### `debug`
-
-_Optional, Default=false_
-
-Enables Datadog debug.
-
-```yaml tab="File (YAML)"
-tracing:
-  datadog:
-    debug: true
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.datadog]
-    debug = true
-```
-
-```bash tab="CLI"
---tracing.datadog.debug=true
-```
-
-#### `globalTags`
-
-_Optional, Default=empty_
-
-Applies a list of shared key:value tags on all spans.
-
-```yaml tab="File (YAML)"
-tracing:
-  datadog:
-    globalTags:
-      tag1: foo
-      tag2: bar
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.datadog]
-    [tracing.datadog.globalTags]
-      tag1 = "foo"
-      tag2 = "bar"
-```
-
-```bash tab="CLI"
---tracing.datadog.globalTags.tag1=foo
---tracing.datadog.globalTags.tag2=bar
-```
-
-#### `prioritySampling`
-
-_Optional, Default=false_
-
-Enables priority sampling.
-When using distributed tracing, 
-this option must be enabled in order to get all the parts of a distributed trace sampled.
-
-```yaml tab="File (YAML)"
-tracing:
-  datadog:
-    prioritySampling: true
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.datadog]
-    prioritySampling = true
-```
-
-```bash tab="CLI"
---tracing.datadog.prioritySampling=true
-```
diff --git a/docs/content/observability/tracing/elastic.md b/docs/content/observability/tracing/elastic.md
deleted file mode 100644
index 0cb0dccee9..0000000000
--- a/docs/content/observability/tracing/elastic.md
+++ /dev/null
@@ -1,93 +0,0 @@
----
-title: "Traefik Elastic Documentation"
-description: "Traefik supports several tracing backends, including Elastic. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
----
-
-# Elastic
-
-To enable the Elastic tracer:
-
-```yaml tab="File (YAML)"
-tracing:
-  elastic: {}
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.elastic]
-```
-
-```bash tab="CLI"
---tracing.elastic=true
-```
-
-#### `serverURL`
-
-_Optional, Default="http://localhost:8200"_
-
-URL of the Elastic APM server.
-
-```yaml tab="File (YAML)"
-tracing:
-  elastic:
-    serverURL: "http://apm:8200"
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.elastic]
-    serverURL = "http://apm:8200"
-```
-
-```bash tab="CLI"
---tracing.elastic.serverurl="http://apm:8200"
-```
-
-#### `secretToken`
-
-_Optional, Default=""_
-
-Token used to connect to Elastic APM Server.
-
-```yaml tab="File (YAML)"
-tracing:
-  elastic:
-    secretToken: "mytoken"
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.elastic]
-    secretToken = "mytoken"
-```
-
-```bash tab="CLI"
---tracing.elastic.secrettoken="mytoken"
-```
-
-#### `serviceEnvironment`
-
-_Optional, Default=""_
-
-Environment's name where Traefik is deployed in, e.g. `production` or `staging`.
-
-```yaml tab="File (YAML)"
-tracing:
-  elastic:
-    serviceEnvironment: "production"
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.elastic]
-    serviceEnvironment = "production"
-```
-
-```bash tab="CLI"
---tracing.elastic.serviceenvironment="production"
-```
-
-### Further
-
-Additional configuration of Elastic APM Go agent can be done using environment variables.
-See [APM Go agent reference](https://www.elastic.co/guide/en/apm/agent/go/current/configuration.html).
diff --git a/docs/content/observability/tracing/haystack.md b/docs/content/observability/tracing/haystack.md
deleted file mode 100644
index af9945ed79..0000000000
--- a/docs/content/observability/tracing/haystack.md
+++ /dev/null
@@ -1,176 +0,0 @@
----
-title: "Traefik Haystack Documentation"
-description: "Traefik supports several tracing backends, including Haystack. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
----
-
-# Haystack
-
-To enable the Haystack tracer:
-
-```yaml tab="File (YAML)"
-tracing:
-  haystack: {}
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.haystack]
-```
-
-```bash tab="CLI"
---tracing.haystack=true
-```
-
-#### `localAgentHost`
-
-_Required, Default="127.0.0.1"_
-
-Local Agent Host instructs reporter to send spans to the Haystack Agent at this address.
-
-```yaml tab="File (YAML)"
-tracing:
-  haystack:
-    localAgentHost: 127.0.0.1
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.haystack]
-    localAgentHost = "127.0.0.1"
-```
-
-```bash tab="CLI"
---tracing.haystack.localAgentHost=127.0.0.1
-```
-
-#### `localAgentPort`
-
-_Required, Default=35000_
-
-Local Agent Port instructs reporter to send spans to the Haystack Agent at this port.
-
-```yaml tab="File (YAML)"
-tracing:
-  haystack:
-    localAgentPort: 35000
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.haystack]
-    localAgentPort = 35000
-```
-
-```bash tab="CLI"
---tracing.haystack.localAgentPort=35000
-```
-
-#### `globalTag`
-
-_Optional, Default=empty_
-
-Applies shared key:value tag on all spans.
-
-```yaml tab="File (YAML)"
-tracing:
-  haystack:
-    globalTag: sample:test
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.haystack]
-    globalTag = "sample:test"
-```
-
-```bash tab="CLI"
---tracing.haystack.globalTag=sample:test
-```
-
-#### `traceIDHeaderName`
-
-_Optional, Default=empty_
-
-Sets the header name used to store the trace ID.
-
-```yaml tab="File (YAML)"
-tracing:
-  haystack:
-    traceIDHeaderName: Trace-ID
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.haystack]
-    traceIDHeaderName = "Trace-ID"
-```
-
-```bash tab="CLI"
---tracing.haystack.traceIDHeaderName=Trace-ID
-```
-
-#### `parentIDHeaderName`
-
-_Optional, Default=empty_
-
-Sets the header name used to store the parent ID.
-
-```yaml tab="File (YAML)"
-tracing:
-  haystack:
-    parentIDHeaderName: Parent-Message-ID
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.haystack]
-    parentIDHeaderName = "Parent-Message-ID"
-```
-
-```bash tab="CLI"
---tracing.haystack.parentIDHeaderName=Parent-Message-ID
-```
-
-#### `spanIDHeaderName`
-
-_Optional, Default=empty_
-
-Sets the header name used to store the span ID.
-
-```yaml tab="File (YAML)"
-tracing:
-  haystack:
-    spanIDHeaderName: Message-ID
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.haystack]
-    spanIDHeaderName = "Message-ID"
-```
-
-```bash tab="CLI"
---tracing.haystack.spanIDHeaderName=Message-ID
-```
-
-#### `baggagePrefixHeaderName`
-
-_Optional, Default=empty_
-
-Sets the header name prefix used to store baggage items in a map.
-
-```yaml tab="File (YAML)"
-tracing:
-  haystack:
-    baggagePrefixHeaderName: "sample"
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.haystack]
-    baggagePrefixHeaderName = "sample"
-```
-
-```bash tab="CLI"
---tracing.haystack.baggagePrefixHeaderName=sample
-```
diff --git a/docs/content/observability/tracing/instana.md b/docs/content/observability/tracing/instana.md
deleted file mode 100644
index 914d9d3f41..0000000000
--- a/docs/content/observability/tracing/instana.md
+++ /dev/null
@@ -1,117 +0,0 @@
----
-title: "Traefik Instana Documentation"
-description: "Traefik supports several tracing backends, including Instana. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
----
-
-# Instana
-
-To enable the Instana tracer:
-
-```yaml tab="File (YAML)"
-tracing:
-  instana: {}
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.instana]
-```
-
-```bash tab="CLI"
---tracing.instana=true
-```
-
-#### `localAgentHost`
-
-_Required, Default="127.0.0.1"_
-
-Local Agent Host instructs reporter to send spans to the Instana Agent at this address.
-
-```yaml tab="File (YAML)"
-tracing:
-  instana:
-    localAgentHost: 127.0.0.1
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.instana]
-    localAgentHost = "127.0.0.1"
-```
-
-```bash tab="CLI"
---tracing.instana.localAgentHost=127.0.0.1
-```
-
-#### `localAgentPort`
-
-_Required, Default=42699_
-
-Local Agent port instructs reporter to send spans to the Instana Agent listening on this port.
-
-```yaml tab="File (YAML)"
-tracing:
-  instana:
-    localAgentPort: 42699
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.instana]
-    localAgentPort = 42699
-```
-
-```bash tab="CLI"
---tracing.instana.localAgentPort=42699
-```
-
-#### `logLevel`
-
-_Required, Default="info"_
-
-Sets Instana tracer log level.
-
-Valid values are:
-
-- `error`
-- `warn`
-- `debug`
-- `info`
-
-```yaml tab="File (YAML)"
-tracing:
-  instana:
-    logLevel: info
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.instana]
-    logLevel = "info"
-```
-
-```bash tab="CLI"
---tracing.instana.logLevel=info
-```
-
-#### `enableAutoProfile`
-
-_Required, Default=false_
-
-Enables [automatic profiling](https://www.ibm.com/docs/en/obi/current?topic=instana-profile-processes) for the Traefik process.
-
-```yaml tab="File (YAML)"
-tracing:
-  instana:
-    enableAutoProfile: true
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.instana]
-    enableAutoProfile = true
-```
-
-```bash tab="CLI"
---tracing.instana.enableAutoProfile=true
-```
diff --git a/docs/content/observability/tracing/jaeger.md b/docs/content/observability/tracing/jaeger.md
deleted file mode 100644
index d40ffed6d7..0000000000
--- a/docs/content/observability/tracing/jaeger.md
+++ /dev/null
@@ -1,294 +0,0 @@
----
-title: "Traefik Jaeger Documentation"
-description: "Traefik supports several tracing backends, including Jaeger. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
----
-
-# Jaeger
-
-To enable the Jaeger tracer:
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger: {}
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-```
-
-```bash tab="CLI"
---tracing.jaeger=true
-```
-
-!!! warning
-    Traefik is able to send data over the compact thrift protocol to the [Jaeger agent](https://www.jaegertracing.io/docs/deployment/#agent)
-    or a [Jaeger collector](https://www.jaegertracing.io/docs/deployment/#collector).
-
-!!! info
-    All Jaeger configuration can be overridden by [environment variables](https://github.com/jaegertracing/jaeger-client-go#environment-variables)
-
-#### `samplingServerURL`
-
-_Required, Default="http://localhost:5778/sampling"_
-
-Address of the Jaeger Agent HTTP sampling server.
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    samplingServerURL: http://localhost:5778/sampling
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-    samplingServerURL = "http://localhost:5778/sampling"
-```
-
-```bash tab="CLI"
---tracing.jaeger.samplingServerURL=http://localhost:5778/sampling
-```
-
-#### `samplingType`
-
-_Required, Default="const"_
-
-Type of the sampler.
-
-Valid values are:
-
-- `const`
-- `probabilistic`
-- `rateLimiting`
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    samplingType: const
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-    samplingType = "const"
-```
-
-```bash tab="CLI"
---tracing.jaeger.samplingType=const
-```
-
-#### `samplingParam`
-
-_Required, Default=1.0_
-
-Value passed to the sampler.
-
-Valid values are:
-
-- for `const` sampler, 0 or 1 for always false/true respectively
-- for `probabilistic` sampler, a probability between 0 and 1
-- for `rateLimiting` sampler, the number of spans per second
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    samplingParam: 1.0
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-    samplingParam = 1.0
-```
-
-```bash tab="CLI"
---tracing.jaeger.samplingParam=1.0
-```
-
-#### `localAgentHostPort`
-
-_Required, Default="127.0.0.1:6831"_
-
-Local Agent Host Port instructs the reporter to send spans to the Jaeger Agent at this address (host:port).
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    localAgentHostPort: 127.0.0.1:6831
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-    localAgentHostPort = "127.0.0.1:6831"
-```
-
-```bash tab="CLI"
---tracing.jaeger.localAgentHostPort=127.0.0.1:6831
-```
-
-#### `gen128Bit`
-
-_Optional, Default=false_
-
-Generates 128 bits trace IDs, compatible with OpenCensus.
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    gen128Bit: true
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-    gen128Bit = true
-```
-
-```bash tab="CLI"
---tracing.jaeger.gen128Bit
-```
-
-#### `propagation`
-
-_Required, Default="jaeger"_
-
-Sets the propagation header type.
-
-Valid values are:
-
-- `jaeger`, jaeger's default trace header.
-- `b3`, compatible with OpenZipkin
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    propagation: jaeger
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-    propagation = "jaeger"
-```
-
-```bash tab="CLI"
---tracing.jaeger.propagation=jaeger
-```
-
-#### `traceContextHeaderName`
-
-_Required, Default="uber-trace-id"_
-
-HTTP header name used to propagate tracing context.
-This must be in lower-case to avoid mismatches when decoding incoming headers.
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    traceContextHeaderName: uber-trace-id
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-    traceContextHeaderName = "uber-trace-id"
-```
-
-```bash tab="CLI"
---tracing.jaeger.traceContextHeaderName=uber-trace-id
-```
-
-### disableAttemptReconnecting
-
-_Optional, Default=true_
-
-Disables the UDP connection helper that periodically re-resolves the agent's hostname and reconnects if there was a change.
-Enabling the re-resolving of UDP address make the client more robust in Kubernetes deployments.
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    disableAttemptReconnecting: false
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger]
-    disableAttemptReconnecting = false
-```
-
-```bash tab="CLI"
---tracing.jaeger.disableAttemptReconnecting=false
-```
-
-### `collector`
-#### `endpoint`
-
-_Optional, Default=""_
-
-Collector Endpoint instructs the reporter to send spans to the Jaeger Collector at this URL.
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    collector:
-        endpoint: http://127.0.0.1:14268/api/traces?format=jaeger.thrift
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger.collector]
-    endpoint = "http://127.0.0.1:14268/api/traces?format=jaeger.thrift"
-```
-
-```bash tab="CLI"
---tracing.jaeger.collector.endpoint=http://127.0.0.1:14268/api/traces?format=jaeger.thrift
-```
-
-#### `user`
-
-_Optional, Default=""_
-
-User instructs the reporter to include a user for basic HTTP authentication when sending spans to the Jaeger Collector.
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    collector:
-        user: my-user
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger.collector]
-    user = "my-user"
-```
-
-```bash tab="CLI"
---tracing.jaeger.collector.user=my-user
-```
-
-#### `password`
-
-_Optional, Default=""_
-
-Password instructs the reporter to include a password for basic HTTP authentication when sending spans to the Jaeger Collector.
-
-```yaml tab="File (YAML)"
-tracing:
-  jaeger:
-    collector:
-        password: my-password
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.jaeger.collector]
-    password = "my-password"
-```
-
-```bash tab="CLI"
---tracing.jaeger.collector.password=my-password
-```
diff --git a/docs/content/observability/tracing/opentelemetry.md b/docs/content/observability/tracing/opentelemetry.md
index d39e09b588..52b37a0a55 100644
--- a/docs/content/observability/tracing/opentelemetry.md
+++ b/docs/content/observability/tracing/opentelemetry.md
@@ -9,122 +9,249 @@ To enable the OpenTelemetry tracer:
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry: {}
+  otlp: {}
 ```
 
 ```toml tab="File (TOML)"
 [tracing]
-  [tracing.openTelemetry]
+  [tracing.otlp]
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry=true
+--tracing.otlp=true
 ```
 
-!!! info "The OpenTelemetry trace reporter will export traces to the collector using HTTP by default, see the [gRPC Section](#grpc-configuration) to use gRPC."
+!!! info "The OpenTelemetry trace reporter will export traces to the collector using HTTP by default (http://localhost:4318/v1/traces), 
+see the [gRPC Section](#grpc-configuration) to use gRPC."
 
 !!! info "Trace sampling"
 
-	By default, the OpenTelemetry trace reporter will sample 100% of traces.
+	By default, the OpenTelemetry trace reporter will sample 100% of traces.  
 	See [OpenTelemetry's SDK configuration](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/#general-sdk-configuration) to customize the sampling strategy.
 
-#### `address`
+### HTTP configuration
 
-_Required, Default="localhost:4318", Format="`<host>:<port>`"_
+_Optional_
 
-Address of the OpenTelemetry Collector to send spans to.
+This instructs the reporter to send spans to the OpenTelemetry Collector using HTTP.
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry:
-    address: localhost:4318
+  otlp:
+    http: {}
 ```
 
 ```toml tab="File (TOML)"
 [tracing]
-  [tracing.openTelemetry]
-    address = "localhost:4318"
+  [tracing.otlp.http]
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry.address=localhost:4318
+--tracing.otlp.http=true
 ```
 
-#### `headers`
+#### `endpoint`
 
-_Optional, Default={}_
+_Required, Default="http://localhost:4318/v1/traces", Format="`<scheme>://<host>:<port><path>`"_
 
-Additional headers sent with spans by the reporter to the OpenTelemetry Collector.
+URL of the OpenTelemetry Collector to send spans to.
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry:
-    headers:
-      foo: bar
-      baz: buz
+  otlp:
+    http:
+      endpoint: http://localhost:4318/v1/traces
 ```
 
 ```toml tab="File (TOML)"
 [tracing]
-  [tracing.openTelemetry.headers]
-    foo = "bar"
-    baz = "buz"
+  [tracing.otlp.http]
+    endpoint = "http://localhost:4318/v1/traces"
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry.headers.foo=bar --tracing.openTelemetry.headers.baz=buz
+--tracing.otlp.http.endpoint=http://localhost:4318/v1/traces
 ```
 
-#### `insecure`
+#### `tls`
+
+_Optional_
+
+Defines the Client TLS configuration used by the reporter to send spans to the OpenTelemetry Collector.
+
+##### `ca`
+
+_Optional_
+
+`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
+it defaults to the system bundle.
+
+```yaml tab="File (YAML)"
+tracing:
+  otlp:
+    http:
+      tls:
+        ca: path/to/ca.crt
+```
+
+```toml tab="File (TOML)"
+[tracing.otlp.http.tls]
+  ca = "path/to/ca.crt"
+```
+
+```bash tab="CLI"
+--tracing.otlp.http.tls.ca=path/to/ca.crt
+```
+
+##### `cert`
+
+_Optional_
+
+`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
+When using this option, setting the `key` option is required.
+
+```yaml tab="File (YAML)"
+tracing:
+  otlp:
+    http:
+      tls:
+        cert: path/to/foo.cert
+        key: path/to/foo.key
+```
+
+```toml tab="File (TOML)"
+[tracing.otlp.http.tls]
+  cert = "path/to/foo.cert"
+  key = "path/to/foo.key"
+```
+
+```bash tab="CLI"
+--tracing.otlp.http.tls.cert=path/to/foo.cert
+--tracing.otlp.http.tls.key=path/to/foo.key
+```
+
+##### `key`
+
+_Optional_
+
+`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
+When using this option, setting the `cert` option is required.
+
+```yaml tab="File (YAML)"
+tracing:
+  otlp:
+    http:
+      tls:
+        cert: path/to/foo.cert
+        key: path/to/foo.key
+```
+
+```toml tab="File (TOML)"
+[tracing.otlp.http.tls]
+  cert = "path/to/foo.cert"
+  key = "path/to/foo.key"
+```
+
+```bash tab="CLI"
+--tracing.otlp.http.tls.cert=path/to/foo.cert
+--tracing.otlp.http.tls.key=path/to/foo.key
+```
+
+##### `insecureSkipVerify`
 
 _Optional, Default=false_
 
-Allows reporter to send spans to the OpenTelemetry Collector without using a secured protocol.
+If `insecureSkipVerify` is `true`,
+the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry:
-    insecure: true
+  otlp:
+    http:
+      tls:
+        insecureSkipVerify: true
+```
+
+```toml tab="File (TOML)"
+[tracing.otlp.http.tls]
+  insecureSkipVerify = true
+```
+
+```bash tab="CLI"
+--tracing.otlp.http.tls.insecureSkipVerify=true
+```
+
+#### gRPC configuration
+
+_Optional_
+
+This instructs the reporter to send spans to the OpenTelemetry Collector using gRPC.
+
+```yaml tab="File (YAML)"
+tracing:
+  otlp:
+    grpc: {}
 ```
 
 ```toml tab="File (TOML)"
 [tracing]
-  [tracing.openTelemetry]
-    insecure = true
+  [tracing.otlp.grpc]
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry.insecure=true
+--tracing.otlp.grpc=true
 ```
 
-#### `path`
+#### `endpoint`
 
-_Required, Default="/v1/traces"_
+_Required, Default="localhost:4317", Format="`<host>:<port>`"_
 
-Allows to override the default URL path used for sending traces.
-This option has no effect when using gRPC transport.
+Address of the OpenTelemetry Collector to send spans to.
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry:
-    path: /foo/v1/traces
+  otlp:
+    grpc:
+      endpoint: localhost:4317
 ```
 
 ```toml tab="File (TOML)"
 [tracing]
-  [tracing.openTelemetry]
-    path = "/foo/v1/traces"
+  [tracing.otlp.grpc]
+    endpoint = "localhost:4317"
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry.path=/foo/v1/traces
+--tracing.otlp.grpc.endpoint=localhost:4317
+```
+#### `insecure`
+
+_Optional, Default=false_
+
+Allows reporter to send spans to the OpenTelemetry Collector without using a secured protocol.
+
+```yaml tab="File (YAML)"
+tracing:
+  otlp:
+    grpc:
+      insecure: true
+```
+
+```toml tab="File (TOML)"
+[tracing]
+  [tracing.otlp.grpc]
+    insecure = true
+```
+
+```bash tab="CLI"
+--tracing.otlp.grpc.insecure=true
 ```
 
 #### `tls`
 
 _Optional_
 
-Defines the TLS configuration used by the reporter to send spans to the OpenTelemetry Collector.
+Defines the Client TLS configuration used by the reporter to send spans to the OpenTelemetry Collector.
 
 ##### `ca`
 
@@ -135,18 +262,19 @@ it defaults to the system bundle.
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry:
-    tls:
-      ca: path/to/ca.crt
+  otlp:
+    grpc:
+      tls:
+        ca: path/to/ca.crt
 ```
 
 ```toml tab="File (TOML)"
-[tracing.openTelemetry.tls]
+[tracing.otlp.grpc.tls]
   ca = "path/to/ca.crt"
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry.tls.ca=path/to/ca.crt
+--tracing.otlp.grpc.tls.ca=path/to/ca.crt
 ```
 
 ##### `cert`
@@ -158,21 +286,22 @@ When using this option, setting the `key` option is required.
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry:
-    tls:
-      cert: path/to/foo.cert
-      key: path/to/foo.key
+  otlp:
+    grpc:
+      tls:
+        cert: path/to/foo.cert
+        key: path/to/foo.key
 ```
 
 ```toml tab="File (TOML)"
-[tracing.openTelemetry.tls]
+[tracing.otlp.grpc.tls]
   cert = "path/to/foo.cert"
   key = "path/to/foo.key"
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry.tls.cert=path/to/foo.cert
---tracing.openTelemetry.tls.key=path/to/foo.key
+--tracing.otlp.grpc.tls.cert=path/to/foo.cert
+--tracing.otlp.grpc.tls.key=path/to/foo.key
 ```
 
 ##### `key`
@@ -184,21 +313,22 @@ When using this option, setting the `cert` option is required.
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry:
-    tls:
-      cert: path/to/foo.cert
-      key: path/to/foo.key
+  otlp:
+    grpc:
+      tls:
+        cert: path/to/foo.cert
+        key: path/to/foo.key
 ```
 
 ```toml tab="File (TOML)"
-[tracing.openTelemetry.tls]
+[tracing.otlp.grpc.tls]
   cert = "path/to/foo.cert"
   key = "path/to/foo.key"
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry.tls.cert=path/to/foo.cert
---tracing.openTelemetry.tls.key=path/to/foo.key
+--tracing.otlp.grpc.tls.cert=path/to/foo.cert
+--tracing.otlp.grpc.tls.key=path/to/foo.key
 ```
 
 ##### `insecureSkipVerify`
@@ -210,37 +340,17 @@ the TLS connection to the OpenTelemetry Collector accepts any certificate presen
 
 ```yaml tab="File (YAML)"
 tracing:
-  openTelemetry:
-    tls:
-      insecureSkipVerify: true
+  otlp:
+    grpc:
+      tls:
+        insecureSkipVerify: true
 ```
 
 ```toml tab="File (TOML)"
-[tracing.openTelemetry.tls]
+[tracing.otlp.grpc.tls]
   insecureSkipVerify = true
 ```
 
 ```bash tab="CLI"
---tracing.openTelemetry.tls.insecureSkipVerify=true
-```
-
-#### gRPC configuration
-
-_Optional_
-
-This instructs the reporter to send spans to the OpenTelemetry Collector using gRPC.
-
-```yaml tab="File (YAML)"
-tracing:
-  openTelemetry:
-    grpc: {}
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.openTelemetry.grpc]
-```
-
-```bash tab="CLI"
---tracing.openTelemetry.grpc=true
+--tracing.otlp.grpc.tls.insecureSkipVerify=true
 ```
diff --git a/docs/content/observability/tracing/overview.md b/docs/content/observability/tracing/overview.md
index f4126274ad..18b8c4f3e4 100644
--- a/docs/content/observability/tracing/overview.md
+++ b/docs/content/observability/tracing/overview.md
@@ -10,21 +10,13 @@ Visualize the Requests Flow
 
 The tracing system allows developers to visualize call flows in their infrastructure.
 
-Traefik uses OpenTracing, an open standard designed for distributed tracing.
+Traefik uses [OpenTelemetry](https://opentelemetry.io/ "Link to website of OTel"), an open standard designed for distributed tracing.
 
-Traefik supports seven tracing backends:
+Please check our dedicated [OTel docs](./opentelemetry.md) to learn more.
 
-- [Jaeger](./jaeger.md)
-- [Zipkin](./zipkin.md)
-- [Datadog](./datadog.md)
-- [Instana](./instana.md)
-- [Haystack](./haystack.md)
-- [Elastic](./elastic.md)
-- [OpenTelemetry](./opentelemetry.md)
 
 ## Configuration
 
-By default, Traefik uses Jaeger as tracing backend.
 
 To enable the tracing:
 
@@ -62,25 +54,71 @@ tracing:
 --tracing.serviceName=traefik
 ```
 
-#### `spanNameLimit`
+#### `sampleRate`
 
-_Required, Default=0_
+_Optional, Default=1.0_
 
-Span name limit allows for name truncation in case of very long names.
-This can prevent certain tracing providers to drop traces that exceed their length limits.
+The proportion of requests to trace, specified between 0.0 and 1.0.
 
-`0` means no truncation will occur.
+```yaml tab="File (YAML)"
+tracing:
+  sampleRate: 0.2
+```
+
+```toml tab="File (TOML)"
+[tracing]
+    sampleRate = 0.2
+```
+
+```bash tab="CLI"
+--tracing.sampleRate=0.2
+```
+
+#### `headers`
+
+_Optional, Default={}_
+
+Defines additional headers to be sent with the span's payload.
+
+```yaml tab="File (YAML)"
+tracing:
+  headers:
+    foo: bar
+    baz: buz
+```
+
+```toml tab="File (TOML)"
+[tracing]
+    [tracing.headers]
+        foo = "bar"
+        baz = "buz"
+```
+
+```bash tab="CLI"
+--tracing.headers.foo=bar --tracing.headers.baz=buz
+```
+
+#### `globalAttributes`
+
+_Optional, Default=empty_
+
+Applies a list of shared key:value attributes on all spans.
 
 ```yaml tab="File (YAML)"
 tracing:
-  spanNameLimit: 150
+  globalAttributes:
+    attr1: foo
+    attr2: bar
 ```
 
 ```toml tab="File (TOML)"
 [tracing]
-  spanNameLimit = 150
+    [tracing.globalAttributes]
+      attr1 = "foo"
+      attr2 = "bar"
 ```
 
 ```bash tab="CLI"
---tracing.spanNameLimit=150
+--tracing.globalAttributes.attr1=foo
+--tracing.globalAttributes.attr2=bar
 ```
diff --git a/docs/content/observability/tracing/zipkin.md b/docs/content/observability/tracing/zipkin.md
deleted file mode 100644
index 146dae6e1a..0000000000
--- a/docs/content/observability/tracing/zipkin.md
+++ /dev/null
@@ -1,110 +0,0 @@
----
-title: "Traefik Zipkin Documentation"
-description: "Traefik supports several tracing backends, including Zipkin. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
----
-
-# Zipkin
-
-To enable the Zipkin tracer:
-
-```yaml tab="File (YAML)"
-tracing:
-  zipkin: {}
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.zipkin]
-```
-
-```bash tab="CLI"
---tracing.zipkin=true
-```
-
-#### `httpEndpoint`
-
-_Required, Default="http://localhost:9411/api/v2/spans"_
-
-HTTP endpoint used to send data.
-
-```yaml tab="File (YAML)"
-tracing:
-  zipkin:
-    httpEndpoint: http://localhost:9411/api/v2/spans
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.zipkin]
-    httpEndpoint = "http://localhost:9411/api/v2/spans"
-```
-
-```bash tab="CLI"
---tracing.zipkin.httpEndpoint=http://localhost:9411/api/v2/spans
-```
-
-#### `sameSpan`
-
-_Optional, Default=false_
-
-Uses SameSpan RPC style traces.
-
-```yaml tab="File (YAML)"
-tracing:
-  zipkin:
-    sameSpan: true
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.zipkin]
-    sameSpan = true
-```
-
-```bash tab="CLI"
---tracing.zipkin.sameSpan=true
-```
-
-#### `id128Bit`
-
-_Optional, Default=true_
-
-Uses 128 bits trace IDs.
-
-```yaml tab="File (YAML)"
-tracing:
-  zipkin:
-    id128Bit: false
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.zipkin]
-    id128Bit = false
-```
-
-```bash tab="CLI"
---tracing.zipkin.id128Bit=false
-```
-
-#### `sampleRate`
-
-_Required, Default=1.0_
-
-The proportion of requests to trace, specified between 0.0 and 1.0.
-
-```yaml tab="File (YAML)"
-tracing:
-  zipkin:
-    sampleRate: 0.2
-```
-
-```toml tab="File (TOML)"
-[tracing]
-  [tracing.zipkin]
-    sampleRate = 0.2
-```
-
-```bash tab="CLI"
---tracing.zipkin.sampleRate=0.2
-```
diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md
index 8e64fd2aea..efb874437a 100644
--- a/docs/content/reference/static-configuration/cli-ref.md
+++ b/docs/content/reference/static-configuration/cli-ref.md
@@ -987,170 +987,50 @@ Defines the allowed SPIFFE trust domain.
 `--tracing`:  
 OpenTracing configuration. (Default: ```false```)
 
-`--tracing.datadog`:  
-Settings for Datadog. (Default: ```false```)
+`--tracing.globalattributes.<name>`:  
+Defines additional attributes (key:value) on all spans.
 
-`--tracing.datadog.bagageprefixheadername`:  
-Sets the header name prefix used to store baggage items in a map.
-
-`--tracing.datadog.debug`:  
-Enables Datadog debug. (Default: ```false```)
-
-`--tracing.datadog.globaltags.<name>`:  
-Sets a list of key:value tags on all spans.
-
-`--tracing.datadog.localagenthostport`:  
-Sets the Datadog Agent host:port. (Default: ```localhost:8126```)
-
-`--tracing.datadog.localagentsocket`:  
-Sets the socket for the Datadog Agent.
-
-`--tracing.datadog.parentidheadername`:  
-Sets the header name used to store the parent ID.
-
-`--tracing.datadog.prioritysampling`:  
-Enables priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled. (Default: ```false```)
-
-`--tracing.datadog.samplingpriorityheadername`:  
-Sets the header name used to store the sampling priority.
-
-`--tracing.datadog.traceidheadername`:  
-Sets the header name used to store the trace ID.
-
-`--tracing.elastic`:  
-Settings for Elastic. (Default: ```false```)
-
-`--tracing.elastic.secrettoken`:  
-Sets the token used to connect to Elastic APM Server.
-
-`--tracing.elastic.serverurl`:  
-Sets the URL of the Elastic APM server.
-
-`--tracing.elastic.serviceenvironment`:  
-Sets the name of the environment Traefik is deployed in, e.g. 'production' or 'staging'.
-
-`--tracing.haystack`:  
-Settings for Haystack. (Default: ```false```)
-
-`--tracing.haystack.baggageprefixheadername`:  
-Sets the header name prefix used to store baggage items in a map.
-
-`--tracing.haystack.globaltag`:  
-Sets a key:value tag on all spans.
-
-`--tracing.haystack.localagenthost`:  
-Sets the Haystack Agent host. (Default: ```127.0.0.1```)
-
-`--tracing.haystack.localagentport`:  
-Sets the Haystack Agent port. (Default: ```35000```)
-
-`--tracing.haystack.parentidheadername`:  
-Sets the header name used to store the parent ID.
-
-`--tracing.haystack.spanidheadername`:  
-Sets the header name used to store the span ID.
-
-`--tracing.haystack.traceidheadername`:  
-Sets the header name used to store the trace ID.
-
-`--tracing.instana`:  
-Settings for Instana. (Default: ```false```)
-
-`--tracing.instana.enableautoprofile`:  
-Enables automatic profiling for the Traefik process. (Default: ```false```)
-
-`--tracing.instana.localagenthost`:  
-Sets the Instana Agent host.
-
-`--tracing.instana.localagentport`:  
-Sets the Instana Agent port. (Default: ```42699```)
-
-`--tracing.instana.loglevel`:  
-Sets the log level for the Instana tracer. ('error','warn','info','debug') (Default: ```info```)
-
-`--tracing.jaeger`:  
-Settings for Jaeger. (Default: ```false```)
-
-`--tracing.jaeger.collector.endpoint`:  
-Instructs reporter to send spans to jaeger-collector at this URL.
-
-`--tracing.jaeger.collector.password`:  
-Password for basic http authentication when sending spans to jaeger-collector.
-
-`--tracing.jaeger.collector.user`:  
-User for basic http authentication when sending spans to jaeger-collector.
-
-`--tracing.jaeger.disableattemptreconnecting`:  
-Disables the periodic re-resolution of the agent's hostname and reconnection if there was a change. (Default: ```true```)
-
-`--tracing.jaeger.gen128bit`:  
-Generates 128 bits span IDs. (Default: ```false```)
-
-`--tracing.jaeger.localagenthostport`:  
-Sets the Jaeger Agent host:port. (Default: ```127.0.0.1:6831```)
-
-`--tracing.jaeger.propagation`:  
-Sets the propagation format (jaeger/b3). (Default: ```jaeger```)
-
-`--tracing.jaeger.samplingparam`:  
-Sets the sampling parameter. (Default: ```1.000000```)
-
-`--tracing.jaeger.samplingserverurl`:  
-Sets the sampling server URL. (Default: ```http://localhost:5778/sampling```)
-
-`--tracing.jaeger.samplingtype`:  
-Sets the sampling type. (Default: ```const```)
-
-`--tracing.jaeger.tracecontextheadername`:  
-Sets the header name used to store the trace ID. (Default: ```uber-trace-id```)
+`--tracing.headers.<name>`:  
+Defines additional headers to be sent with the payloads.
 
-`--tracing.opentelemetry`:  
+`--tracing.otlp`:  
 Settings for OpenTelemetry. (Default: ```false```)
 
-`--tracing.opentelemetry.address`:  
-Sets the address (host:port) of the collector endpoint. (Default: ```localhost:4318```)
-
-`--tracing.opentelemetry.grpc`:  
-gRPC specific configuration for the OpenTelemetry collector. (Default: ```true```)
-
-`--tracing.opentelemetry.headers.<name>`:  
-Defines additional headers to be sent with the payloads.
+`--tracing.otlp.grpc.endpoint`:  
+Sets the gRPC endpoint (host:port) of the collector. (Default: ```localhost:4317```)
 
-`--tracing.opentelemetry.insecure`:  
+`--tracing.otlp.grpc.insecure`:  
 Disables client transport security for the exporter. (Default: ```false```)
 
-`--tracing.opentelemetry.path`:  
-Sets the URL path of the collector endpoint.
-
-`--tracing.opentelemetry.tls.ca`:  
+`--tracing.otlp.grpc.tls.ca`:  
 TLS CA
 
-`--tracing.opentelemetry.tls.cert`:  
+`--tracing.otlp.grpc.tls.cert`:  
 TLS cert
 
-`--tracing.opentelemetry.tls.insecureskipverify`:  
+`--tracing.otlp.grpc.tls.insecureskipverify`:  
 TLS insecure skip verify (Default: ```false```)
 
-`--tracing.opentelemetry.tls.key`:  
+`--tracing.otlp.grpc.tls.key`:  
 TLS key
 
-`--tracing.servicename`:  
-Set the name for this service. (Default: ```traefik```)
-
-`--tracing.spannamelimit`:  
-Set the maximum character limit for Span names (default 0 = no limit). (Default: ```0```)
+`--tracing.otlp.http.endpoint`:  
+Sets the HTTP endpoint (scheme://host:port/v1/traces) of the collector. (Default: ```localhost:4318```)
 
-`--tracing.zipkin`:  
-Settings for Zipkin. (Default: ```false```)
+`--tracing.otlp.http.tls.ca`:  
+TLS CA
 
-`--tracing.zipkin.httpendpoint`:  
-Sets the HTTP Endpoint to report traces to. (Default: ```http://localhost:9411/api/v2/spans```)
+`--tracing.otlp.http.tls.cert`:  
+TLS cert
 
-`--tracing.zipkin.id128bit`:  
-Uses 128 bits root span IDs. (Default: ```true```)
+`--tracing.otlp.http.tls.insecureskipverify`:  
+TLS insecure skip verify (Default: ```false```)
 
-`--tracing.zipkin.samespan`:  
-Uses SameSpan RPC style traces. (Default: ```false```)
+`--tracing.otlp.http.tls.key`:  
+TLS key
 
-`--tracing.zipkin.samplerate`:  
+`--tracing.samplerate`:  
 Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
+
+`--tracing.servicename`:  
+Set the name for this service. (Default: ```traefik```)
diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md
index 36dd4040c1..10659e2e1e 100644
--- a/docs/content/reference/static-configuration/env-ref.md
+++ b/docs/content/reference/static-configuration/env-ref.md
@@ -987,170 +987,50 @@ Defines the allowed SPIFFE trust domain.
 `TRAEFIK_TRACING`:  
 OpenTracing configuration. (Default: ```false```)
 
-`TRAEFIK_TRACING_DATADOG`:  
-Settings for Datadog. (Default: ```false```)
+`TRAEFIK_TRACING_GLOBALATTRIBUTES_<NAME>`:  
+Defines additional attributes (key:value) on all spans.
 
-`TRAEFIK_TRACING_DATADOG_BAGAGEPREFIXHEADERNAME`:  
-Sets the header name prefix used to store baggage items in a map.
-
-`TRAEFIK_TRACING_DATADOG_DEBUG`:  
-Enables Datadog debug. (Default: ```false```)
-
-`TRAEFIK_TRACING_DATADOG_GLOBALTAGS_<NAME>`:  
-Sets a list of key:value tags on all spans.
-
-`TRAEFIK_TRACING_DATADOG_LOCALAGENTHOSTPORT`:  
-Sets the Datadog Agent host:port. (Default: ```localhost:8126```)
-
-`TRAEFIK_TRACING_DATADOG_LOCALAGENTSOCKET`:  
-Sets the socket for the Datadog Agent.
-
-`TRAEFIK_TRACING_DATADOG_PARENTIDHEADERNAME`:  
-Sets the header name used to store the parent ID.
-
-`TRAEFIK_TRACING_DATADOG_PRIORITYSAMPLING`:  
-Enables priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled. (Default: ```false```)
-
-`TRAEFIK_TRACING_DATADOG_SAMPLINGPRIORITYHEADERNAME`:  
-Sets the header name used to store the sampling priority.
-
-`TRAEFIK_TRACING_DATADOG_TRACEIDHEADERNAME`:  
-Sets the header name used to store the trace ID.
-
-`TRAEFIK_TRACING_ELASTIC`:  
-Settings for Elastic. (Default: ```false```)
-
-`TRAEFIK_TRACING_ELASTIC_SECRETTOKEN`:  
-Sets the token used to connect to Elastic APM Server.
-
-`TRAEFIK_TRACING_ELASTIC_SERVERURL`:  
-Sets the URL of the Elastic APM server.
-
-`TRAEFIK_TRACING_ELASTIC_SERVICEENVIRONMENT`:  
-Sets the name of the environment Traefik is deployed in, e.g. 'production' or 'staging'.
-
-`TRAEFIK_TRACING_HAYSTACK`:  
-Settings for Haystack. (Default: ```false```)
-
-`TRAEFIK_TRACING_HAYSTACK_BAGGAGEPREFIXHEADERNAME`:  
-Sets the header name prefix used to store baggage items in a map.
-
-`TRAEFIK_TRACING_HAYSTACK_GLOBALTAG`:  
-Sets a key:value tag on all spans.
-
-`TRAEFIK_TRACING_HAYSTACK_LOCALAGENTHOST`:  
-Sets the Haystack Agent host. (Default: ```127.0.0.1```)
-
-`TRAEFIK_TRACING_HAYSTACK_LOCALAGENTPORT`:  
-Sets the Haystack Agent port. (Default: ```35000```)
-
-`TRAEFIK_TRACING_HAYSTACK_PARENTIDHEADERNAME`:  
-Sets the header name used to store the parent ID.
-
-`TRAEFIK_TRACING_HAYSTACK_SPANIDHEADERNAME`:  
-Sets the header name used to store the span ID.
-
-`TRAEFIK_TRACING_HAYSTACK_TRACEIDHEADERNAME`:  
-Sets the header name used to store the trace ID.
-
-`TRAEFIK_TRACING_INSTANA`:  
-Settings for Instana. (Default: ```false```)
-
-`TRAEFIK_TRACING_INSTANA_ENABLEAUTOPROFILE`:  
-Enables automatic profiling for the Traefik process. (Default: ```false```)
-
-`TRAEFIK_TRACING_INSTANA_LOCALAGENTHOST`:  
-Sets the Instana Agent host.
-
-`TRAEFIK_TRACING_INSTANA_LOCALAGENTPORT`:  
-Sets the Instana Agent port. (Default: ```42699```)
-
-`TRAEFIK_TRACING_INSTANA_LOGLEVEL`:  
-Sets the log level for the Instana tracer. ('error','warn','info','debug') (Default: ```info```)
-
-`TRAEFIK_TRACING_JAEGER`:  
-Settings for Jaeger. (Default: ```false```)
-
-`TRAEFIK_TRACING_JAEGER_COLLECTOR_ENDPOINT`:  
-Instructs reporter to send spans to jaeger-collector at this URL.
-
-`TRAEFIK_TRACING_JAEGER_COLLECTOR_PASSWORD`:  
-Password for basic http authentication when sending spans to jaeger-collector.
-
-`TRAEFIK_TRACING_JAEGER_COLLECTOR_USER`:  
-User for basic http authentication when sending spans to jaeger-collector.
-
-`TRAEFIK_TRACING_JAEGER_DISABLEATTEMPTRECONNECTING`:  
-Disables the periodic re-resolution of the agent's hostname and reconnection if there was a change. (Default: ```true```)
-
-`TRAEFIK_TRACING_JAEGER_GEN128BIT`:  
-Generates 128 bits span IDs. (Default: ```false```)
-
-`TRAEFIK_TRACING_JAEGER_LOCALAGENTHOSTPORT`:  
-Sets the Jaeger Agent host:port. (Default: ```127.0.0.1:6831```)
-
-`TRAEFIK_TRACING_JAEGER_PROPAGATION`:  
-Sets the propagation format (jaeger/b3). (Default: ```jaeger```)
-
-`TRAEFIK_TRACING_JAEGER_SAMPLINGPARAM`:  
-Sets the sampling parameter. (Default: ```1.000000```)
-
-`TRAEFIK_TRACING_JAEGER_SAMPLINGSERVERURL`:  
-Sets the sampling server URL. (Default: ```http://localhost:5778/sampling```)
-
-`TRAEFIK_TRACING_JAEGER_SAMPLINGTYPE`:  
-Sets the sampling type. (Default: ```const```)
-
-`TRAEFIK_TRACING_JAEGER_TRACECONTEXTHEADERNAME`:  
-Sets the header name used to store the trace ID. (Default: ```uber-trace-id```)
+`TRAEFIK_TRACING_HEADERS_<NAME>`:  
+Defines additional headers to be sent with the payloads.
 
-`TRAEFIK_TRACING_OPENTELEMETRY`:  
+`TRAEFIK_TRACING_OTLP`:  
 Settings for OpenTelemetry. (Default: ```false```)
 
-`TRAEFIK_TRACING_OPENTELEMETRY_ADDRESS`:  
-Sets the address (host:port) of the collector endpoint. (Default: ```localhost:4318```)
-
-`TRAEFIK_TRACING_OPENTELEMETRY_GRPC`:  
-gRPC specific configuration for the OpenTelemetry collector. (Default: ```true```)
-
-`TRAEFIK_TRACING_OPENTELEMETRY_HEADERS_<NAME>`:  
-Defines additional headers to be sent with the payloads.
+`TRAEFIK_TRACING_OTLP_GRPC_ENDPOINT`:  
+Sets the gRPC endpoint (host:port) of the collector. (Default: ```localhost:4317```)
 
-`TRAEFIK_TRACING_OPENTELEMETRY_INSECURE`:  
+`TRAEFIK_TRACING_OTLP_GRPC_INSECURE`:  
 Disables client transport security for the exporter. (Default: ```false```)
 
-`TRAEFIK_TRACING_OPENTELEMETRY_PATH`:  
-Sets the URL path of the collector endpoint.
-
-`TRAEFIK_TRACING_OPENTELEMETRY_TLS_CA`:  
+`TRAEFIK_TRACING_OTLP_GRPC_TLS_CA`:  
 TLS CA
 
-`TRAEFIK_TRACING_OPENTELEMETRY_TLS_CERT`:  
+`TRAEFIK_TRACING_OTLP_GRPC_TLS_CERT`:  
 TLS cert
 
-`TRAEFIK_TRACING_OPENTELEMETRY_TLS_INSECURESKIPVERIFY`:  
+`TRAEFIK_TRACING_OTLP_GRPC_TLS_INSECURESKIPVERIFY`:  
 TLS insecure skip verify (Default: ```false```)
 
-`TRAEFIK_TRACING_OPENTELEMETRY_TLS_KEY`:  
+`TRAEFIK_TRACING_OTLP_GRPC_TLS_KEY`:  
 TLS key
 
-`TRAEFIK_TRACING_SERVICENAME`:  
-Set the name for this service. (Default: ```traefik```)
-
-`TRAEFIK_TRACING_SPANNAMELIMIT`:  
-Set the maximum character limit for Span names (default 0 = no limit). (Default: ```0```)
+`TRAEFIK_TRACING_OTLP_HTTP_ENDPOINT`:  
+Sets the HTTP endpoint (scheme://host:port/v1/traces) of the collector. (Default: ```localhost:4318```)
 
-`TRAEFIK_TRACING_ZIPKIN`:  
-Settings for Zipkin. (Default: ```false```)
+`TRAEFIK_TRACING_OTLP_HTTP_TLS_CA`:  
+TLS CA
 
-`TRAEFIK_TRACING_ZIPKIN_HTTPENDPOINT`:  
-Sets the HTTP Endpoint to report traces to. (Default: ```http://localhost:9411/api/v2/spans```)
+`TRAEFIK_TRACING_OTLP_HTTP_TLS_CERT`:  
+TLS cert
 
-`TRAEFIK_TRACING_ZIPKIN_ID128BIT`:  
-Uses 128 bits root span IDs. (Default: ```true```)
+`TRAEFIK_TRACING_OTLP_HTTP_TLS_INSECURESKIPVERIFY`:  
+TLS insecure skip verify (Default: ```false```)
 
-`TRAEFIK_TRACING_ZIPKIN_SAMESPAN`:  
-Uses SameSpan RPC style traces. (Default: ```false```)
+`TRAEFIK_TRACING_OTLP_HTTP_TLS_KEY`:  
+TLS key
 
-`TRAEFIK_TRACING_ZIPKIN_SAMPLERATE`:  
+`TRAEFIK_TRACING_SAMPLERATE`:  
 Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
+
+`TRAEFIK_TRACING_SERVICENAME`:  
+Set the name for this service. (Default: ```traefik```)
diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml
index 6d75b4dbcb..58acc5ac76 100644
--- a/docs/content/reference/static-configuration/file.toml
+++ b/docs/content/reference/static-configuration/file.toml
@@ -367,68 +367,28 @@
 
 [tracing]
   serviceName = "foobar"
-  spanNameLimit = 42
-  [tracing.jaeger]
-    samplingServerURL = "foobar"
-    samplingType = "foobar"
-    samplingParam = 42.0
-    localAgentHostPort = "foobar"
-    gen128Bit = true
-    propagation = "foobar"
-    traceContextHeaderName = "foobar"
-    disableAttemptReconnecting = true
-    [tracing.jaeger.collector]
-      endpoint = "foobar"
-      user = "foobar"
-      password = "foobar"
-  [tracing.zipkin]
-    httpEndpoint = "foobar"
-    sameSpan = true
-    id128Bit = true
-    sampleRate = 42.0
-  [tracing.datadog]
-    localAgentHostPort = "foobar"
-    localAgentSocket = "foobar"
-    [tracing.datadog.globalTags]
-      tag1 = "foobar"
-      tag2 = "foobar"
-    debug = true
-    prioritySampling = true
-    traceIDHeaderName = "foobar"
-    parentIDHeaderName = "foobar"
-    samplingPriorityHeaderName = "foobar"
-    bagagePrefixHeaderName = "foobar"
-  [tracing.instana]
-    localAgentHost = "foobar"
-    localAgentPort = 42
-    logLevel = "foobar"
-    enableAutoProfile = true
-  [tracing.haystack]
-    localAgentHost = "foobar"
-    localAgentPort = 42
-    globalTag = "foobar"
-    traceIDHeaderName = "foobar"
-    parentIDHeaderName = "foobar"
-    spanIDHeaderName = "foobar"
-    baggagePrefixHeaderName = "foobar"
-  [tracing.elastic]
-    serverURL = "foobar"
-    secretToken = "foobar"
-    serviceEnvironment = "foobar"
-  [tracing.openTelemetry]
-    address = "foobar"
+  sampleRate = 42
+  [tracing.headers]
+    header1 = "foobar"
+    header2 = "foobar"
+  [tracing.globalAttributes]
+    attr1 = "foobar"
+    attr2 = "foobar"
+  [tracing.otlp.grpc]
+    endpoint = "foobar"
     insecure = true
-    path = "foobar"
-    [tracing.openTelemetry.headers]
-      name0 = "foobar"
-      name1 = "foobar"
-    [tracing.openTelemetry.tls]
+    [tracing.otlp.grpc.tls]
       ca = "foobar"
-      caOptional = true
       cert = "foobar"
       key = "foobar"
       insecureSkipVerify = true
-    [tracing.openTelemetry.grpc]
+  [tracing.otlp.http]
+    endpoint = "foobar"
+    [tracing.otlp.http.tls]
+    ca = "foobar"
+    cert = "foobar"
+    key = "foobar"
+    insecureSkipVerify = true
 
 [hostResolver]
   cnameFlattening = true
diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml
index 4410e29eb0..d822979c92 100644
--- a/docs/content/reference/static-configuration/file.yaml
+++ b/docs/content/reference/static-configuration/file.yaml
@@ -397,68 +397,29 @@ accessLog:
   bufferingSize: 42
 tracing:
   serviceName: foobar
-  spanNameLimit: 42
-  jaeger:
-    samplingServerURL: foobar
-    samplingType: foobar
-    samplingParam: 42
-    localAgentHostPort: foobar
-    gen128Bit: true
-    propagation: foobar
-    traceContextHeaderName: foobar
-    disableAttemptReconnecting: true
-    collector:
+  sampleRate: 42
+  headers:
+    header1: foobar
+    header2: foobar
+  globalAttributes:
+    attr1: foobar
+    attr2: foobar
+  otlp:
+    grpc:
       endpoint: foobar
-      user: foobar
-      password: foobar
-  zipkin:
-    httpEndpoint: foobar
-    sameSpan: true
-    id128Bit: true
-    sampleRate: 42
-  datadog:
-    localAgentHostPort: foobar
-    localAgentSocket: foobar
-    globalTags:
-      tag1: foobar
-      tag2: foobar
-    debug: true
-    prioritySampling: true
-    traceIDHeaderName: foobar
-    parentIDHeaderName: foobar
-    samplingPriorityHeaderName: foobar
-    bagagePrefixHeaderName: foobar
-  instana:
-    localAgentHost: foobar
-    localAgentPort: 42
-    logLevel: foobar
-    enableAutoProfile: true
-  haystack:
-    localAgentHost: foobar
-    localAgentPort: 42
-    globalTag: foobar
-    traceIDHeaderName: foobar
-    parentIDHeaderName: foobar
-    spanIDHeaderName: foobar
-    baggagePrefixHeaderName: foobar
-  elastic:
-    serverURL: foobar
-    secretToken: foobar
-    serviceEnvironment: foobar
-  openTelemetry:
-    address: foobar
-    headers:
-      name0: foobar
-      name1: foobar
-    insecure: true
-    path: foobar
-    tls:
-      ca: foobar
-      caOptional: true
-      cert: foobar
-      key: foobar
-      insecureSkipVerify: true
-    grpc: {}
+      insecure: true
+      tls:
+        ca: foobar
+        cert: foobar
+        key: foobar
+        insecureSkipVerify: true
+    http:
+      endpoint: foobar
+      tls:
+        ca: foobar
+        cert: foobar
+        key: foobar
+        insecureSkipVerify: true
 hostResolver:
   cnameFlattening: true
   resolvConfig: foobar
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index 01cd88a984..6ba875a3fd 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -153,19 +153,9 @@ nav:
       - 'Access Logs': 'observability/access-logs.md'
       - 'Metrics':
           - 'Overview': 'observability/metrics/overview.md'
-          - 'Datadog': 'observability/metrics/datadog.md'
-          - 'InfluxDB2': 'observability/metrics/influxdb2.md'
           - 'OpenTelemetry': 'observability/metrics/opentelemetry.md'
-          - 'Prometheus': 'observability/metrics/prometheus.md'
-          - 'StatsD': 'observability/metrics/statsd.md'
       - 'Tracing':
           - 'Overview': 'observability/tracing/overview.md'
-          - 'Jaeger': 'observability/tracing/jaeger.md'
-          - 'Zipkin': 'observability/tracing/zipkin.md'
-          - 'Datadog': 'observability/tracing/datadog.md'
-          - 'Instana': 'observability/tracing/instana.md'
-          - 'Haystack': 'observability/tracing/haystack.md'
-          - 'Elastic': 'observability/tracing/elastic.md'
           - 'OpenTelemetry': 'observability/tracing/opentelemetry.md'
   - 'User Guides':
       - 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md'
diff --git a/go.mod b/go.mod
index f0a5faf498..25d529a2d9 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,6 @@ go 1.21
 
 require (
 	github.com/BurntSushi/toml v1.3.2
-	github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61
 	github.com/Masterminds/sprig/v3 v3.2.3
 	github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
 	github.com/andybalholm/brotli v1.0.6
@@ -36,7 +35,6 @@ require (
 	github.com/http-wasm/http-wasm-host-go v0.5.2
 	github.com/influxdata/influxdb-client-go/v2 v2.7.0
 	github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
-	github.com/instana/go-sensor v1.38.3
 	github.com/klauspost/compress v1.17.1
 	github.com/kvtools/consul v1.0.2
 	github.com/kvtools/etcdv3 v1.0.2
@@ -49,54 +47,46 @@ require (
 	github.com/mitchellh/hashstructure v1.0.0
 	github.com/mitchellh/mapstructure v1.5.0
 	github.com/natefinch/lumberjack v0.0.0-20201021141957-47ffae23317c
-	github.com/opentracing/opentracing-go v1.2.0
-	github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5
-	github.com/openzipkin/zipkin-go v0.2.2
 	github.com/patrickmn/go-cache v2.1.0+incompatible
 	github.com/pires/go-proxyproto v0.6.1
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
 	github.com/prometheus/client_golang v1.14.0
 	github.com/prometheus/client_model v0.3.0
 	github.com/quic-go/quic-go v0.40.1
-	github.com/rs/zerolog v1.28.0
+	github.com/rs/zerolog v1.29.0
 	github.com/sirupsen/logrus v1.9.3
 	github.com/spiffe/go-spiffe/v2 v2.1.1
 	github.com/stretchr/testify v1.8.4
 	github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154
 	github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2
 	github.com/tetratelabs/wazero v1.5.0
+	github.com/tidwall/gjson v1.17.0
 	github.com/traefik/grpc-web v0.16.0
 	github.com/traefik/paerser v0.2.0
 	github.com/traefik/yaegi v0.15.1
-	github.com/uber/jaeger-client-go v2.30.0+incompatible
-	github.com/uber/jaeger-lib v2.2.0+incompatible
 	github.com/unrolled/render v1.0.2
 	github.com/unrolled/secure v1.0.9
 	github.com/vdemeester/shakers v0.1.0
 	github.com/vulcand/oxy/v2 v2.0.0-20230427132221-be5cf38f3c1c
 	github.com/vulcand/predicate v1.2.0
-	go.elastic.co/apm v1.13.1
-	go.elastic.co/apm/module/apmot v1.13.1
 	go.opentelemetry.io/collector/pdata v0.66.0
-	go.opentelemetry.io/otel v1.19.0
-	go.opentelemetry.io/otel/bridge/opentracing v1.19.0
-	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0
-	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0
-	go.opentelemetry.io/otel/metric v1.19.0
-	go.opentelemetry.io/otel/sdk v1.19.0
-	go.opentelemetry.io/otel/sdk/metric v1.19.0
-	go.opentelemetry.io/otel/trace v1.19.0
+	go.opentelemetry.io/otel v1.21.0
+	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0
+	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0
+	go.opentelemetry.io/otel/metric v1.21.0
+	go.opentelemetry.io/otel/sdk v1.21.0
+	go.opentelemetry.io/otel/sdk/metric v1.21.0
+	go.opentelemetry.io/otel/trace v1.21.0
 	golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
 	golang.org/x/mod v0.12.0
 	golang.org/x/net v0.17.0
 	golang.org/x/text v0.13.0
 	golang.org/x/time v0.3.0
 	golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846
-	google.golang.org/grpc v1.58.3
-	gopkg.in/DataDog/dd-trace-go.v1 v1.56.1
+	google.golang.org/grpc v1.59.0
 	gopkg.in/yaml.v3 v3.0.1
 	k8s.io/api v0.26.3
 	k8s.io/apiextensions-apiserver v0.26.3
@@ -129,13 +119,6 @@ require (
 	github.com/Azure/go-autorest/logger v0.2.1 // indirect
 	github.com/Azure/go-autorest/tracing v0.6.0 // indirect
 	github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
-	github.com/DataDog/appsec-internal-go v1.0.0 // indirect
-	github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 // indirect
-	github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df // indirect
-	github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
-	github.com/DataDog/go-libddwaf v1.5.0 // indirect
-	github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect
-	github.com/DataDog/sketches-go v1.4.2 // indirect
 	github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
 	github.com/Masterminds/goutils v1.1.1 // indirect
 	github.com/Masterminds/semver/v3 v3.2.0 // indirect
@@ -148,7 +131,6 @@ require (
 	github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755 // indirect
 	github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
 	github.com/armon/go-metrics v0.4.1 // indirect
-	github.com/armon/go-radix v1.0.0 // indirect
 	github.com/aws/aws-sdk-go-v2 v1.20.3 // indirect
 	github.com/aws/aws-sdk-go-v2/config v1.18.28 // indirect
 	github.com/aws/aws-sdk-go-v2/credentials v1.13.27 // indirect
@@ -190,26 +172,23 @@ require (
 	github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
 	github.com/docker/go-metrics v0.0.1 // indirect
 	github.com/docker/go-units v0.4.0 // indirect
-	github.com/dustin/go-humanize v1.0.1 // indirect
-	github.com/ebitengine/purego v0.5.0-alpha.1 // indirect
-	github.com/elastic/go-licenser v0.3.1 // indirect
-	github.com/elastic/go-sysinfo v1.1.1 // indirect
-	github.com/elastic/go-windows v1.0.0 // indirect
 	github.com/emicklei/go-restful/v3 v3.11.0 // indirect
 	github.com/evanphx/json-patch v4.12.0+incompatible // indirect
 	github.com/exoscale/egoscale v0.100.1 // indirect
 	github.com/fatih/color v1.15.0 // indirect
 	github.com/fvbommel/sortorder v1.0.1 // indirect
 	github.com/ghodss/yaml v1.0.0 // indirect
+	github.com/gin-gonic/gin v1.7.7 // indirect
 	github.com/go-errors/errors v1.0.1 // indirect
 	github.com/go-jose/go-jose/v3 v3.0.0 // indirect
 	github.com/go-logfmt/logfmt v0.5.1 // indirect
-	github.com/go-logr/logr v1.2.4 // indirect
+	github.com/go-logr/logr v1.3.0 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-openapi/jsonpointer v0.19.5 // indirect
 	github.com/go-openapi/jsonreference v0.20.0 // indirect
 	github.com/go-openapi/swag v0.19.14 // indirect
 	github.com/go-resty/resty/v2 v2.7.0 // indirect
+	github.com/go-sql-driver/mysql v1.6.0 // indirect
 	github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
 	github.com/go-zookeeper/zk v1.0.3 // indirect
 	github.com/gofrs/flock v0.8.0 // indirect
@@ -219,7 +198,7 @@ require (
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/mock v1.6.0 // indirect
 	github.com/google/gnostic v0.5.7-v3refs // indirect
-	github.com/google/go-cmp v0.5.9 // indirect
+	github.com/google/go-cmp v0.6.0 // indirect
 	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect
@@ -248,9 +227,7 @@ require (
 	github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
 	github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect
 	github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea // indirect
-	github.com/jcchavezs/porto v0.1.0 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
-	github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
 	github.com/jonboulle/clockwork v0.2.2 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
@@ -264,7 +241,6 @@ require (
 	github.com/liquidweb/go-lwApi v0.0.5 // indirect
 	github.com/liquidweb/liquidweb-cli v0.6.9 // indirect
 	github.com/liquidweb/liquidweb-go v1.6.3 // indirect
-	github.com/looplab/fsm v0.1.0 // indirect
 	github.com/magiconair/properties v1.8.6 // indirect
 	github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f // indirect
 	github.com/mailgun/multibuf v0.1.2 // indirect
@@ -300,15 +276,14 @@ require (
 	github.com/nrdcg/porkbun v0.2.0 // indirect
 	github.com/nzdjb/go-metaname v1.0.0 // indirect
 	github.com/onsi/ginkgo v1.16.5 // indirect
-	github.com/onsi/ginkgo/v2 v2.9.5 // indirect
+	github.com/onsi/ginkgo/v2 v2.11.0 // indirect
+	github.com/onsi/gomega v1.27.10 // indirect
 	github.com/opencontainers/go-digest v1.0.0 // indirect
-	github.com/opencontainers/image-spec v1.0.2 // indirect
+	github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
 	github.com/opencontainers/runc v1.1.5 // indirect
-	github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect
+	github.com/opentracing/opentracing-go v1.2.0 // indirect
 	github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
-	github.com/outcaste-io/ristretto v0.2.3 // indirect
 	github.com/ovh/go-ovh v1.4.1 // indirect
-	github.com/philhofer/fwd v1.1.2 // indirect
 	github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pquerna/otp v1.4.0 // indirect
@@ -323,22 +298,21 @@ require (
 	github.com/sacloud/iaas-api-go v1.11.1 // indirect
 	github.com/sacloud/packages-go v0.0.9 // indirect
 	github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b // indirect
-	github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
 	github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 // indirect
-	github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
 	github.com/shopspring/decimal v1.2.0 // indirect
 	github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // indirect
 	github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
 	github.com/softlayer/softlayer-go v1.1.2 // indirect
 	github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
-	github.com/spf13/cast v1.3.1 // indirect
+	github.com/spf13/cast v1.5.0 // indirect
 	github.com/spf13/cobra v1.6.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/stretchr/objx v0.5.1 // indirect
 	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 // indirect
 	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 // indirect
 	github.com/theupdateframework/notary v0.6.1 // indirect
-	github.com/tinylib/msgp v1.1.8 // indirect
+	github.com/tidwall/match v1.1.1 // indirect
+	github.com/tidwall/pretty v1.2.0 // indirect
 	github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 // indirect
 	github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
 	github.com/transip/gotransip/v6 v6.20.0 // indirect
@@ -351,42 +325,34 @@ require (
 	github.com/yandex-cloud/go-genproto v0.0.0-20220805142335-27b56ddae16f // indirect
 	github.com/yandex-cloud/go-sdk v0.0.0-20220805164847-cf028e604997 // indirect
 	github.com/zeebo/errs v1.2.2 // indirect
-	go.elastic.co/apm/module/apmhttp v1.13.1 // indirect
-	go.elastic.co/fastjson v1.1.0 // indirect
 	go.etcd.io/etcd/api/v3 v3.5.5 // indirect
 	go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
 	go.etcd.io/etcd/client/v3 v3.5.5 // indirect
 	go.opencensus.io v0.24.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.0.0 // indirect
 	go.uber.org/atomic v1.11.0 // indirect
 	go.uber.org/mock v0.3.0 // indirect
 	go.uber.org/multierr v1.8.0 // indirect
 	go.uber.org/ratelimit v0.2.0 // indirect
 	go.uber.org/zap v1.21.0 // indirect
-	go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect
-	go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect
 	golang.org/x/crypto v0.14.0 // indirect
-	golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
-	golang.org/x/oauth2 v0.10.0 // indirect
+	golang.org/x/oauth2 v0.11.0 // indirect
 	golang.org/x/sync v0.3.0 // indirect
-	golang.org/x/sys v0.13.0 // indirect
+	golang.org/x/sys v0.14.0 // indirect
 	golang.org/x/term v0.13.0 // indirect
-	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
 	google.golang.org/api v0.128.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
+	google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
+	gopkg.in/h2non/gock.v1 v1.0.16 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/ns1/ns1-go.v2 v2.7.6 // indirect
 	gopkg.in/square/go-jose.v2 v2.5.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
-	howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
-	inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect
-	k8s.io/klog/v2 v2.80.1 // indirect
+	k8s.io/klog/v2 v2.90.1 // indirect
 	k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
 	nhooyr.io/websocket v1.8.7 // indirect
 	sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
diff --git a/go.sum b/go.sum
index 9780e2eb57..e51ba44398 100644
--- a/go.sum
+++ b/go.sum
@@ -118,25 +118,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
 github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/DataDog/appsec-internal-go v1.0.0 h1:2u5IkF4DBj3KVeQn5Vg2vjPUtt513zxEYglcqnd500U=
-github.com/DataDog/appsec-internal-go v1.0.0/go.mod h1:+Y+4klVWKPOnZx6XESG7QHydOaUGEXyH2j/vSg9JiNM=
-github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 h1:bUMSNsw1iofWiju9yc1f+kBd33E3hMJtq9GuU602Iy8=
-github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0/go.mod h1:HzySONXnAgSmIQfL6gOv9hWprKJkx8CicuXuUbmgWfo=
-github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df h1:PbzrhHhs2+RRdKKti7JBSM8ATIeiji2T2cVt/d8GT8k=
-github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df/go.mod h1:5Q39ZOIOwZMnFyRadp+5gH1bFdjmb+Pgxe+j5XOwaTg=
 github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
-github.com/DataDog/datadog-go/v5 v5.3.0 h1:2q2qjFOb3RwAZNU+ez27ZVDwErJv5/VpbBPprz7Z+s8=
-github.com/DataDog/datadog-go/v5 v5.3.0/go.mod h1:XRDJk1pTc00gm+ZDiBKsjh7oOOtJfYfglVCmFb8C2+Q=
-github.com/DataDog/go-libddwaf v1.5.0 h1:lrHP3VrEriy1M5uQuaOcKphf5GU40mBhihMAp6Ik55c=
-github.com/DataDog/go-libddwaf v1.5.0/go.mod h1:Fpnmoc2k53h6desQrH1P0/gR52CUzkLNFugE5zWwUBQ=
-github.com/DataDog/go-tuf v1.0.2-0.5.2 h1:EeZr937eKAWPxJ26IykAdWA4A0jQXJgkhUjqEI/w7+I=
-github.com/DataDog/go-tuf v1.0.2-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0=
-github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4=
-github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM=
-github.com/DataDog/sketches-go v1.4.2 h1:gppNudE9d19cQ98RYABOetxIhpTCl4m7CnbRZjvVA/o=
-github.com/DataDog/sketches-go v1.4.2/go.mod h1:xJIXldczJyyjnbDop7ZZcLxJdV3+7Kra7H1KMgpgkLk=
-github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61 h1:1NIUJ+MAMpqDr4LWIfNsoJR+G7zg/8GZVwuRkmJxtTc=
-github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61/go.mod h1:62qWSDaEI0BLykU+zQza5CAKgW0lOy9oBSz3/DvYz4w=
 github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
 github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
 github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
@@ -157,7 +139,6 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
 github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
 github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
 github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
 github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
 github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
 github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
@@ -188,8 +169,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
 github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
 github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
-github.com/Shopify/sarama v1.38.1 h1:lqqPUPQZ7zPqYlWpTh+LQ9bhYNu2xJL6k1SJN4WVe2A=
-github.com/Shopify/sarama v1.38.1/go.mod h1:iwv9a67Ha8VNa+TifujYoWGxWnu2kNVAQdSdZ4X2o5g=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
@@ -227,7 +206,6 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
 github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
 github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
 github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
@@ -308,8 +286,6 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq
 github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
 github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA=
 github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
-github.com/bytedance/sonic v1.10.0 h1:qtNZduETEIWJVIyDl01BeNxur2rW9OwTQ/yBqFRkKEk=
-github.com/bytedance/sonic v1.10.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
 github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
 github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
 github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
@@ -330,10 +306,6 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
 github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
 github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
 github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
-github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
-github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
-github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
-github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -370,7 +342,6 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH
 github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
-github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
 github.com/compose-spec/compose-go v1.0.2/go.mod h1:gCIA3No0j5nNszz2X0yd/mkigTIWcOgHiPa9guWvoec=
 github.com/compose-spec/compose-go v1.0.3 h1:yvut1x9H4TUMptNA4mZ63VGVtDNX1OKy2TZCi6yFw8Q=
@@ -546,8 +517,6 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe
 github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
 github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
-github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
@@ -617,28 +586,12 @@ github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZ
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
 github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
-github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
-github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
 github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
-github.com/eapache/go-resiliency v1.4.0 h1:3OK9bWpPk5q6pbFAaYSEwD9CLUSHG8bnZuqX2yMt3B0=
-github.com/eapache/go-resiliency v1.4.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
-github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws=
-github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
-github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
-github.com/ebitengine/purego v0.5.0-alpha.1 h1:0gVgWGb8GjKYs7cufvfNSleJAD00m2xWC26FMwOjNrw=
-github.com/ebitengine/purego v0.5.0-alpha.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
 github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
 github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
 github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
-github.com/elastic/go-licenser v0.3.1 h1:RmRukU/JUmts+rpexAw0Fvt2ly7VVu6mw8z4HrEzObU=
-github.com/elastic/go-licenser v0.3.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ=
-github.com/elastic/go-sysinfo v1.1.1 h1:ZVlaLDyhVkDfjwPGU55CQRCRolNpc7P0BbyhhQZQmMI=
-github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0=
-github.com/elastic/go-windows v1.0.0 h1:qLURgZFkkrYyTTkvYpsZIgf83AUsdIHfvlJaqaZ7aSY=
-github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU=
 github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
@@ -682,6 +635,8 @@ github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD
 github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
 github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
 github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
+github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
+github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
@@ -703,8 +658,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
 github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
-github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
-github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
+github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
+github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
 github.com/go-acme/lego/v4 v4.14.0 h1:/skZoRHgVh0d2RK7l1g3Ch8HqeqP9LB8ZEjLdGEpcDE=
 github.com/go-acme/lego/v4 v4.14.0/go.mod h1:zjmvNCDLGz7GrC1OqdVpVmZFKSRabEDtWbdzmcpBsGo=
@@ -734,8 +689,8 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
 github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
-github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
+github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
@@ -770,8 +725,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
 github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
 github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
 github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
-github.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM=
-github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
+github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
+github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
 github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
 github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
 github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -801,8 +756,6 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E
 github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk=
 github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
 github.com/goccy/go-json v0.7.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
-github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
-github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
 github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
 github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
@@ -814,9 +767,8 @@ github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j
 github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY=
 github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
 github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
 github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
-github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
 github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
 github.com/gogo/googleapis v1.3.0/go.mod h1:d+q1s/xVJxZGKWwC/6UfPIF33J+G1Tq4GYv9Y+Tg/EU=
@@ -839,8 +791,8 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW
 github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
-github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
+github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
+github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
 github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -880,8 +832,6 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
 github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
 github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
-github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
 github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
 github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -907,8 +857,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-containerregistry v0.0.0-20191015185424-71da34e4d9b3/go.mod h1:ZXFeSndFcK4vB1NR4voH1Zm38K7ViUNiYtfIBDxrwf0=
 github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo=
 github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
@@ -1068,9 +1018,8 @@ github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG
 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
 github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
-github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM=
-github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
 github.com/hashicorp/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
 github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
 github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
@@ -1114,32 +1063,15 @@ github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7
 github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
 github.com/infobloxopen/infoblox-go-client v1.1.1 h1:728A6LbLjptj/7kZjHyIxQnm768PWHfGFm0HH8FnbtU=
 github.com/infobloxopen/infoblox-go-client v1.1.1/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI=
-github.com/instana/go-sensor v1.38.3 h1:/PdHEDveLmUCvK+O6REvSv8kKljX8vaj9JMjMeCHAWk=
-github.com/instana/go-sensor v1.38.3/go.mod h1:E42MelHWFz11qqaLwvgt0j98v2s2O/bq22UDkGaG0Gg=
-github.com/instana/testify v1.6.2-0.20200721153833-94b1851f4d65 h1:T25FL3WEzgmKB0m6XCJNZ65nw09/QIp3T1yXr487D+A=
-github.com/instana/testify v1.6.2-0.20200721153833-94b1851f4d65/go.mod h1:nYhEREG/B7HUY7P+LKOrqy53TpIqmJ9JyUShcaEKtGw=
 github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
 github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
 github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
 github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
 github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
-github.com/jcchavezs/porto v0.1.0 h1:Xmxxn25zQMmgE7/yHYmh19KcItG81hIwfbEEFnd6w/Q=
-github.com/jcchavezs/porto v0.1.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A=
-github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
-github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
-github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
-github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
-github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
-github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
-github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
-github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
-github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
-github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
 github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
+github.com/jinzhu/gorm v1.9.11 h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE=
 github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw=
-github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
-github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
 github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
@@ -1155,8 +1087,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo=
 github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU=
-github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4=
-github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
 github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
@@ -1198,8 +1128,6 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
 github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.17.1 h1:NE3C767s2ak2bweCZo3+rdP4U/HoyVXLv/X9f2gPS5g=
 github.com/klauspost/compress v1.17.1/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
-github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
-github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
 github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
 github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -1270,8 +1198,6 @@ github.com/liquidweb/liquidweb-cli v0.6.9/go.mod h1:cE1uvQ+x24NGUL75D0QagOFCG8Wd
 github.com/liquidweb/liquidweb-go v1.6.3 h1:NVHvcnX3eb3BltiIoA+gLYn15nOpkYkdizOEYGSKrk4=
 github.com/liquidweb/liquidweb-go v1.6.3/go.mod h1:SuXXp+thr28LnjEw18AYtWwIbWMHSUiajPQs8T9c/Rc=
 github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
-github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20=
-github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
 github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -1469,8 +1395,8 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
 github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
 github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
-github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
-github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
+github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
+github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
 github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -1484,8 +1410,8 @@ github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+t
 github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
 github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
 github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
-github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
-github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
+github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
+github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
 github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -1495,8 +1421,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
-github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=
+github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
 github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@@ -1521,7 +1447,6 @@ github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3
 github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
 github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU=
 github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
-github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=
 github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
 github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU=
 github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
@@ -1529,16 +1454,12 @@ github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
 github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
-github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU=
 github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
 github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
-github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI=
 github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
 github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
 github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
-github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0=
-github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac=
 github.com/ovh/go-ovh v1.4.1 h1:VBGa5wMyQtTP7Zb+w97zRCh9sLtM/2YKRyy+MEJmWaM=
 github.com/ovh/go-ovh v1.4.1/go.mod h1:6bL6pPyUT7tBfI0pqOegJgRjgjuO+mOo+MyXd1EEC0M=
 github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
@@ -1552,17 +1473,10 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
 github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
 github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
 github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
-github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
 github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
-github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
-github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
 github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
-github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
-github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw=
 github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
 github.com/pivotal/image-relocation v0.0.0-20191111101224-e94aff6df06c/go.mod h1:/JNbQwGylYm3AQh8q+MBF8e/h0W1Jy20JGTvozuXYTE=
@@ -1626,7 +1540,6 @@ github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJ
 github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
@@ -1649,26 +1562,22 @@ github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58
 github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q=
 github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
-github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
 github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
-github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052 h1:Qp27Idfgi6ACvFQat5+VJvlYToylpM/hcyLBI3WaKPA=
-github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052/go.mod h1:uvX/8buq8uVeiZiFht+0lqSLBHF+uGV8BrTv8W/SIwk=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
 github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
 github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
 github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
-github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
-github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
+github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
+github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -1685,8 +1594,6 @@ github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiB
 github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
 github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b h1:jUK33OXuZP/l6babJtnLo1qsGvq6G9so9KMflGAm4YA=
 github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b/go.mod h1:8458kAagoME2+LN5//WxE71ysZ3B7r22fdgb7qVmXSY=
-github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis=
-github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 h1:1WuWJu7/e8SqK+uQl7lfk/N/oMZTL2NE/TJsNKRNMc4=
 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
@@ -1694,8 +1601,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
 github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
-github.com/secure-systems-lab/go-securesystemslib v0.7.0 h1:OwvJ5jQf9LnIAS83waAjPbcMsODrTQUpJ02eNLUoxBg=
-github.com/secure-systems-lab/go-securesystemslib v0.7.0/go.mod h1:/2gYnlnHVQ6xeGtfIqFy7Do03K4cdCY0A/GlJLDKLHI=
 github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
 github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
@@ -1733,16 +1638,15 @@ github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e/go.mod h1:fKZCUVd
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
-github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
-github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
 github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
 github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
+github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
 github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
@@ -1817,8 +1721,12 @@ github.com/tetratelabs/wazero v1.5.0 h1:Yz3fZHivfDiZFUXnWMPUoiW7s8tC1sjdBtlJn08q
 github.com/tetratelabs/wazero v1.5.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
 github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=
 github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
-github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
-github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
+github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
+github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
+github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
+github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
+github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 h1:014iQD8i8EabPWK2XgUuOTxg5s2nhfDmq6GupskfUO8=
@@ -1836,12 +1744,7 @@ github.com/traefik/yaegi v0.15.1/go.mod h1:AVRxhaI2G+nUsaM1zyktzwXn69G3t/AuTDrCi
 github.com/transip/gotransip/v6 v6.20.0 h1:AuvwyOZ51f2brzMbTqlRy/wmaM3kF7Vx5Wds8xcDflY=
 github.com/transip/gotransip/v6 v6.20.0/go.mod h1:nzv9eN2tdsUrm5nG5ZX6AugYIU4qgsMwIn2c0EZLk8c=
 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
-github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
-github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
-github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
-github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
-github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
 github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
 github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
@@ -1849,9 +1752,8 @@ github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
 github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
 github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
-github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
-github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/ultradns/ultradns-go-sdk v1.5.0-20230427130837-23c9b0c h1:mKnW6IGLw7uXu6DL6RitufZWcXS6hCnauXRUFof7rKM=
 github.com/ultradns/ultradns-go-sdk v1.5.0-20230427130837-23c9b0c/go.mod h1:F4UyVEmq4/m5lAmx+GccrxyRCXmnBjzUL09JLTQFp94=
 github.com/unrolled/render v1.0.2 h1:dGS3EmChQP3yOi1YeFNO/Dx+MbWZhdvhQJTXochM5bs=
@@ -1927,14 +1829,6 @@ github.com/zmap/zcrypto v0.0.0-20190729165852-9051775e6a2e h1:mvOa4+/DXStR4ZXOks
 github.com/zmap/zcrypto v0.0.0-20190729165852-9051775e6a2e/go.mod h1:w7kd3qXHh8FNaczNjslXqvFQiv5mMWRXlL9klTUAHc8=
 github.com/zmap/zlint v0.0.0-20190806154020-fd021b4cfbeb h1:vxqkjztXSaPVDc8FQCdHTaejm2x747f6yPbnu1h2xkg=
 github.com/zmap/zlint v0.0.0-20190806154020-fd021b4cfbeb/go.mod h1:29UiAJNsiVdvTBFCJW8e3q6dcDbOoPkhMgttOSCIMMY=
-go.elastic.co/apm v1.13.1 h1:ICIcUcQOImg/bve9mQVyLCvm1cSUZ1afdwK6ACnxczU=
-go.elastic.co/apm v1.13.1/go.mod h1:dylGv2HKR0tiCV+wliJz1KHtDyuD8SPe69oV7VyK6WY=
-go.elastic.co/apm/module/apmhttp v1.13.1 h1:g2id6+AY8NRSA6nzwPDSU1AmBiHyZeh/lJRBlXq2yfQ=
-go.elastic.co/apm/module/apmhttp v1.13.1/go.mod h1:PmSy4HY0asQzoFpl+gna9n+ebfI43fPvo21sd22gquE=
-go.elastic.co/apm/module/apmot v1.13.1 h1:4PCbjgVz0A/9a/wuiHu1en83TLgmBbK9fJwLgES8Rr8=
-go.elastic.co/apm/module/apmot v1.13.1/go.mod h1:NnG6U6ahaixUHpjQioL0QvVtOxWjVn8Z09qJHSCsmqU=
-go.elastic.co/fastjson v1.1.0 h1:3MrGBWWVIxe/xvsbpghtkFoPciPhOCmjsR/HfwEeQR4=
-go.elastic.co/fastjson v1.1.0/go.mod h1:boNGISWMjQsUPy/t6yqt2/1Wx4YNPSe+mZjlyw9vKKI=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
@@ -1963,30 +1857,26 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
 go.opentelemetry.io/collector/pdata v0.66.0 h1:UdE5U6MsDNzuiWaXdjGx2lC3ElVqWmN/hiUE8vyvSuM=
 go.opentelemetry.io/collector/pdata v0.66.0/go.mod h1:pqyaznLzk21m+1KL6fwOsRryRELL+zNM0qiVSn0MbVc=
-go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
-go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
-go.opentelemetry.io/otel/bridge/opentracing v1.19.0 h1:HCvsUi6uuhat/nAuxCl41A+OPxXXPxMNTRxKZx7hTW4=
-go.opentelemetry.io/otel/bridge/opentracing v1.19.0/go.mod h1:n46h+7L/lcSuHhpqJQiUdb4eux19NNxTuWJ/ZMnIQMg=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 h1:ZtfnDL+tUrs1F0Pzfwbg2d59Gru9NCH3bgSHBM6LDwU=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0/go.mod h1:hG4Fj/y8TR/tlEDREo8tWstl9fO9gcFkn4xrx0Io8xU=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0 h1:NmnYCiR0qNufkldjVvyQfZTHSdzeHoZ41zggMsdMcLM=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0/go.mod h1:UVAO61+umUsHLtYb8KXXRoHtxUkdOPkYidzW3gipRLQ=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 h1:wNMDy/LVGLj2h3p6zg4d0gypKfWKSWI14E1C4smOgl8=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0/go.mod h1:YfbDdXAAkemWJK3H/DshvlrxqFB2rtW4rY6ky/3x/H0=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
-go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
-go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
-go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
-go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
-go.opentelemetry.io/otel/sdk/metric v1.19.0 h1:EJoTO5qysMsYCa+w4UghwFV/ptQgqSL/8Ni+hx+8i1k=
-go.opentelemetry.io/otel/sdk/metric v1.19.0/go.mod h1:XjG0jQyFJrv2PbMvwND7LwCEhsJzCzV5210euduKcKY=
-go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
-go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
+go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
+go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 h1:jd0+5t/YynESZqsSyPz+7PAFdEop0dlN0+PkyHYo8oI=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0/go.mod h1:U707O40ee1FpQGyhvqnzmCJm1Wh6OX6GGBVn0E6Uyyk=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 h1:bflGWrfYyuulcdxf14V6n9+CoQcu5SAAdHmDPAJnlps=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0/go.mod h1:qcTO4xHAxZLaLxPd60TdE88rxtItPHgHWqOhOGRr0as=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I=
+go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
+go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
+go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
+go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
+go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
+go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
+go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
+go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
 go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
@@ -1994,14 +1884,13 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
 go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
 go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
 go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
 go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
-go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
-go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
 go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -2018,14 +1907,6 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
 go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
 go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
 go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
-go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA=
-go4.org/intern v0.0.0-20230525184215-6c62f75575cb h1:ae7kzL5Cfdmcecbh22ll7lYP3iuUdnfnhiPcSaDgH/8=
-go4.org/intern v0.0.0-20230525184215-6c62f75575cb/go.mod h1:Ycrt6raEcnF5FTsLiLKkhBTO6DPX3RCUCUVnks3gFJU=
-go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
-go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 h1:WJhcL4p+YeDxmZWg141nRm7XC8IDmhz7lk5GpadO1Sg=
-go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
-golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
-golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -2096,7 +1977,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu
 golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
@@ -2111,7 +1991,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
 golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -2143,6 +2022,7 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -2182,7 +2062,6 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
 golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
 golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -2200,8 +2079,8 @@ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
-golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
+golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
+golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -2214,7 +2093,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2258,7 +2136,6 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -2338,24 +2215,21 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
+golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
 golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
 golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2370,7 +2244,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2434,7 +2307,6 @@ golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjs
 golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
 golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -2457,15 +2329,12 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
 golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
 golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
-golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
 gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
 gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
 gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM=
@@ -2560,12 +2429,12 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D
 google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
 google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g=
-google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0=
-google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw=
-google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
+google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY=
+google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
+google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
+google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
 google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -2597,8 +2466,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K
 google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
 google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
 google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
-google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
+google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
+google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
 google.golang.org/grpc/examples v0.0.0-20201130180447-c456688b1860/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -2616,8 +2485,6 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
 google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
 google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/DataDog/dd-trace-go.v1 v1.56.1 h1:AUe/ZF7xm6vYnigPe+TY54DmfWYJxhMRaw/TfvrbzvE=
-gopkg.in/DataDog/dd-trace-go.v1 v1.56.1/go.mod h1:KDLJ3CWVOSuVVwu+0ZR5KZo2rP6c7YyBV3v387dIpUU=
 gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -2638,8 +2505,10 @@ gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
 gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
 gopkg.in/gorethink/gorethink.v3 v3.0.5 h1:e2Uc/Xe+hpcVQFsj6MuHlYog3r0JYpnTzwDj/y2O4MU=
 gopkg.in/gorethink/gorethink.v3 v3.0.5/go.mod h1:+3yIIHJUGMBK+wyPH+iN5TP+88ikFDfZdqTlK3Y9q8I=
-gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=
+gopkg.in/h2non/gentleman.v1 v1.0.4/go.mod h1:JYuHVdFzS4MKOXe0o+chKJ4hCe6tqKKw9XH9YP6WFrg=
 gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
+gopkg.in/h2non/gock.v1 v1.0.16 h1:F11k+OafeuFENsjei5t2vMTSTs9L62AdyTe4E1cgdG8=
+gopkg.in/h2non/gock.v1 v1.0.16/go.mod h1:XVuDAssexPLwgxCLMvDTWNU5eqklsydR6I5phZ9oPB8=
 gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
@@ -2689,10 +2558,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=
-howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
-inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a h1:1XCVEdxrvL6c0TGOhecLuB7U9zYNdxZEjvOqJreKZiM=
-inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a/go.mod h1:e83i32mAQOW1LAqEIweALsuK2Uw4mhQadA5r7b0Wobo=
 k8s.io/api v0.0.0-20180904230853-4e7be11eab3f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
 k8s.io/api v0.0.0-20191016110408-35e52d86657a/go.mod h1:/L5qH+AD540e7Cetbui1tuJeXdmNhO8jM6VkXeDdDhQ=
 k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
@@ -2756,8 +2621,8 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
 k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
 k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
 k8s.io/klog/v2 v2.10.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
-k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
-k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
+k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
 k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
 k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
 k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
diff --git a/integration/fixtures/tracing/otel-collector-config.yaml b/integration/fixtures/tracing/otel-collector-config.yaml
new file mode 100644
index 0000000000..4f51aec4b9
--- /dev/null
+++ b/integration/fixtures/tracing/otel-collector-config.yaml
@@ -0,0 +1,21 @@
+receivers:
+  otlp:
+    protocols:
+      grpc:
+      http:
+exporters:
+  otlp/tempo:
+    endpoint: http://tempo:4317
+    tls:
+      insecure: true
+service:
+  telemetry:
+    logs:
+      level: "error"
+  extensions: [ health_check ]
+  pipelines:
+    traces:
+      receivers: [otlp]
+      exporters: [otlp/tempo]
+extensions:
+  health_check:
\ No newline at end of file
diff --git a/integration/fixtures/tracing/simple-jaeger.toml b/integration/fixtures/tracing/simple-jaeger.toml
deleted file mode 100644
index bf02ced6af..0000000000
--- a/integration/fixtures/tracing/simple-jaeger.toml
+++ /dev/null
@@ -1,70 +0,0 @@
-[global]
-  checkNewVersion = false
-  sendAnonymousUsage = false
-
-[log]
-  level = "DEBUG"
-  noColor = true
-
-[api]
-  insecure = true
-
-[entryPoints]
-  [entryPoints.web]
-    address = ":8000"
-
-[tracing]
-  servicename = "tracing"
-  [tracing.jaeger]
-    samplingType = "const"
-    samplingParam = 1.0
-    samplingServerURL = "http://{{.IP}}:5778/sampling"
-    localAgentHostPort = "{{.IP}}:6831"
-    traceContextHeaderName = "{{.TraceContextHeaderName}}"
-
-[providers.file]
-  filename = "{{ .SelfFilename }}"
-
-## dynamic configuration ##
-
-[http.routers]
-  [http.routers.router1]
-    Service = "service1"
-    Middlewares = ["retry", "ratelimit-1"]
-    Rule = "Path(`/ratelimit`)"
-  [http.routers.router2]
-    Service = "service2"
-    Middlewares = ["retry"]
-    Rule = "Path(`/retry`)"
-  [http.routers.router3]
-    Service = "service3"
-    Middlewares = ["retry", "basic-auth"]
-    Rule = "Path(`/auth`)"
-
-[http.middlewares]
-  [http.middlewares.retry.retry]
-    attempts = 3
-  [http.middlewares.basic-auth.basicAuth]
-    users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"]
-  [http.middlewares.ratelimit-1.rateLimit]
-    average = 1
-    burst = 2
-
-[http.services]
-  [http.services.service1]
-    [http.services.service1.loadBalancer]
-      passHostHeader = true
-      [[http.services.service1.loadBalancer.servers]]
-        url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
-
-  [http.services.service2]
-    [http.services.service2.loadBalancer]
-      passHostHeader = true
-      [[http.services.service2.loadBalancer.servers]]
-        url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
-
-  [http.services.service3]
-    [http.services.service3.loadBalancer]
-      passHostHeader = true
-      [[http.services.service3.loadBalancer.servers]]
-        url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
diff --git a/integration/fixtures/tracing/simple-jaeger-collector.toml b/integration/fixtures/tracing/simple-opentelemetry.toml
similarity index 76%
rename from integration/fixtures/tracing/simple-jaeger-collector.toml
rename to integration/fixtures/tracing/simple-opentelemetry.toml
index e858e2a570..77d779800a 100644
--- a/integration/fixtures/tracing/simple-jaeger-collector.toml
+++ b/integration/fixtures/tracing/simple-opentelemetry.toml
@@ -15,12 +15,15 @@
 
 [tracing]
   servicename = "tracing"
-  [tracing.jaeger]
-    samplingType = "const"
-    samplingParam = 1.0
-    samplingServerURL = "http://{{.IP}}:5778/sampling"
-    [tracing.jaeger.collector]
-      endpoint = "http://{{.IP}}:14268/api/traces?format=jaeger.thrift"
+  sampleRate = 1.0
+{{if .IsHTTP}}
+  [tracing.otlp.http]
+    endpoint = "http://{{.IP}}:4318"
+{{else}}
+  [tracing.otlp.grpc]
+    endpoint = "{{.IP}}:4317"
+    insecure = true
+{{end}}
 
 [providers.file]
   filename = "{{ .SelfFilename }}"
@@ -28,6 +31,10 @@
 ## dynamic configuration ##
 
 [http.routers]
+  [http.routers.router0]
+    Service = "service0"
+    Middlewares = []
+    Rule = "Path(`/basic`)"
   [http.routers.router1]
     Service = "service1"
     Middlewares = ["retry", "ratelimit-1"]
@@ -50,8 +57,13 @@
     average = 1
     burst = 2
 
-
 [http.services]
+  [http.services.service0]
+    [http.services.service0.loadBalancer]
+      passHostHeader = true
+      [[http.services.service0.loadBalancer.servers]]
+        url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
+
   [http.services.service1]
     [http.services.service1.loadBalancer]
       passHostHeader = true
diff --git a/integration/fixtures/tracing/simple-zipkin.toml b/integration/fixtures/tracing/simple-zipkin.toml
deleted file mode 100644
index ef935fa28d..0000000000
--- a/integration/fixtures/tracing/simple-zipkin.toml
+++ /dev/null
@@ -1,66 +0,0 @@
-[global]
-  checkNewVersion = false
-  sendAnonymousUsage = false
-
-[log]
-  level = "DEBUG"
-  noColor = true
-
-[api]
-  insecure = true
-
-[entryPoints]
-  [entryPoints.web]
-    address = ":8000"
-
-[tracing]
-  servicename = "tracing"
-  [tracing.zipkin]
-    httpEndpoint = "http://{{.IP}}:9411/api/v2/spans"
-
-[providers.file]
-  filename = "{{ .SelfFilename }}"
-
-## dynamic configuration ##
-
-[http.routers]
-  [http.routers.router1]
-    service = "service1"
-    middlewares = ["retry", "ratelimit-1"]
-    rule = "Path(`/ratelimit`)"
-  [http.routers.router2]
-    service = "service2"
-    middlewares = ["retry"]
-    rule = "Path(`/retry`)"
-  [http.routers.router3]
-    service = "service3"
-    middlewares = ["retry", "basic-auth"]
-    rule = "Path(`/auth`)"
-
-[http.middlewares]
-  [http.middlewares.retry.retry]
-    attempts = 3
-  [http.middlewares.basic-auth.basicAuth]
-    users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"]
-  [http.middlewares.ratelimit-1.rateLimit]
-    average = 1
-    burst = 2
-
-[http.services]
-  [http.services.service1]
-    [http.services.service1.loadBalancer]
-      passHostHeader = true
-      [[http.services.service1.loadBalancer.servers]]
-        url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
-
-  [http.services.service2]
-    [http.services.service2.loadBalancer]
-      passHostHeader = true
-      [[http.services.service2.loadBalancer.servers]]
-        url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
-
-  [http.services.service3]
-    [http.services.service3.loadBalancer]
-      passHostHeader = true
-      [[http.services.service3.loadBalancer.servers]]
-        url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
diff --git a/integration/fixtures/tracing/tempo.yaml b/integration/fixtures/tracing/tempo.yaml
new file mode 100644
index 0000000000..0a115bfaa0
--- /dev/null
+++ b/integration/fixtures/tracing/tempo.yaml
@@ -0,0 +1,56 @@
+server:
+  http_listen_port: 3200
+
+query_frontend:
+  search:
+    duration_slo: 5s
+    throughput_bytes_slo: 1.073741824e+09
+  trace_by_id:
+    duration_slo: 5s
+
+distributor:
+  receivers:
+    otlp:
+      protocols:
+        grpc:
+
+ingester:
+  lifecycler:
+    address: 127.0.0.1
+    ring:
+      kvstore:
+        store: inmemory
+      replication_factor: 1
+    final_sleep: 0s
+  trace_idle_period: 1s
+  max_block_duration: 1m
+  complete_block_timeout: 5s
+  flush_check_period: 1s
+compactor:
+  compaction:
+    block_retention: 1h
+
+metrics_generator:
+  registry:
+    external_labels:
+      source: tempo
+      cluster: docker-compose
+  storage:
+    path: /tmp/tempo/generator/wal
+    remote_write:
+      - url: http://prometheus:9090/api/v1/write
+        send_exemplars: true
+
+storage:
+  trace:
+    backend: local                     # backend configuration to use
+    wal:
+      path: /tmp/tempo/wal             # where to store the wal locally
+    local:
+      path: /tmp/tempo/blocks
+
+overrides:
+  defaults:
+    metrics_generator:
+      processors: [service-graphs, span-metrics] # enables metrics generator
+
diff --git a/integration/resources/compose/tracing.yml b/integration/resources/compose/tracing.yml
index aeea9b3789..4cd02cec0b 100644
--- a/integration/resources/compose/tracing.yml
+++ b/integration/resources/compose/tracing.yml
@@ -1,16 +1,15 @@
 version: "3.8"
 services:
-  zipkin:
-    image: openzipkin/zipkin:2.16.2
-    environment:
-      STORAGE_TYPE: mem
-      JAVA_OPTS: -Dlogging.level.zipkin=DEBUG
-
-  jaeger:
-    image: jaegertracing/all-in-one:1.14
-    environment:
-      COLLECTOR_ZIPKIN_HTTP_PORT: 9411
-
+  tempo:
+    hostname: tempo
+    image: grafana/tempo:latest
+    command: [ "-config.file=/etc/tempo.yaml" ]
+    volumes:
+      - ./fixtures/tracing/tempo.yaml:/etc/tempo.yaml
+  otel-collector:
+    image: otel/opentelemetry-collector-contrib:0.89.0
+    volumes:
+      - ./fixtures/tracing/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
   whoami:
     image: traefik/whoami
 
diff --git a/pkg/config/dynamic/fixtures/sample.toml b/pkg/config/dynamic/fixtures/sample.toml
index 86242772cf..f6ab56cf15 100644
--- a/pkg/config/dynamic/fixtures/sample.toml
+++ b/pkg/config/dynamic/fixtures/sample.toml
@@ -122,41 +122,29 @@
 
 [tracing]
   serviceName = "foobar"
-  spanNameLimit = 42
-  [tracing.jaeger]
-    samplingServerURL = "foobar"
-    samplingType = "foobar"
-    samplingParam = 42.0
-    localAgentHostPort = "foobar"
-    gen128Bit = true
-    propagation = "foobar"
-    traceContextHeaderName = "foobar"
-  [tracing.zipkin]
-    httpEndpoint = "foobar"
-    sameSpan = true
-    id128Bit = true
-    debug = true
-    sampleRate = 42.0
-  [tracing.datadog]
-    localAgentHostPort = "foobar"
-    localAgentSocket = "foobar"
-    debug = true
-    prioritySampling = true
-    traceIDHeaderName = "foobar"
-    parentIDHeaderName = "foobar"
-    samplingPriorityHeaderName = "foobar"
-    bagagePrefixHeaderName = "foobar"
-  [tracing.instana]
-    localAgentHost = "foobar"
-    localAgentPort = 42
-    logLevel = "foobar"
-  [tracing.haystack]
-    localAgentHost = "foobar"
-    localAgentPort = 42
-    globalTag = "foobar"
-    traceIDHeaderName = "foobar"
-    parentIDHeaderName = "foobar"
-    spanIDHeaderName = "foobar"
+  sampleRate = 42
+  [tracing.headers]
+    header1 = "foobar"
+    header2 = "foobar"
+  [tracing.globalAttributes]
+    attr1 = "foobar"
+    attr2 = "foobar"
+  [tracing.otlp.grpc]
+    endpoint = "foobar"
+    insecure = true
+    [tracing.otlp.grpc.tls]
+      ca = "foobar"
+      cert = "foobar"
+      key = "foobar"
+      insecureSkipVerify = true
+  [tracing.otlp.http]
+    endpoint = "foobar"
+    insecure = true
+    [tracing.otlp.http.tls]
+      ca = "foobar"
+      cert = "foobar"
+      key = "foobar"
+      insecureSkipVerify = true
 
 [hostResolver]
   cnameFlattening = true
diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go
index 01a28d7c01..1c141a5a83 100644
--- a/pkg/config/static/static_config.go
+++ b/pkg/config/static/static_config.go
@@ -1,6 +1,7 @@
 package static
 
 import (
+	"errors"
 	"fmt"
 	"strings"
 	"time"
@@ -27,13 +28,7 @@ import (
 	"github.com/traefik/traefik/v3/pkg/provider/nomad"
 	"github.com/traefik/traefik/v3/pkg/provider/rest"
 	"github.com/traefik/traefik/v3/pkg/tls"
-	"github.com/traefik/traefik/v3/pkg/tracing/datadog"
-	"github.com/traefik/traefik/v3/pkg/tracing/elastic"
-	"github.com/traefik/traefik/v3/pkg/tracing/haystack"
-	"github.com/traefik/traefik/v3/pkg/tracing/instana"
-	"github.com/traefik/traefik/v3/pkg/tracing/jaeger"
 	"github.com/traefik/traefik/v3/pkg/tracing/opentelemetry"
-	"github.com/traefik/traefik/v3/pkg/tracing/zipkin"
 	"github.com/traefik/traefik/v3/pkg/types"
 )
 
@@ -187,21 +182,18 @@ func (a *LifeCycle) SetDefaults() {
 
 // Tracing holds the tracing configuration.
 type Tracing struct {
-	ServiceName   string                `description:"Set the name for this service." json:"serviceName,omitempty" toml:"serviceName,omitempty" yaml:"serviceName,omitempty" export:"true"`
-	SpanNameLimit int                   `description:"Set the maximum character limit for Span names (default 0 = no limit)." json:"spanNameLimit,omitempty" toml:"spanNameLimit,omitempty" yaml:"spanNameLimit,omitempty" export:"true"`
-	Jaeger        *jaeger.Config        `description:"Settings for Jaeger." json:"jaeger,omitempty" toml:"jaeger,omitempty" yaml:"jaeger,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
-	Zipkin        *zipkin.Config        `description:"Settings for Zipkin." json:"zipkin,omitempty" toml:"zipkin,omitempty" yaml:"zipkin,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
-	Datadog       *datadog.Config       `description:"Settings for Datadog." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
-	Instana       *instana.Config       `description:"Settings for Instana." json:"instana,omitempty" toml:"instana,omitempty" yaml:"instana,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
-	Haystack      *haystack.Config      `description:"Settings for Haystack." json:"haystack,omitempty" toml:"haystack,omitempty" yaml:"haystack,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
-	Elastic       *elastic.Config       `description:"Settings for Elastic." json:"elastic,omitempty" toml:"elastic,omitempty" yaml:"elastic,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
-	OpenTelemetry *opentelemetry.Config `description:"Settings for OpenTelemetry." json:"openTelemetry,omitempty" toml:"openTelemetry,omitempty" yaml:"openTelemetry,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
+	ServiceName      string            `description:"Set the name for this service." json:"serviceName,omitempty" toml:"serviceName,omitempty" yaml:"serviceName,omitempty" export:"true"`
+	Headers          map[string]string `description:"Defines additional headers to be sent with the payloads." json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"`
+	GlobalAttributes map[string]string `description:"Defines additional attributes (key:value) on all spans." json:"globalAttributes,omitempty" toml:"globalAttributes,omitempty" yaml:"globalAttributes,omitempty" export:"true"`
+	SampleRate       float64           `description:"Sets the rate between 0.0 and 1.0 of requests to trace." json:"sampleRate,omitempty" toml:"sampleRate,omitempty" yaml:"sampleRate,omitempty" export:"true"`
+
+	OTLP *opentelemetry.Config `description:"Settings for OpenTelemetry." json:"otlp,omitempty" toml:"otlp,omitempty" yaml:"otlp,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
 }
 
 // SetDefaults sets the default values.
 func (t *Tracing) SetDefaults() {
 	t.ServiceName = "traefik"
-	t.SpanNameLimit = 0
+	t.SampleRate = 1.0
 }
 
 // Providers contains providers configuration.
@@ -326,6 +318,20 @@ func (c *Configuration) ValidateConfiguration() error {
 		acmeEmail = resolver.ACME.Email
 	}
 
+	if c.Tracing != nil && c.Tracing.OTLP != nil {
+		if c.Tracing.OTLP.HTTP == nil && c.Tracing.OTLP.GRPC == nil {
+			return errors.New("tracing OTLP: at least one of HTTP and gRPC options should be defined")
+		}
+
+		if c.Tracing.OTLP.HTTP != nil && c.Tracing.OTLP.GRPC != nil {
+			return errors.New("tracing OTLP: HTTP and gRPC options are mutually exclusive")
+		}
+
+		if c.Tracing.OTLP.GRPC != nil && c.Tracing.OTLP.GRPC.TLS != nil && c.Tracing.OTLP.GRPC.Insecure {
+			return errors.New("tracing OTLP GRPC: TLS and Insecure options are mutually exclusive")
+		}
+	}
+
 	return nil
 }
 
diff --git a/pkg/logs/haystack.go b/pkg/logs/haystack.go
deleted file mode 100644
index 6f3db7361b..0000000000
--- a/pkg/logs/haystack.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package logs
-
-import (
-	"github.com/rs/zerolog"
-)
-
-type HaystackLogger struct {
-	logger zerolog.Logger
-}
-
-func NewHaystackLogger(logger zerolog.Logger) *HaystackLogger {
-	return &HaystackLogger{logger: logger}
-}
-
-// Error prints the error message.
-func (l HaystackLogger) Error(format string, v ...interface{}) {
-	l.logger.Error().CallerSkipFrame(1).Msgf(format, v...)
-}
-
-// Info prints the info message.
-func (l HaystackLogger) Info(format string, v ...interface{}) {
-	l.logger.Info().CallerSkipFrame(1).Msgf(format, v...)
-}
-
-// Debug prints the info message.
-func (l HaystackLogger) Debug(format string, v ...interface{}) {
-	l.logger.Debug().CallerSkipFrame(1).Msgf(format, v...)
-}
diff --git a/pkg/logs/jaeger.go b/pkg/logs/jaeger.go
deleted file mode 100644
index 2faedc2fb2..0000000000
--- a/pkg/logs/jaeger.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package logs
-
-import (
-	"github.com/rs/zerolog"
-)
-
-// JaegerLogger is an implementation of the Logger interface that delegates to traefik log.
-type JaegerLogger struct {
-	logger zerolog.Logger
-}
-
-func NewJaegerLogger(logger zerolog.Logger) *JaegerLogger {
-	return &JaegerLogger{logger: logger}
-}
-
-func (l *JaegerLogger) Error(msg string) {
-	l.logger.Error().CallerSkipFrame(1).Msg(msg)
-}
-
-// Infof logs a message at debug priority.
-func (l *JaegerLogger) Infof(msg string, args ...interface{}) {
-	l.logger.Debug().CallerSkipFrame(1).Msgf(msg, args...)
-}
diff --git a/pkg/metrics/opentelemetry.go b/pkg/metrics/opentelemetry.go
index a6c0c43e09..e866ff5e02 100644
--- a/pkg/metrics/opentelemetry.go
+++ b/pkg/metrics/opentelemetry.go
@@ -19,7 +19,7 @@ import (
 	"go.opentelemetry.io/otel/metric"
 	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
 	"go.opentelemetry.io/otel/sdk/resource"
-	semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
+	semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/encoding/gzip"
 )
diff --git a/pkg/middlewares/addprefix/add_prefix.go b/pkg/middlewares/addprefix/add_prefix.go
index 4363da9b9a..e91facaf93 100644
--- a/pkg/middlewares/addprefix/add_prefix.go
+++ b/pkg/middlewares/addprefix/add_prefix.go
@@ -5,10 +5,9 @@ import (
 	"fmt"
 	"net/http"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -40,8 +39,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.AddPrefix, name
 	return result, nil
 }
 
-func (a *addPrefix) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return a.name, tracing.SpanKindNoneEnum
+func (a *addPrefix) GetTracingInformation() (string, string, trace.SpanKind) {
+	return a.name, typeName, trace.SpanKindInternal
 }
 
 func (a *addPrefix) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/auth/basic_auth.go b/pkg/middlewares/auth/basic_auth.go
index 70e25d3a12..5a3caa26d0 100644
--- a/pkg/middlewares/auth/basic_auth.go
+++ b/pkg/middlewares/auth/basic_auth.go
@@ -8,15 +8,15 @@ import (
 	"strings"
 
 	goauth "github.com/abbot/go-http-auth"
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
-	basicTypeName = "BasicAuth"
+	typeNameBasic = "BasicAuth"
 )
 
 type basicAuth struct {
@@ -30,7 +30,7 @@ type basicAuth struct {
 
 // NewBasic creates a basicAuth middleware.
 func NewBasic(ctx context.Context, next http.Handler, authConfig dynamic.BasicAuth, name string) (http.Handler, error) {
-	middlewares.GetLogger(ctx, name, basicTypeName).Debug().Msg("Creating middleware")
+	middlewares.GetLogger(ctx, name, typeNameBasic).Debug().Msg("Creating middleware")
 
 	users, err := getUsers(authConfig.UsersFile, authConfig.Users, basicUserParser)
 	if err != nil {
@@ -55,12 +55,12 @@ func NewBasic(ctx context.Context, next http.Handler, authConfig dynamic.BasicAu
 	return ba, nil
 }
 
-func (b *basicAuth) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return b.name, tracing.SpanKindNoneEnum
+func (b *basicAuth) GetTracingInformation() (string, string, trace.SpanKind) {
+	return b.name, typeNameBasic, trace.SpanKindInternal
 }
 
 func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	logger := middlewares.GetLogger(req.Context(), b.name, basicTypeName)
+	logger := middlewares.GetLogger(req.Context(), b.name, typeNameBasic)
 
 	user, password, ok := req.BasicAuth()
 	if ok {
@@ -77,7 +77,7 @@ func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 
 	if !ok {
 		logger.Debug().Msg("Authentication failed")
-		tracing.SetErrorWithEvent(req, "Authentication failed")
+		tracing.SetStatusErrorf(req.Context(), "Authentication failed")
 
 		b.auth.RequireAuth(rw, req)
 		return
diff --git a/pkg/middlewares/auth/digest_auth.go b/pkg/middlewares/auth/digest_auth.go
index ea772aeb5a..e02bc58831 100644
--- a/pkg/middlewares/auth/digest_auth.go
+++ b/pkg/middlewares/auth/digest_auth.go
@@ -8,15 +8,15 @@ import (
 	"strings"
 
 	goauth "github.com/abbot/go-http-auth"
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
-	digestTypeName = "digestAuth"
+	typeNameDigest = "digestAuth"
 )
 
 type digestAuth struct {
@@ -30,7 +30,7 @@ type digestAuth struct {
 
 // NewDigest creates a digest auth middleware.
 func NewDigest(ctx context.Context, next http.Handler, authConfig dynamic.DigestAuth, name string) (http.Handler, error) {
-	middlewares.GetLogger(ctx, name, digestTypeName).Debug().Msg("Creating middleware")
+	middlewares.GetLogger(ctx, name, typeNameDigest).Debug().Msg("Creating middleware")
 
 	users, err := getUsers(authConfig.UsersFile, authConfig.Users, digestUserParser)
 	if err != nil {
@@ -54,12 +54,12 @@ func NewDigest(ctx context.Context, next http.Handler, authConfig dynamic.Digest
 	return da, nil
 }
 
-func (d *digestAuth) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return d.name, tracing.SpanKindNoneEnum
+func (d *digestAuth) GetTracingInformation() (string, string, trace.SpanKind) {
+	return d.name, typeNameDigest, trace.SpanKindInternal
 }
 
 func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	logger := middlewares.GetLogger(req.Context(), d.name, digestTypeName)
+	logger := middlewares.GetLogger(req.Context(), d.name, typeNameDigest)
 
 	username, authinfo := d.auth.CheckAuth(req)
 	if username == "" {
@@ -78,13 +78,13 @@ func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 
 		if authinfo != nil && *authinfo == "stale" {
 			logger.Debug().Msg("Digest authentication failed, possibly because out of order requests")
-			tracing.SetErrorWithEvent(req, "Digest authentication failed, possibly because out of order requests")
+			tracing.SetStatusErrorf(req.Context(), "Digest authentication failed, possibly because out of order requests")
 			d.auth.RequireAuthStale(rw, req)
 			return
 		}
 
 		logger.Debug().Msg("Digest authentication failed")
-		tracing.SetErrorWithEvent(req, "Digest authentication failed")
+		tracing.SetStatusErrorf(req.Context(), "Digest authentication failed")
 		d.auth.RequireAuth(rw, req)
 		return
 	}
diff --git a/pkg/middlewares/auth/forward.go b/pkg/middlewares/auth/forward.go
index b19e37a6fa..f931374697 100644
--- a/pkg/middlewares/auth/forward.go
+++ b/pkg/middlewares/auth/forward.go
@@ -11,21 +11,22 @@ import (
 	"strings"
 	"time"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/middlewares/connectionheader"
 	"github.com/traefik/traefik/v3/pkg/tracing"
 	"github.com/vulcand/oxy/v2/forward"
 	"github.com/vulcand/oxy/v2/utils"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
-	xForwardedURI     = "X-Forwarded-Uri"
-	xForwardedMethod  = "X-Forwarded-Method"
-	forwardedTypeName = "ForwardedAuthType"
+	xForwardedURI    = "X-Forwarded-Uri"
+	xForwardedMethod = "X-Forwarded-Method"
 )
 
+const typeNameForward = "ForwardAuth"
+
 // hopHeaders Hop-by-hop headers to be removed in the authentication request.
 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
 // Proxy-Authorization header is forwarded to the authentication server (see https://tools.ietf.org/html/rfc7235#section-4.4).
@@ -51,7 +52,7 @@ type forwardAuth struct {
 
 // NewForward creates a forward auth middleware.
 func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAuth, name string) (http.Handler, error) {
-	middlewares.GetLogger(ctx, name, forwardedTypeName).Debug().Msg("Creating middleware")
+	middlewares.GetLogger(ctx, name, typeNameForward).Debug().Msg("Creating middleware")
 
 	fa := &forwardAuth{
 		address:             config.Address,
@@ -89,30 +90,38 @@ func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAu
 		fa.authResponseHeadersRegex = re
 	}
 
-	return connectionheader.Remover(fa), nil
+	return fa, nil
 }
 
-func (fa *forwardAuth) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return fa.name, ext.SpanKindRPCClientEnum
+func (fa *forwardAuth) GetTracingInformation() (string, string, trace.SpanKind) {
+	return fa.name, typeNameForward, trace.SpanKindInternal
 }
 
 func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	logger := middlewares.GetLogger(req.Context(), fa.name, forwardedTypeName)
+	logger := middlewares.GetLogger(req.Context(), fa.name, typeNameForward)
+
+	req = connectionheader.Remove(req)
 
-	forwardReq, err := http.NewRequest(http.MethodGet, fa.address, nil)
-	tracing.LogRequest(tracing.GetSpan(req), forwardReq)
+	forwardReq, err := http.NewRequestWithContext(req.Context(), http.MethodGet, fa.address, nil)
 	if err != nil {
 		logMessage := fmt.Sprintf("Error calling %s. Cause %s", fa.address, err)
 		logger.Debug().Msg(logMessage)
-		tracing.SetErrorWithEvent(req, logMessage)
-
+		tracing.SetStatusErrorf(req.Context(), logMessage)
 		rw.WriteHeader(http.StatusInternalServerError)
 		return
 	}
 
-	// Ensure tracing headers are in the request before we copy the headers to the
-	// forwardReq.
-	tracing.InjectRequestHeaders(req)
+	var forwardSpan trace.Span
+	if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
+		var tracingCtx context.Context
+		tracingCtx, forwardSpan = tracer.Start(req.Context(), "AuthRequest", trace.WithSpanKind(trace.SpanKindClient))
+		defer forwardSpan.End()
+
+		forwardReq = forwardReq.WithContext(tracingCtx)
+
+		tracing.InjectContextIntoCarrier(forwardReq)
+		tracing.LogClientRequest(forwardSpan, forwardReq)
+	}
 
 	writeHeader(req, forwardReq, fa.trustForwardHeader, fa.authRequestHeaders)
 
@@ -120,7 +129,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	if forwardErr != nil {
 		logMessage := fmt.Sprintf("Error calling %s. Cause: %s", fa.address, forwardErr)
 		logger.Debug().Msg(logMessage)
-		tracing.SetErrorWithEvent(req, logMessage)
+		tracing.SetStatusErrorf(forwardReq.Context(), logMessage)
 
 		rw.WriteHeader(http.StatusInternalServerError)
 		return
@@ -131,12 +140,18 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	if readError != nil {
 		logMessage := fmt.Sprintf("Error reading body %s. Cause: %s", fa.address, readError)
 		logger.Debug().Msg(logMessage)
-		tracing.SetErrorWithEvent(req, logMessage)
+		tracing.SetStatusErrorf(forwardReq.Context(), logMessage)
 
 		rw.WriteHeader(http.StatusInternalServerError)
 		return
 	}
 
+	// Ending the forward request span as soon as the response is handled.
+	// If any errors happen earlier, this span will be close by the defer instruction.
+	if forwardSpan != nil {
+		forwardSpan.End()
+	}
+
 	// Pass the forward response's body and selected headers if it
 	// didn't return a response within the range of [200, 300).
 	if forwardResponse.StatusCode < http.StatusOK || forwardResponse.StatusCode >= http.StatusMultipleChoices {
@@ -152,7 +167,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 			if !errors.Is(err, http.ErrNoLocation) {
 				logMessage := fmt.Sprintf("Error reading response location header %s. Cause: %s", fa.address, err)
 				logger.Debug().Msg(logMessage)
-				tracing.SetErrorWithEvent(req, logMessage)
+				tracing.SetStatusErrorf(forwardReq.Context(), logMessage)
 
 				rw.WriteHeader(http.StatusInternalServerError)
 				return
@@ -162,7 +177,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 			rw.Header().Set("Location", redirectURL.String())
 		}
 
-		tracing.LogResponseCode(tracing.GetSpan(req), forwardResponse.StatusCode)
+		tracing.LogResponseCode(forwardSpan, forwardResponse.StatusCode, trace.SpanKindClient)
 		rw.WriteHeader(forwardResponse.StatusCode)
 
 		if _, err = rw.Write(body); err != nil {
@@ -193,6 +208,8 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 		}
 	}
 
+	tracing.LogResponseCode(forwardSpan, forwardResponse.StatusCode, trace.SpanKindClient)
+
 	req.RequestURI = req.URL.RequestURI()
 	fa.next.ServeHTTP(rw, req)
 }
diff --git a/pkg/middlewares/buffering/buffering.go b/pkg/middlewares/buffering/buffering.go
index 6aa2ed562d..ec9100a98f 100644
--- a/pkg/middlewares/buffering/buffering.go
+++ b/pkg/middlewares/buffering/buffering.go
@@ -4,13 +4,12 @@ import (
 	"context"
 	"net/http"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/rs/zerolog"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/logs"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
-	"github.com/traefik/traefik/v3/pkg/tracing"
 	oxybuffer "github.com/vulcand/oxy/v2/buffer"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -49,8 +48,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.Buffering, name
 	}, nil
 }
 
-func (b *buffer) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return b.name, tracing.SpanKindNoneEnum
+func (b *buffer) GetTracingInformation() (string, string, trace.SpanKind) {
+	return b.name, typeName, trace.SpanKindInternal
 }
 
 func (b *buffer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/circuitbreaker/circuit_breaker.go b/pkg/middlewares/circuitbreaker/circuit_breaker.go
index 8445b45b81..3fa06ba234 100644
--- a/pkg/middlewares/circuitbreaker/circuit_breaker.go
+++ b/pkg/middlewares/circuitbreaker/circuit_breaker.go
@@ -5,7 +5,6 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/rs/zerolog"
 	"github.com/rs/zerolog/log"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
@@ -13,6 +12,7 @@ import (
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/tracing"
 	"github.com/vulcand/oxy/v2/cbreaker"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const typeName = "CircuitBreaker"
@@ -32,7 +32,7 @@ func New(ctx context.Context, next http.Handler, confCircuitBreaker dynamic.Circ
 
 	cbOpts := []cbreaker.Option{
 		cbreaker.Fallback(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
-			tracing.SetErrorWithEvent(req, "blocked by circuit-breaker (%q)", expression)
+			tracing.SetStatusErrorf(req.Context(), "blocked by circuit-breaker (%q)", expression)
 			rw.WriteHeader(http.StatusServiceUnavailable)
 
 			if _, err := rw.Write([]byte(http.StatusText(http.StatusServiceUnavailable))); err != nil {
@@ -66,8 +66,8 @@ func New(ctx context.Context, next http.Handler, confCircuitBreaker dynamic.Circ
 	}, nil
 }
 
-func (c *circuitBreaker) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return c.name, tracing.SpanKindNoneEnum
+func (c *circuitBreaker) GetTracingInformation() (string, string, trace.SpanKind) {
+	return c.name, typeName, trace.SpanKindInternal
 }
 
 func (c *circuitBreaker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/compress/compress.go b/pkg/middlewares/compress/compress.go
index adc346237c..b7ae85b4d5 100644
--- a/pkg/middlewares/compress/compress.go
+++ b/pkg/middlewares/compress/compress.go
@@ -9,11 +9,10 @@ import (
 	"strings"
 
 	"github.com/klauspost/compress/gzhttp"
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/middlewares/compress/brotli"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const typeName = "Compress"
@@ -114,8 +113,8 @@ func (c *compress) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	c.next.ServeHTTP(rw, req)
 }
 
-func (c *compress) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return c.name, tracing.SpanKindNoneEnum
+func (c *compress) GetTracingInformation() (string, string, trace.SpanKind) {
+	return c.name, typeName, trace.SpanKindInternal
 }
 
 func (c *compress) newGzipHandler() (http.Handler, error) {
diff --git a/pkg/middlewares/connectionheader/connectionheader.go b/pkg/middlewares/connectionheader/connectionheader.go
index b7a64910a4..12a994f17a 100644
--- a/pkg/middlewares/connectionheader/connectionheader.go
+++ b/pkg/middlewares/connectionheader/connectionheader.go
@@ -17,22 +17,27 @@ const (
 // See RFC 7230, section 6.1.
 func Remover(next http.Handler) http.HandlerFunc {
 	return func(rw http.ResponseWriter, req *http.Request) {
-		var reqUpType string
-		if httpguts.HeaderValuesContainsToken(req.Header[connectionHeader], upgradeHeader) {
-			reqUpType = req.Header.Get(upgradeHeader)
-		}
+		next.ServeHTTP(rw, Remove(req))
+	}
+}
 
-		removeConnectionHeaders(req.Header)
+// Remove removes hop-by-hop header on the request.
+func Remove(req *http.Request) *http.Request {
+	var reqUpType string
+	if httpguts.HeaderValuesContainsToken(req.Header[connectionHeader], upgradeHeader) {
+		reqUpType = req.Header.Get(upgradeHeader)
+	}
 
-		if reqUpType != "" {
-			req.Header.Set(connectionHeader, upgradeHeader)
-			req.Header.Set(upgradeHeader, reqUpType)
-		} else {
-			req.Header.Del(connectionHeader)
-		}
+	removeConnectionHeaders(req.Header)
 
-		next.ServeHTTP(rw, req)
+	if reqUpType != "" {
+		req.Header.Set(connectionHeader, upgradeHeader)
+		req.Header.Set(upgradeHeader, reqUpType)
+	} else {
+		req.Header.Del(connectionHeader)
 	}
+
+	return req
 }
 
 func removeConnectionHeaders(h http.Header) {
diff --git a/pkg/middlewares/customerrors/custom_errors.go b/pkg/middlewares/customerrors/custom_errors.go
index 2d71e751d4..dd1f77e333 100644
--- a/pkg/middlewares/customerrors/custom_errors.go
+++ b/pkg/middlewares/customerrors/custom_errors.go
@@ -10,12 +10,12 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/tracing"
 	"github.com/traefik/traefik/v3/pkg/types"
 	"github.com/vulcand/oxy/v2/utils"
+	"go.opentelemetry.io/otel/trace"
 )
 
 // Compile time validation that the response recorder implements http interfaces correctly.
@@ -24,7 +24,7 @@ var (
 	_ middlewares.Stateful = &codeCatcher{}
 )
 
-const typeName = "customError"
+const typeName = "CustomError"
 
 type serviceBuilder interface {
 	BuildHTTP(ctx context.Context, serviceName string) (http.Handler, error)
@@ -62,8 +62,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.ErrorPage, servi
 	}, nil
 }
 
-func (c *customErrors) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return c.name, tracing.SpanKindNoneEnum
+func (c *customErrors) GetTracingInformation() (string, string, trace.SpanKind) {
+	return c.name, typeName, trace.SpanKindInternal
 }
 
 func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
@@ -71,7 +71,7 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 
 	if c.backendHandler == nil {
 		logger.Error().Msg("Error pages: no backend handler.")
-		tracing.SetErrorWithEvent(req, "Error pages: no backend handler.")
+		tracing.SetStatusErrorf(req.Context(), "Error pages: no backend handler.")
 		c.next.ServeHTTP(rw, req)
 		return
 	}
@@ -96,12 +96,12 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	pageReq, err := newRequest("http://" + req.Host + query)
 	if err != nil {
 		logger.Error().Err(err).Send()
+		tracing.SetStatusErrorf(req.Context(), err.Error())
 		http.Error(rw, http.StatusText(code), code)
 		return
 	}
 
 	utils.CopyHeaders(pageReq.Header, req.Header)
-
 	c.backendHandler.ServeHTTP(newCodeModifier(rw, code),
 		pageReq.WithContext(req.Context()))
 }
diff --git a/pkg/middlewares/grpcweb/grpcweb.go b/pkg/middlewares/grpcweb/grpcweb.go
index 18fe108eb7..1d32b52730 100644
--- a/pkg/middlewares/grpcweb/grpcweb.go
+++ b/pkg/middlewares/grpcweb/grpcweb.go
@@ -9,7 +9,7 @@ import (
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 )
 
-const typeName = "grpc-web"
+const typeName = "GRPCWeb"
 
 // New builds a new gRPC web request converter.
 func New(ctx context.Context, next http.Handler, config dynamic.GrpcWeb, name string) http.Handler {
diff --git a/pkg/middlewares/headers/headers.go b/pkg/middlewares/headers/headers.go
index 1210f6711e..e393aa1a65 100644
--- a/pkg/middlewares/headers/headers.go
+++ b/pkg/middlewares/headers/headers.go
@@ -6,11 +6,10 @@ import (
 	"errors"
 	"net/http"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/middlewares/connectionheader"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -61,8 +60,8 @@ func New(ctx context.Context, next http.Handler, cfg dynamic.Headers, name strin
 	}, nil
 }
 
-func (h *headers) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return h.name, tracing.SpanKindNoneEnum
+func (h *headers) GetTracingInformation() (string, string, trace.SpanKind) {
+	return h.name, typeName, trace.SpanKindInternal
 }
 
 func (h *headers) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/inflightreq/inflight_req.go b/pkg/middlewares/inflightreq/inflight_req.go
index a6fcdf101a..c051936071 100644
--- a/pkg/middlewares/inflightreq/inflight_req.go
+++ b/pkg/middlewares/inflightreq/inflight_req.go
@@ -5,13 +5,12 @@ import (
 	"fmt"
 	"net/http"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/rs/zerolog"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/logs"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
-	"github.com/traefik/traefik/v3/pkg/tracing"
 	"github.com/vulcand/oxy/v2/connlimit"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -54,8 +53,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.InFlightReq, nam
 	return &inFlightReq{handler: handler, name: name}, nil
 }
 
-func (i *inFlightReq) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return i.name, tracing.SpanKindNoneEnum
+func (i *inFlightReq) GetTracingInformation() (string, string, trace.SpanKind) {
+	return i.name, typeName, trace.SpanKindInternal
 }
 
 func (i *inFlightReq) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/ipallowlist/ip_allowlist.go b/pkg/middlewares/ipallowlist/ip_allowlist.go
index e888d5d92f..ddd7bfe47a 100644
--- a/pkg/middlewares/ipallowlist/ip_allowlist.go
+++ b/pkg/middlewares/ipallowlist/ip_allowlist.go
@@ -6,12 +6,12 @@ import (
 	"fmt"
 	"net/http"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/rs/zerolog/log"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/ip"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -55,8 +55,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.IPAllowList, nam
 	}, nil
 }
 
-func (al *ipAllowLister) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return al.name, tracing.SpanKindNoneEnum
+func (al *ipAllowLister) GetTracingInformation() (string, string, trace.SpanKind) {
+	return al.name, typeName, trace.SpanKindInternal
 }
 
 func (al *ipAllowLister) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
@@ -68,7 +68,7 @@ func (al *ipAllowLister) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	if err != nil {
 		msg := fmt.Sprintf("Rejecting IP %s: %v", clientIP, err)
 		logger.Debug().Msg(msg)
-		tracing.SetErrorWithEvent(req, msg)
+		tracing.SetStatusErrorf(req.Context(), msg)
 		reject(ctx, rw)
 		return
 	}
diff --git a/pkg/middlewares/metrics/metrics.go b/pkg/middlewares/metrics/metrics.go
index 64a09db171..a61da207ed 100644
--- a/pkg/middlewares/metrics/metrics.go
+++ b/pkg/middlewares/metrics/metrics.go
@@ -16,6 +16,8 @@ import (
 	"github.com/traefik/traefik/v3/pkg/middlewares/capture"
 	"github.com/traefik/traefik/v3/pkg/middlewares/retry"
 	traefiktls "github.com/traefik/traefik/v3/pkg/tls"
+	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 	"google.golang.org/grpc/codes"
 )
 
@@ -39,6 +41,7 @@ type metricsMiddleware struct {
 	reqsBytesCounter     gokitmetrics.Counter
 	respsBytesCounter    gokitmetrics.Counter
 	baseLabels           []string
+	name                 string
 }
 
 // NewEntryPointMiddleware creates a new metrics middleware for an Entrypoint.
@@ -53,6 +56,7 @@ func NewEntryPointMiddleware(ctx context.Context, next http.Handler, registry me
 		reqsBytesCounter:     registry.EntryPointReqsBytesCounter(),
 		respsBytesCounter:    registry.EntryPointRespsBytesCounter(),
 		baseLabels:           []string{"entrypoint", entryPointName},
+		name:                 nameEntrypoint,
 	}
 }
 
@@ -68,6 +72,7 @@ func NewRouterMiddleware(ctx context.Context, next http.Handler, registry metric
 		reqsBytesCounter:     registry.RouterReqsBytesCounter(),
 		respsBytesCounter:    registry.RouterRespsBytesCounter(),
 		baseLabels:           []string{"router", routerName, "service", serviceName},
+		name:                 nameRouter,
 	}
 }
 
@@ -83,6 +88,7 @@ func NewServiceMiddleware(ctx context.Context, next http.Handler, registry metri
 		reqsBytesCounter:     registry.ServiceReqsBytesCounter(),
 		respsBytesCounter:    registry.ServiceRespsBytesCounter(),
 		baseLabels:           []string{"service", serviceName},
+		name:                 nameService,
 	}
 }
 
@@ -100,6 +106,17 @@ func WrapRouterHandler(ctx context.Context, registry metrics.Registry, routerNam
 	}
 }
 
+// WrapServiceHandler Wraps metrics service to alice.Constructor.
+func WrapServiceHandler(ctx context.Context, registry metrics.Registry, serviceName string) alice.Constructor {
+	return func(next http.Handler) (http.Handler, error) {
+		return NewServiceMiddleware(ctx, next, registry, serviceName), nil
+	}
+}
+
+func (m *metricsMiddleware) GetTracingInformation() (string, string, trace.SpanKind) {
+	return m.name, typeName, trace.SpanKindInternal
+}
+
 func (m *metricsMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	proto := getRequestProtocol(req)
 
@@ -127,6 +144,7 @@ func (m *metricsMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request)
 		}
 		logger := with.Logger()
 		logger.Error().Err(err).Msg("Could not get Capture")
+		tracing.SetStatusErrorf(req.Context(), "Could not get Capture")
 		return
 	}
 
diff --git a/pkg/middlewares/passtlsclientcert/pass_tls_client_cert.go b/pkg/middlewares/passtlsclientcert/pass_tls_client_cert.go
index 94367ce289..77f1cd09d8 100644
--- a/pkg/middlewares/passtlsclientcert/pass_tls_client_cert.go
+++ b/pkg/middlewares/passtlsclientcert/pass_tls_client_cert.go
@@ -11,11 +11,10 @@ import (
 	"net/url"
 	"strings"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/rs/zerolog/log"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const typeName = "PassClientTLSCert"
@@ -140,8 +139,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.PassTLSClientCer
 	}, nil
 }
 
-func (p *passTLSClientCert) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return p.name, tracing.SpanKindNoneEnum
+func (p *passTLSClientCert) GetTracingInformation() (string, string, trace.SpanKind) {
+	return p.name, typeName, trace.SpanKindInternal
 }
 
 func (p *passTLSClientCert) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/ratelimiter/rate_limiter.go b/pkg/middlewares/ratelimiter/rate_limiter.go
index 1c3582c4e4..fcede7dce7 100644
--- a/pkg/middlewares/ratelimiter/rate_limiter.go
+++ b/pkg/middlewares/ratelimiter/rate_limiter.go
@@ -9,17 +9,17 @@ import (
 	"time"
 
 	"github.com/mailgun/ttlmap"
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/rs/zerolog/log"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/tracing"
 	"github.com/vulcand/oxy/v2/utils"
+	"go.opentelemetry.io/otel/trace"
 	"golang.org/x/time/rate"
 )
 
 const (
-	typeName   = "RateLimiterType"
+	typeName   = "RateLimiter"
 	maxSources = 65536
 )
 
@@ -122,8 +122,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.RateLimit, name
 	}, nil
 }
 
-func (rl *rateLimiter) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return rl.name, tracing.SpanKindNoneEnum
+func (rl *rateLimiter) GetTracingInformation() (string, string, trace.SpanKind) {
+	return rl.name, typeName, trace.SpanKindInternal
 }
 
 func (rl *rateLimiter) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
@@ -153,12 +153,14 @@ func (rl *rateLimiter) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	// as the expiryTime is supposed to reflect the activity (or lack thereof) on that source.
 	if err := rl.buckets.Set(source, bucket, rl.ttl); err != nil {
 		logger.Error().Err(err).Msg("Could not insert/update bucket")
+		tracing.SetStatusErrorf(req.Context(), "Could not insert/update bucket")
 		http.Error(rw, "could not insert/update bucket", http.StatusInternalServerError)
 		return
 	}
 
 	res := bucket.Reserve()
 	if !res.OK() {
+		tracing.SetStatusErrorf(req.Context(), "No bursty traffic allowed")
 		http.Error(rw, "No bursty traffic allowed", http.StatusTooManyRequests)
 		return
 	}
diff --git a/pkg/middlewares/redirect/redirect.go b/pkg/middlewares/redirect/redirect.go
index d64d8cd70e..25ca6a2ac9 100644
--- a/pkg/middlewares/redirect/redirect.go
+++ b/pkg/middlewares/redirect/redirect.go
@@ -5,9 +5,8 @@ import (
 	"net/url"
 	"regexp"
 
-	"github.com/opentracing/opentracing-go/ext"
-	"github.com/traefik/traefik/v3/pkg/tracing"
 	"github.com/vulcand/oxy/v2/utils"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -15,6 +14,8 @@ const (
 	schemeHTTPS = "https"
 )
 
+const typeName = "Redirect"
+
 var uriRegexp = regexp.MustCompile(`^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$`)
 
 type redirect struct {
@@ -45,8 +46,8 @@ func newRedirect(next http.Handler, regex, replacement string, permanent bool, r
 	}, nil
 }
 
-func (r *redirect) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return r.name, tracing.SpanKindNoneEnum
+func (r *redirect) GetTracingInformation() (string, string, trace.SpanKind) {
+	return r.name, typeName, trace.SpanKindInternal
 }
 
 func (r *redirect) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/replacepath/replace_path.go b/pkg/middlewares/replacepath/replace_path.go
index 9f6fea4431..3419d7b838 100644
--- a/pkg/middlewares/replacepath/replace_path.go
+++ b/pkg/middlewares/replacepath/replace_path.go
@@ -5,10 +5,10 @@ import (
 	"net/http"
 	"net/url"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -35,8 +35,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.ReplacePath, nam
 	}, nil
 }
 
-func (r *replacePath) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return r.name, tracing.SpanKindNoneEnum
+func (r *replacePath) GetTracingInformation() (string, string, trace.SpanKind) {
+	return r.name, typeName, trace.SpanKindInternal
 }
 
 func (r *replacePath) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
@@ -52,6 +52,7 @@ func (r *replacePath) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	req.URL.Path, err = url.PathUnescape(req.URL.RawPath)
 	if err != nil {
 		middlewares.GetLogger(context.Background(), r.name, typeName).Error().Err(err).Send()
+		tracing.SetStatusErrorf(req.Context(), err.Error())
 		http.Error(rw, err.Error(), http.StatusInternalServerError)
 		return
 	}
diff --git a/pkg/middlewares/replacepathregex/replace_path_regex.go b/pkg/middlewares/replacepathregex/replace_path_regex.go
index 1fffb6bd47..ff800d354d 100644
--- a/pkg/middlewares/replacepathregex/replace_path_regex.go
+++ b/pkg/middlewares/replacepathregex/replace_path_regex.go
@@ -8,11 +8,11 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/middlewares/replacepath"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const typeName = "ReplacePathRegex"
@@ -42,8 +42,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.ReplacePathRegex
 	}, nil
 }
 
-func (rp *replacePathRegex) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return rp.name, tracing.SpanKindNoneEnum
+func (rp *replacePathRegex) GetTracingInformation() (string, string, trace.SpanKind) {
+	return rp.name, typeName, trace.SpanKindInternal
 }
 
 func (rp *replacePathRegex) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
@@ -63,6 +63,7 @@ func (rp *replacePathRegex) ServeHTTP(rw http.ResponseWriter, req *http.Request)
 		req.URL.Path, err = url.PathUnescape(req.URL.RawPath)
 		if err != nil {
 			middlewares.GetLogger(context.Background(), rp.name, typeName).Error().Err(err).Send()
+			tracing.SetStatusErrorf(req.Context(), err.Error())
 			http.Error(rw, err.Error(), http.StatusInternalServerError)
 			return
 		}
diff --git a/pkg/middlewares/retry/retry.go b/pkg/middlewares/retry/retry.go
index 68bfdadd40..f8945a9897 100644
--- a/pkg/middlewares/retry/retry.go
+++ b/pkg/middlewares/retry/retry.go
@@ -12,10 +12,12 @@ import (
 	"time"
 
 	"github.com/cenkalti/backoff/v4"
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/attribute"
+	semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
+	"go.opentelemetry.io/otel/trace"
 )
 
 // Compile time validation that the response writer implements http interfaces correctly.
@@ -60,10 +62,6 @@ func New(ctx context.Context, next http.Handler, config dynamic.Retry, listener
 	}, nil
 }
 
-func (r *retry) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return r.name, tracing.SpanKindNoneEnum
-}
-
 func (r *retry) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	if r.attempts == 1 {
 		r.next.ServeHTTP(rw, req)
@@ -79,12 +77,35 @@ func (r *retry) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 
 	attempts := 1
 
+	initialCtx := req.Context()
+	tracer := tracing.TracerFromContext(initialCtx)
+
+	var currentSpan trace.Span
 	operation := func() error {
+		if tracer != nil {
+			if currentSpan != nil {
+				currentSpan.End()
+			}
+			// Because multiple tracing spans may need to be created,
+			// the Retry middleware does not implement trace.Traceable,
+			// and creates directly a new span for each retry operation.
+			var tracingCtx context.Context
+			tracingCtx, currentSpan = tracer.Start(initialCtx, typeName, trace.WithSpanKind(trace.SpanKindInternal))
+
+			currentSpan.SetAttributes(attribute.String("traefik.middleware.name", r.name))
+			// Only add the attribute "http.resend_count" defined by semantic conventions starting from second attempt.
+			if attempts > 1 {
+				currentSpan.SetAttributes(semconv.HTTPResendCount(attempts - 1))
+			}
+
+			req = req.WithContext(tracingCtx)
+		}
+
 		shouldRetry := attempts < r.attempts
 		retryResponseWriter := newResponseWriter(rw, shouldRetry)
 
 		// Disable retries when the backend already received request data
-		trace := &httptrace.ClientTrace{
+		clientTrace := &httptrace.ClientTrace{
 			WroteHeaders: func() {
 				retryResponseWriter.DisableRetries()
 			},
@@ -92,7 +113,7 @@ func (r *retry) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 				retryResponseWriter.DisableRetries()
 			},
 		}
-		newCtx := httptrace.WithClientTrace(req.Context(), trace)
+		newCtx := httptrace.WithClientTrace(req.Context(), clientTrace)
 
 		r.next.ServeHTTP(retryResponseWriter, req.Clone(newCtx))
 
@@ -119,6 +140,10 @@ func (r *retry) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	if err != nil {
 		logger.Debug().Err(err).Msg("Final retry attempt failed")
 	}
+
+	if currentSpan != nil {
+		currentSpan.End()
+	}
 }
 
 func (r *retry) newBackOff() backoff.BackOff {
diff --git a/pkg/middlewares/stripprefix/strip_prefix.go b/pkg/middlewares/stripprefix/strip_prefix.go
index a017c051f0..18717875e7 100644
--- a/pkg/middlewares/stripprefix/strip_prefix.go
+++ b/pkg/middlewares/stripprefix/strip_prefix.go
@@ -5,10 +5,9 @@ import (
 	"net/http"
 	"strings"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -34,8 +33,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.StripPrefix, nam
 	}, nil
 }
 
-func (s *stripPrefix) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return s.name, tracing.SpanKindNoneEnum
+func (s *stripPrefix) GetTracingInformation() (string, string, trace.SpanKind) {
+	return s.name, typeName, trace.SpanKindUnspecified
 }
 
 func (s *stripPrefix) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/stripprefixregex/strip_prefix_regex.go b/pkg/middlewares/stripprefixregex/strip_prefix_regex.go
index 383ce1f01e..71de1ad281 100644
--- a/pkg/middlewares/stripprefixregex/strip_prefix_regex.go
+++ b/pkg/middlewares/stripprefixregex/strip_prefix_regex.go
@@ -6,11 +6,10 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/middlewares/stripprefix"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
@@ -44,8 +43,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.StripPrefixRegex
 	return &stripPrefix, nil
 }
 
-func (s *stripPrefixRegex) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return s.name, tracing.SpanKindNoneEnum
+func (s *stripPrefixRegex) GetTracingInformation() (string, string, trace.SpanKind) {
+	return s.name, typeName, trace.SpanKindInternal
 }
 
 func (s *stripPrefixRegex) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
diff --git a/pkg/middlewares/tracing/entrypoint.go b/pkg/middlewares/tracing/entrypoint.go
index b17d8c2ce2..5ea32ee8ff 100644
--- a/pkg/middlewares/tracing/entrypoint.go
+++ b/pkg/middlewares/tracing/entrypoint.go
@@ -5,57 +5,53 @@ import (
 	"net/http"
 
 	"github.com/containous/alice"
-	"github.com/opentracing/opentracing-go"
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/middlewares"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/trace"
 )
 
 const (
 	entryPointTypeName = "TracingEntryPoint"
 )
 
-// NewEntryPoint creates a new middleware that the incoming request.
-func NewEntryPoint(ctx context.Context, t *tracing.Tracing, entryPointName string, next http.Handler) http.Handler {
+type entryPointTracing struct {
+	tracer     trace.Tracer
+	entryPoint string
+	next       http.Handler
+}
+
+// WrapEntryPointHandler Wraps tracing to alice.Constructor.
+func WrapEntryPointHandler(ctx context.Context, tracer trace.Tracer, entryPointName string) alice.Constructor {
+	return func(next http.Handler) (http.Handler, error) {
+		return newEntryPoint(ctx, tracer, entryPointName, next), nil
+	}
+}
+
+// newEntryPoint creates a new tracing middleware for incoming requests.
+func newEntryPoint(ctx context.Context, tracer trace.Tracer, entryPointName string, next http.Handler) http.Handler {
 	middlewares.GetLogger(ctx, "tracing", entryPointTypeName).Debug().Msg("Creating middleware")
 
-	return &entryPointMiddleware{
+	return &entryPointTracing{
 		entryPoint: entryPointName,
-		Tracing:    t,
+		tracer:     tracer,
 		next:       next,
 	}
 }
 
-type entryPointMiddleware struct {
-	*tracing.Tracing
-	entryPoint string
-	next       http.Handler
-}
+func (e *entryPointTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+	tracingCtx := tracing.ExtractCarrierIntoContext(req.Context(), req.Header)
+	tracingCtx, span := e.tracer.Start(tracingCtx, "EntryPoint", trace.WithSpanKind(trace.SpanKindServer))
+	defer span.End()
 
-func (e *entryPointMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	spanCtx, err := e.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header))
-	if err != nil {
-		middlewares.GetLogger(req.Context(), "tracing", entryPointTypeName).
-			Debug().Err(err).Msg("Failed to extract the context")
-	}
+	req = req.WithContext(tracingCtx)
 
-	span, req, finish := e.StartSpanf(req, ext.SpanKindRPCServerEnum, "EntryPoint", []string{e.entryPoint, req.Host}, " ", ext.RPCServerOption(spanCtx))
-	defer finish()
+	span.SetAttributes(attribute.String("entry_point", e.entryPoint))
 
-	ext.Component.Set(span, e.ServiceName)
-	tracing.LogRequest(span, req)
-
-	req = req.WithContext(tracing.WithTracing(req.Context(), e.Tracing))
+	tracing.LogServerRequest(span, req)
 
 	recorder := newStatusCodeRecorder(rw, http.StatusOK)
 	e.next.ServeHTTP(recorder, req)
 
-	tracing.LogResponseCode(span, recorder.Status())
-}
-
-// WrapEntryPointHandler Wraps tracing to alice.Constructor.
-func WrapEntryPointHandler(ctx context.Context, tracer *tracing.Tracing, entryPointName string) alice.Constructor {
-	return func(next http.Handler) (http.Handler, error) {
-		return NewEntryPoint(ctx, tracer, entryPointName, next), nil
-	}
+	tracing.LogResponseCode(span, recorder.Status(), trace.SpanKindServer)
 }
diff --git a/pkg/middlewares/tracing/forwarder.go b/pkg/middlewares/tracing/forwarder.go
deleted file mode 100644
index e2ee76a105..0000000000
--- a/pkg/middlewares/tracing/forwarder.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package tracing
-
-import (
-	"context"
-	"net/http"
-
-	"github.com/opentracing/opentracing-go/ext"
-	"github.com/traefik/traefik/v3/pkg/logs"
-	"github.com/traefik/traefik/v3/pkg/middlewares"
-	"github.com/traefik/traefik/v3/pkg/tracing"
-)
-
-const (
-	forwarderTypeName = "TracingForwarder"
-)
-
-type forwarderMiddleware struct {
-	router  string
-	service string
-	next    http.Handler
-}
-
-// NewForwarder creates a new forwarder middleware that traces the outgoing request.
-func NewForwarder(ctx context.Context, router, service string, next http.Handler) http.Handler {
-	middlewares.GetLogger(ctx, "tracing", forwarderTypeName).
-		Debug().Str(logs.ServiceName, service).Msg("Added outgoing tracing middleware")
-
-	return &forwarderMiddleware{
-		router:  router,
-		service: service,
-		next:    next,
-	}
-}
-
-func (f *forwarderMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	tr, err := tracing.FromContext(req.Context())
-	if err != nil {
-		f.next.ServeHTTP(rw, req)
-		return
-	}
-
-	opParts := []string{f.service, f.router}
-	span, req, finish := tr.StartSpanf(req, ext.SpanKindRPCClientEnum, "forward", opParts, "/")
-	defer finish()
-
-	span.SetTag("traefik.service.name", f.service)
-	span.SetTag("traefik.router.name", f.router)
-	ext.HTTPMethod.Set(span, req.Method)
-	ext.HTTPUrl.Set(span, req.URL.String())
-	span.SetTag("http.host", req.Host)
-
-	tracing.InjectRequestHeaders(req)
-
-	recorder := newStatusCodeRecorder(rw, 200)
-
-	f.next.ServeHTTP(recorder, req)
-
-	tracing.LogResponseCode(span, recorder.Status())
-}
diff --git a/pkg/middlewares/tracing/middleware.go b/pkg/middlewares/tracing/middleware.go
new file mode 100644
index 0000000000..47a6af5022
--- /dev/null
+++ b/pkg/middlewares/tracing/middleware.go
@@ -0,0 +1,71 @@
+package tracing
+
+import (
+	"context"
+	"net/http"
+
+	"github.com/containous/alice"
+	"github.com/rs/zerolog/log"
+	"github.com/traefik/traefik/v3/pkg/logs"
+	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// Traceable embeds tracing information.
+type Traceable interface {
+	GetTracingInformation() (name string, typeName string, spanKind trace.SpanKind)
+}
+
+// WrapMiddleware adds traceability to an alice.Constructor.
+func WrapMiddleware(ctx context.Context, constructor alice.Constructor) alice.Constructor {
+	return func(next http.Handler) (http.Handler, error) {
+		if constructor == nil {
+			return nil, nil
+		}
+		handler, err := constructor(next)
+		if err != nil {
+			return nil, err
+		}
+
+		if traceableHandler, ok := handler.(Traceable); ok {
+			name, typeName, spanKind := traceableHandler.GetTracingInformation()
+			log.Ctx(ctx).Debug().Str(logs.MiddlewareName, name).Msg("Adding tracing to middleware")
+			return NewMiddleware(handler, name, typeName, spanKind), nil
+		}
+		return handler, nil
+	}
+}
+
+// NewMiddleware returns a http.Handler struct.
+func NewMiddleware(next http.Handler, name string, typeName string, spanKind trace.SpanKind) http.Handler {
+	return &middlewareTracing{
+		next:     next,
+		name:     name,
+		typeName: typeName,
+		spanKind: spanKind,
+	}
+}
+
+// middlewareTracing is used to wrap http handler middleware.
+type middlewareTracing struct {
+	next     http.Handler
+	name     string
+	typeName string
+	spanKind trace.SpanKind
+}
+
+func (w *middlewareTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+	if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
+		tracingCtx, span := tracer.Start(req.Context(), w.typeName, trace.WithSpanKind(w.spanKind))
+		defer span.End()
+
+		req = req.WithContext(tracingCtx)
+
+		span.SetAttributes(attribute.String("traefik.middleware.name", w.name))
+	}
+
+	if w.next != nil {
+		w.next.ServeHTTP(rw, req)
+	}
+}
diff --git a/pkg/middlewares/tracing/router.go b/pkg/middlewares/tracing/router.go
new file mode 100644
index 0000000000..e964be12ca
--- /dev/null
+++ b/pkg/middlewares/tracing/router.go
@@ -0,0 +1,60 @@
+package tracing
+
+import (
+	"context"
+	"net/http"
+
+	"github.com/containous/alice"
+	"github.com/traefik/traefik/v3/pkg/logs"
+	"github.com/traefik/traefik/v3/pkg/middlewares"
+	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/attribute"
+	semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
+	"go.opentelemetry.io/otel/trace"
+)
+
+const (
+	routerTypeName = "TracingRouter"
+)
+
+type routerTracing struct {
+	router     string
+	routerRule string
+	service    string
+	next       http.Handler
+}
+
+// WrapRouterHandler Wraps tracing to alice.Constructor.
+func WrapRouterHandler(ctx context.Context, router, routerRule, service string) alice.Constructor {
+	return func(next http.Handler) (http.Handler, error) {
+		return newRouter(ctx, router, routerRule, service, next), nil
+	}
+}
+
+// newRouter creates a new tracing middleware that traces the internal requests.
+func newRouter(ctx context.Context, router, routerRule, service string, next http.Handler) http.Handler {
+	middlewares.GetLogger(ctx, "tracing", routerTypeName).
+		Debug().Str(logs.RouterName, router).Str(logs.ServiceName, service).Msg("Added outgoing tracing middleware")
+
+	return &routerTracing{
+		router:     router,
+		routerRule: routerRule,
+		service:    service,
+		next:       next,
+	}
+}
+
+func (f *routerTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+	if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
+		tracingCtx, span := tracer.Start(req.Context(), "Router", trace.WithSpanKind(trace.SpanKindInternal))
+		defer span.End()
+
+		req = req.WithContext(tracingCtx)
+
+		span.SetAttributes(attribute.String("traefik.service.name", f.service))
+		span.SetAttributes(attribute.String("traefik.router.name", f.router))
+		span.SetAttributes(semconv.HTTPRoute(f.routerRule))
+	}
+
+	f.next.ServeHTTP(rw, req)
+}
diff --git a/pkg/middlewares/tracing/service.go b/pkg/middlewares/tracing/service.go
new file mode 100644
index 0000000000..9cc5bd1ca6
--- /dev/null
+++ b/pkg/middlewares/tracing/service.go
@@ -0,0 +1,45 @@
+package tracing
+
+import (
+	"context"
+	"net/http"
+
+	"github.com/traefik/traefik/v3/pkg/logs"
+	"github.com/traefik/traefik/v3/pkg/middlewares"
+	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/trace"
+)
+
+const (
+	serviceTypeName = "TracingService"
+)
+
+type serviceTracing struct {
+	service string
+	next    http.Handler
+}
+
+// NewService creates a new tracing middleware that traces the outgoing requests.
+func NewService(ctx context.Context, service string, next http.Handler) http.Handler {
+	middlewares.GetLogger(ctx, "tracing", serviceTypeName).
+		Debug().Str(logs.ServiceName, service).Msg("Added outgoing tracing middleware")
+
+	return &serviceTracing{
+		service: service,
+		next:    next,
+	}
+}
+
+func (t *serviceTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+	if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
+		tracingCtx, span := tracer.Start(req.Context(), "Service", trace.WithSpanKind(trace.SpanKindInternal))
+		defer span.End()
+
+		req = req.WithContext(tracingCtx)
+
+		span.SetAttributes(attribute.String("traefik.service.name", t.service))
+	}
+
+	t.next.ServeHTTP(rw, req)
+}
diff --git a/pkg/middlewares/tracing/wrapper.go b/pkg/middlewares/tracing/wrapper.go
deleted file mode 100644
index 1fa3cfcdd8..0000000000
--- a/pkg/middlewares/tracing/wrapper.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package tracing
-
-import (
-	"context"
-	"net/http"
-
-	"github.com/containous/alice"
-	"github.com/opentracing/opentracing-go/ext"
-	"github.com/rs/zerolog/log"
-	"github.com/traefik/traefik/v3/pkg/logs"
-	"github.com/traefik/traefik/v3/pkg/tracing"
-)
-
-// Traceable embeds tracing information.
-type Traceable interface {
-	GetTracingInformation() (name string, spanKind ext.SpanKindEnum)
-}
-
-// Wrap adds traceability to an alice.Constructor.
-func Wrap(ctx context.Context, constructor alice.Constructor) alice.Constructor {
-	return func(next http.Handler) (http.Handler, error) {
-		if constructor == nil {
-			return nil, nil
-		}
-		handler, err := constructor(next)
-		if err != nil {
-			return nil, err
-		}
-
-		if traceableHandler, ok := handler.(Traceable); ok {
-			name, spanKind := traceableHandler.GetTracingInformation()
-			log.Ctx(ctx).Debug().Str(logs.MiddlewareName, name).Msg("Adding tracing to middleware")
-			return NewWrapper(handler, name, spanKind), nil
-		}
-		return handler, nil
-	}
-}
-
-// NewWrapper returns a http.Handler struct.
-func NewWrapper(next http.Handler, name string, spanKind ext.SpanKindEnum) http.Handler {
-	return &Wrapper{
-		next:     next,
-		name:     name,
-		spanKind: spanKind,
-	}
-}
-
-// Wrapper is used to wrap http handler middleware.
-type Wrapper struct {
-	next     http.Handler
-	name     string
-	spanKind ext.SpanKindEnum
-}
-
-func (w *Wrapper) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	_, err := tracing.FromContext(req.Context())
-	if err != nil {
-		w.next.ServeHTTP(rw, req)
-		return
-	}
-
-	var finish func()
-	_, req, finish = tracing.StartSpan(req, w.name, w.spanKind)
-	defer finish()
-
-	if w.next != nil {
-		w.next.ServeHTTP(rw, req)
-	}
-}
diff --git a/pkg/server/middleware/chainbuilder.go b/pkg/server/middleware/chainbuilder.go
index 864e7e68b4..980d7a2b51 100644
--- a/pkg/server/middleware/chainbuilder.go
+++ b/pkg/server/middleware/chainbuilder.go
@@ -8,20 +8,20 @@ import (
 	"github.com/traefik/traefik/v3/pkg/metrics"
 	"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
 	"github.com/traefik/traefik/v3/pkg/middlewares/capture"
-	metricsmiddleware "github.com/traefik/traefik/v3/pkg/middlewares/metrics"
-	mTracing "github.com/traefik/traefik/v3/pkg/middlewares/tracing"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	metricsMiddle "github.com/traefik/traefik/v3/pkg/middlewares/metrics"
+	tracingMiddle "github.com/traefik/traefik/v3/pkg/middlewares/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 // ChainBuilder Creates a middleware chain by entry point. It is used for middlewares that are created almost systematically and that need to be created before all others.
 type ChainBuilder struct {
 	metricsRegistry        metrics.Registry
 	accessLoggerMiddleware *accesslog.Handler
-	tracer                 *tracing.Tracing
+	tracer                 trace.Tracer
 }
 
 // NewChainBuilder Creates a new ChainBuilder.
-func NewChainBuilder(metricsRegistry metrics.Registry, accessLoggerMiddleware *accesslog.Handler, tracer *tracing.Tracing) *ChainBuilder {
+func NewChainBuilder(metricsRegistry metrics.Registry, accessLoggerMiddleware *accesslog.Handler, tracer trace.Tracer) *ChainBuilder {
 	return &ChainBuilder{
 		metricsRegistry:        metricsRegistry,
 		accessLoggerMiddleware: accessLoggerMiddleware,
@@ -42,11 +42,12 @@ func (c *ChainBuilder) Build(ctx context.Context, entryPointName string) alice.C
 	}
 
 	if c.tracer != nil {
-		chain = chain.Append(mTracing.WrapEntryPointHandler(ctx, c.tracer, entryPointName))
+		chain = chain.Append(tracingMiddle.WrapEntryPointHandler(ctx, c.tracer, entryPointName))
 	}
 
 	if c.metricsRegistry != nil && c.metricsRegistry.IsEpEnabled() {
-		chain = chain.Append(metricsmiddleware.WrapEntryPointHandler(ctx, c.metricsRegistry, entryPointName))
+		metricsHandler := metricsMiddle.WrapEntryPointHandler(ctx, c.metricsRegistry, entryPointName)
+		chain = chain.Append(tracingMiddle.WrapMiddleware(ctx, metricsHandler))
 	}
 
 	return chain
@@ -59,8 +60,4 @@ func (c *ChainBuilder) Close() {
 			log.Error().Err(err).Msg("Could not close the access log file")
 		}
 	}
-
-	if c.tracer != nil {
-		c.tracer.Close()
-	}
 }
diff --git a/pkg/server/middleware/middlewares.go b/pkg/server/middleware/middlewares.go
index afeab88e4c..fe2fd23a96 100644
--- a/pkg/server/middleware/middlewares.go
+++ b/pkg/server/middleware/middlewares.go
@@ -372,7 +372,7 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) (
 		return nil, fmt.Errorf("invalid middleware %q configuration: invalid middleware type or middleware does not exist", middlewareName)
 	}
 
-	return tracing.Wrap(ctx, middleware), nil
+	return tracing.WrapMiddleware(ctx, middleware), nil
 }
 
 func inSlice(element string, stack []string) bool {
diff --git a/pkg/server/middleware/plugins.go b/pkg/server/middleware/plugins.go
index 80253b05b4..eacf8fba1c 100644
--- a/pkg/server/middleware/plugins.go
+++ b/pkg/server/middleware/plugins.go
@@ -5,12 +5,13 @@ import (
 	"errors"
 	"net/http"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/plugins"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
+const typeName = "Plugin"
+
 // PluginsBuilder the plugin's builder interface.
 type PluginsBuilder interface {
 	Build(pName string, config map[string]interface{}, middlewareName string) (plugins.Constructor, error)
@@ -54,6 +55,6 @@ func (s *traceablePlugin) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	s.h.ServeHTTP(rw, req)
 }
 
-func (s *traceablePlugin) GetTracingInformation() (string, ext.SpanKindEnum) {
-	return s.name, tracing.SpanKindNoneEnum
+func (s *traceablePlugin) GetTracingInformation() (string, string, trace.SpanKind) {
+	return s.name, typeName, trace.SpanKindInternal
 }
diff --git a/pkg/server/router/router.go b/pkg/server/router/router.go
index 5e4aa043bb..4b383e0768 100644
--- a/pkg/server/router/router.go
+++ b/pkg/server/router/router.go
@@ -198,21 +198,20 @@ func (m *Manager) buildHTTPHandler(ctx context.Context, router *runtime.RouterIn
 
 	mHandler := m.middlewaresBuilder.BuildChain(ctx, router.Middlewares)
 
-	tHandler := func(next http.Handler) (http.Handler, error) {
-		return tracing.NewForwarder(ctx, routerName, router.Service, next), nil
-	}
-
 	chain := alice.New()
 
+	chain = chain.Append(tracing.WrapRouterHandler(ctx, routerName, router.Rule, provider.GetQualifiedName(ctx, router.Service)))
+
 	if m.metricsRegistry != nil && m.metricsRegistry.IsRouterEnabled() {
-		chain = chain.Append(metricsMiddle.WrapRouterHandler(ctx, m.metricsRegistry, routerName, provider.GetQualifiedName(ctx, router.Service)))
+		metricsHandler := metricsMiddle.WrapRouterHandler(ctx, m.metricsRegistry, routerName, provider.GetQualifiedName(ctx, router.Service))
+		chain = chain.Append(tracing.WrapMiddleware(ctx, metricsHandler))
 	}
 
 	if router.DefaultRule {
 		chain = chain.Append(denyrouterrecursion.WrapHandler(routerName))
 	}
 
-	return chain.Extend(*mHandler).Append(tHandler).Then(sHandler)
+	return chain.Extend(*mHandler).Then(sHandler)
 }
 
 // BuildDefaultHTTPRouter creates a default HTTP router.
diff --git a/pkg/server/server.go b/pkg/server/server.go
index c17464621e..0f4379f049 100644
--- a/pkg/server/server.go
+++ b/pkg/server/server.go
@@ -3,6 +3,7 @@ package server
 import (
 	"context"
 	"errors"
+	"io"
 	"os"
 	"os/signal"
 	"time"
@@ -27,12 +28,12 @@ type Server struct {
 	stopChan chan bool
 
 	routinesPool *safe.Pool
+
+	tracerCloser io.Closer
 }
 
 // NewServer returns an initialized Server.
-func NewServer(routinesPool *safe.Pool, entryPoints TCPEntryPoints, entryPointsUDP UDPEntryPoints, watcher *ConfigurationWatcher,
-	chainBuilder *middleware.ChainBuilder, accessLoggerMiddleware *accesslog.Handler,
-) *Server {
+func NewServer(routinesPool *safe.Pool, entryPoints TCPEntryPoints, entryPointsUDP UDPEntryPoints, watcher *ConfigurationWatcher, chainBuilder *middleware.ChainBuilder, accessLoggerMiddleware *accesslog.Handler, tracerCloser io.Closer) *Server {
 	srv := &Server{
 		watcher:                watcher,
 		tcpEntryPoints:         entryPoints,
@@ -42,6 +43,7 @@ func NewServer(routinesPool *safe.Pool, entryPoints TCPEntryPoints, entryPointsU
 		stopChan:               make(chan bool, 1),
 		routinesPool:           routinesPool,
 		udpEntryPoints:         entryPointsUDP,
+		tracerCloser:           tracerCloser,
 	}
 
 	srv.configureSignals()
@@ -105,6 +107,12 @@ func (s *Server) Close() {
 
 	s.chainBuilder.Close()
 
+	if s.tracerCloser != nil {
+		if err := s.tracerCloser.Close(); err != nil {
+			log.Error().Err(err).Msg("Could not close the tracer")
+		}
+	}
+
 	cancel()
 }
 
diff --git a/pkg/server/service/proxy.go b/pkg/server/service/proxy.go
index 413a97a6c0..083875f9e9 100644
--- a/pkg/server/service/proxy.go
+++ b/pkg/server/service/proxy.go
@@ -22,9 +22,13 @@ const StatusClientClosedRequest = 499
 const StatusClientClosedRequestText = "Client Closed Request"
 
 func buildSingleHostProxy(target *url.URL, passHostHeader bool, flushInterval time.Duration, roundTripper http.RoundTripper, bufferPool httputil.BufferPool) http.Handler {
+	// Wrapping the roundTripper with the Tracing roundTripper,
+	// to handle the reverseProxy client span creation.
+	tracingRoundTripper := newTracingRoundTripper(roundTripper)
+
 	return &httputil.ReverseProxy{
 		Director:      directorBuilder(target, passHostHeader),
-		Transport:     roundTripper,
+		Transport:     tracingRoundTripper,
 		FlushInterval: flushInterval,
 		BufferPool:    bufferPool,
 		ErrorHandler:  errorHandler,
@@ -94,31 +98,35 @@ func isWebSocketUpgrade(req *http.Request) bool {
 }
 
 func errorHandler(w http.ResponseWriter, req *http.Request, err error) {
-	statusCode := http.StatusInternalServerError
+	statusCode := computeStatusCode(err)
+
+	logger := log.Ctx(req.Context())
+	logger.Debug().Err(err).Msgf("%d %s", statusCode, statusText(statusCode))
+
+	w.WriteHeader(statusCode)
+	if _, werr := w.Write([]byte(statusText(statusCode))); werr != nil {
+		logger.Debug().Err(werr).Msg("Error while writing status code")
+	}
+}
 
+func computeStatusCode(err error) int {
 	switch {
 	case errors.Is(err, io.EOF):
-		statusCode = http.StatusBadGateway
+		return http.StatusBadGateway
 	case errors.Is(err, context.Canceled):
-		statusCode = StatusClientClosedRequest
+		return StatusClientClosedRequest
 	default:
 		var netErr net.Error
 		if errors.As(err, &netErr) {
 			if netErr.Timeout() {
-				statusCode = http.StatusGatewayTimeout
-			} else {
-				statusCode = http.StatusBadGateway
+				return http.StatusGatewayTimeout
 			}
+
+			return http.StatusBadGateway
 		}
 	}
 
-	logger := log.Ctx(req.Context())
-	logger.Debug().Err(err).Msgf("%d %s", statusCode, statusText(statusCode))
-
-	w.WriteHeader(statusCode)
-	if _, werr := w.Write([]byte(statusText(statusCode))); werr != nil {
-		logger.Debug().Err(werr).Msg("Error while writing status code")
-	}
+	return http.StatusInternalServerError
 }
 
 func statusText(statusCode int) string {
diff --git a/pkg/server/service/service.go b/pkg/server/service/service.go
index 61f6859f43..55fcb9fa24 100644
--- a/pkg/server/service/service.go
+++ b/pkg/server/service/service.go
@@ -14,6 +14,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/containous/alice"
 	"github.com/rs/zerolog/log"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
 	"github.com/traefik/traefik/v3/pkg/config/runtime"
@@ -22,6 +23,7 @@ import (
 	"github.com/traefik/traefik/v3/pkg/metrics"
 	"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
 	metricsMiddle "github.com/traefik/traefik/v3/pkg/middlewares/metrics"
+	tracingMiddle "github.com/traefik/traefik/v3/pkg/middlewares/tracing"
 	"github.com/traefik/traefik/v3/pkg/safe"
 	"github.com/traefik/traefik/v3/pkg/server/cookie"
 	"github.com/traefik/traefik/v3/pkg/server/provider"
@@ -305,9 +307,18 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName
 		proxy = accesslog.NewFieldHandler(proxy, accesslog.ServiceName, serviceName, accesslog.AddServiceFields)
 
 		if m.metricsRegistry != nil && m.metricsRegistry.IsSvcEnabled() {
-			proxy = metricsMiddle.NewServiceMiddleware(ctx, proxy, m.metricsRegistry, serviceName)
+			metricsHandler := metricsMiddle.WrapServiceHandler(ctx, m.metricsRegistry, serviceName)
+
+			proxy, err = alice.New().
+				Append(tracingMiddle.WrapMiddleware(ctx, metricsHandler)).
+				Then(proxy)
+			if err != nil {
+				return nil, fmt.Errorf("error wrapping metrics handler: %w", err)
+			}
 		}
 
+		proxy = tracingMiddle.NewService(ctx, serviceName, proxy)
+
 		lb.Add(proxyName, proxy, nil)
 
 		// servers are considered UP by default.
diff --git a/pkg/server/service/tracing_roundtripper.go b/pkg/server/service/tracing_roundtripper.go
new file mode 100644
index 0000000000..bdb2ab4f3b
--- /dev/null
+++ b/pkg/server/service/tracing_roundtripper.go
@@ -0,0 +1,42 @@
+package service
+
+import (
+	"context"
+	"net/http"
+
+	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
+)
+
+type wrapper struct {
+	rt http.RoundTripper
+}
+
+func (t *wrapper) RoundTrip(req *http.Request) (*http.Response, error) {
+	var span trace.Span
+	if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
+		var tracingCtx context.Context
+		tracingCtx, span = tracer.Start(req.Context(), "ReverseProxy", trace.WithSpanKind(trace.SpanKindClient))
+		defer span.End()
+
+		req = req.WithContext(tracingCtx)
+
+		tracing.LogClientRequest(span, req)
+		tracing.InjectContextIntoCarrier(req)
+	}
+
+	response, err := t.rt.RoundTrip(req)
+	if err != nil {
+		statusCode := computeStatusCode(err)
+		tracing.LogResponseCode(span, statusCode, trace.SpanKindClient)
+		return response, err
+	}
+
+	tracing.LogResponseCode(span, response.StatusCode, trace.SpanKindClient)
+
+	return response, nil
+}
+
+func newTracingRoundTripper(rt http.RoundTripper) http.RoundTripper {
+	return &wrapper{rt: rt}
+}
diff --git a/pkg/tracing/datadog/datadog.go b/pkg/tracing/datadog/datadog.go
deleted file mode 100644
index 0bdacff7b3..0000000000
--- a/pkg/tracing/datadog/datadog.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package datadog
-
-import (
-	"io"
-	"net"
-	"os"
-
-	"github.com/opentracing/opentracing-go"
-	"github.com/rs/zerolog/log"
-	"github.com/traefik/traefik/v3/pkg/logs"
-	ddtracer "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer"
-	datadog "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
-)
-
-// Name sets the name of this tracer.
-const Name = "datadog"
-
-// Config provides configuration settings for a datadog tracer.
-type Config struct {
-	LocalAgentHostPort         string            `description:"Sets the Datadog Agent host:port." json:"localAgentHostPort,omitempty" toml:"localAgentHostPort,omitempty" yaml:"localAgentHostPort,omitempty"`
-	LocalAgentSocket           string            `description:"Sets the socket for the Datadog Agent." json:"localAgentSocket,omitempty" toml:"localAgentSocket,omitempty" yaml:"localAgentSocket,omitempty"`
-	GlobalTags                 map[string]string `description:"Sets a list of key:value tags on all spans." json:"globalTags,omitempty" toml:"globalTags,omitempty" yaml:"globalTags,omitempty" export:"true"`
-	Debug                      bool              `description:"Enables Datadog debug." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"`
-	PrioritySampling           bool              `description:"Enables priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled." json:"prioritySampling,omitempty" toml:"prioritySampling,omitempty" yaml:"prioritySampling,omitempty" export:"true"`
-	TraceIDHeaderName          string            `description:"Sets the header name used to store the trace ID." json:"traceIDHeaderName,omitempty" toml:"traceIDHeaderName,omitempty" yaml:"traceIDHeaderName,omitempty" export:"true"`
-	ParentIDHeaderName         string            `description:"Sets the header name used to store the parent ID." json:"parentIDHeaderName,omitempty" toml:"parentIDHeaderName,omitempty" yaml:"parentIDHeaderName,omitempty" export:"true"`
-	SamplingPriorityHeaderName string            `description:"Sets the header name used to store the sampling priority." json:"samplingPriorityHeaderName,omitempty" toml:"samplingPriorityHeaderName,omitempty" yaml:"samplingPriorityHeaderName,omitempty" export:"true"`
-	BagagePrefixHeaderName     string            `description:"Sets the header name prefix used to store baggage items in a map." json:"bagagePrefixHeaderName,omitempty" toml:"bagagePrefixHeaderName,omitempty" yaml:"bagagePrefixHeaderName,omitempty" export:"true"`
-}
-
-// SetDefaults sets the default values.
-func (c *Config) SetDefaults() {
-	host, ok := os.LookupEnv("DD_AGENT_HOST")
-	if !ok {
-		host = "localhost"
-	}
-
-	port, ok := os.LookupEnv("DD_TRACE_AGENT_PORT")
-	if !ok {
-		port = "8126"
-	}
-
-	c.LocalAgentHostPort = net.JoinHostPort(host, port)
-}
-
-// Setup sets up the tracer.
-func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) {
-	logger := log.With().Str(logs.TracingProviderName, Name).Logger()
-
-	opts := []datadog.StartOption{
-		datadog.WithService(serviceName),
-		datadog.WithDebugMode(c.Debug),
-		datadog.WithPropagator(datadog.NewPropagator(&datadog.PropagatorConfig{
-			TraceHeader:    c.TraceIDHeaderName,
-			ParentHeader:   c.ParentIDHeaderName,
-			PriorityHeader: c.SamplingPriorityHeaderName,
-			BaggagePrefix:  c.BagagePrefixHeaderName,
-		})),
-		datadog.WithLogger(logs.NewDatadogLogger(logger)),
-	}
-
-	if c.LocalAgentSocket != "" {
-		opts = append(opts, datadog.WithUDS(c.LocalAgentSocket))
-	} else {
-		opts = append(opts, datadog.WithAgentAddr(c.LocalAgentHostPort))
-	}
-
-	for k, v := range c.GlobalTags {
-		opts = append(opts, datadog.WithGlobalTag(k, v))
-	}
-
-	if c.PrioritySampling {
-		opts = append(opts, datadog.WithPrioritySampling())
-	}
-
-	tracer := ddtracer.New(opts...)
-
-	// Without this, child spans are getting the NOOP tracer
-	opentracing.SetGlobalTracer(tracer)
-
-	logger.Debug().Msg("Datadog tracer configured")
-
-	return tracer, nil, nil
-}
diff --git a/pkg/tracing/elastic/elastic.go b/pkg/tracing/elastic/elastic.go
deleted file mode 100644
index 383cca2bdb..0000000000
--- a/pkg/tracing/elastic/elastic.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package elastic
-
-import (
-	"io"
-	"net/url"
-
-	"github.com/opentracing/opentracing-go"
-	"github.com/rs/zerolog/log"
-	"github.com/traefik/traefik/v3/pkg/logs"
-	"github.com/traefik/traefik/v3/pkg/version"
-	"go.elastic.co/apm"
-	"go.elastic.co/apm/module/apmot"
-	"go.elastic.co/apm/transport"
-)
-
-// Name sets the name of this tracer.
-const Name = "elastic"
-
-func init() {
-	// The APM lib uses the init() function to create a default tracer.
-	// So this default tracer must be disabled.
-	// https://github.com/elastic/apm-agent-go/blob/8dd383d0d21776faad8841fe110f35633d199a03/tracer.go#L61-L65
-	apm.DefaultTracer.Close()
-}
-
-// Config provides configuration settings for a elastic.co tracer.
-type Config struct {
-	ServerURL          string `description:"Sets the URL of the Elastic APM server." json:"serverURL,omitempty" toml:"serverURL,omitempty" yaml:"serverURL,omitempty"`
-	SecretToken        string `description:"Sets the token used to connect to Elastic APM Server." json:"secretToken,omitempty" toml:"secretToken,omitempty" yaml:"secretToken,omitempty" loggable:"false"`
-	ServiceEnvironment string `description:"Sets the name of the environment Traefik is deployed in, e.g. 'production' or 'staging'." json:"serviceEnvironment,omitempty" toml:"serviceEnvironment,omitempty" yaml:"serviceEnvironment,omitempty" export:"true"`
-}
-
-// Setup sets up the tracer.
-func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) {
-	// Create default transport.
-	tr, err := transport.NewHTTPTransport()
-	if err != nil {
-		return nil, nil, err
-	}
-
-	if c.ServerURL != "" {
-		serverURL, err := url.Parse(c.ServerURL)
-		if err != nil {
-			return nil, nil, err
-		}
-		tr.SetServerURL(serverURL)
-	}
-
-	if c.SecretToken != "" {
-		tr.SetSecretToken(c.SecretToken)
-	}
-
-	tracer, err := apm.NewTracerOptions(apm.TracerOptions{
-		ServiceName:        serviceName,
-		ServiceVersion:     version.Version,
-		ServiceEnvironment: c.ServiceEnvironment,
-		Transport:          tr,
-	})
-	if err != nil {
-		return nil, nil, err
-	}
-
-	logger := log.With().Str(logs.TracingProviderName, Name).Logger()
-	tracer.SetLogger(logs.NewElasticLogger(logger))
-
-	otTracer := apmot.New(apmot.WithTracer(tracer))
-
-	// Without this, child spans are getting the NOOP tracer
-	opentracing.SetGlobalTracer(otTracer)
-
-	log.Debug().Msg("Elastic tracer configured")
-
-	return otTracer, nil, nil
-}
diff --git a/pkg/tracing/haystack/haystack.go b/pkg/tracing/haystack/haystack.go
deleted file mode 100644
index 6e460dcfb1..0000000000
--- a/pkg/tracing/haystack/haystack.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package haystack
-
-import (
-	"io"
-	"strings"
-	"time"
-
-	"github.com/ExpediaDotCom/haystack-client-go"
-	"github.com/opentracing/opentracing-go"
-	"github.com/rs/zerolog/log"
-	"github.com/traefik/traefik/v3/pkg/logs"
-)
-
-// Name sets the name of this tracer.
-const Name = "haystack"
-
-// Config provides configuration settings for a haystack tracer.
-type Config struct {
-	LocalAgentHost          string `description:"Sets the Haystack Agent host." json:"localAgentHost,omitempty" toml:"localAgentHost,omitempty" yaml:"localAgentHost,omitempty"`
-	LocalAgentPort          int    `description:"Sets the Haystack Agent port." json:"localAgentPort,omitempty" toml:"localAgentPort,omitempty" yaml:"localAgentPort,omitempty"`
-	GlobalTag               string `description:"Sets a key:value tag on all spans." json:"globalTag,omitempty" toml:"globalTag,omitempty" yaml:"globalTag,omitempty" export:"true"`
-	TraceIDHeaderName       string `description:"Sets the header name used to store the trace ID." json:"traceIDHeaderName,omitempty" toml:"traceIDHeaderName,omitempty" yaml:"traceIDHeaderName,omitempty" export:"true"`
-	ParentIDHeaderName      string `description:"Sets the header name used to store the parent ID." json:"parentIDHeaderName,omitempty" toml:"parentIDHeaderName,omitempty" yaml:"parentIDHeaderName,omitempty" export:"true"`
-	SpanIDHeaderName        string `description:"Sets the header name used to store the span ID." json:"spanIDHeaderName,omitempty" toml:"spanIDHeaderName,omitempty" yaml:"spanIDHeaderName,omitempty" export:"true"`
-	BaggagePrefixHeaderName string `description:"Sets the header name prefix used to store baggage items in a map." json:"baggagePrefixHeaderName,omitempty" toml:"baggagePrefixHeaderName,omitempty" yaml:"baggagePrefixHeaderName,omitempty" export:"true"`
-}
-
-// SetDefaults sets the default values.
-func (c *Config) SetDefaults() {
-	c.LocalAgentHost = "127.0.0.1"
-	c.LocalAgentPort = 35000
-}
-
-// Setup sets up the tracer.
-func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) {
-	tag := strings.SplitN(c.GlobalTag, ":", 2)
-
-	value := ""
-	if len(tag) == 2 {
-		value = tag[1]
-	}
-
-	host := "localhost"
-	port := 35000
-	if len(c.LocalAgentHost) > 0 {
-		host = c.LocalAgentHost
-	}
-	if c.LocalAgentPort > 0 {
-		port = c.LocalAgentPort
-	}
-
-	logger := log.With().Str(logs.TracingProviderName, Name).Logger()
-
-	tracer, closer := haystack.NewTracer(serviceName, haystack.NewAgentDispatcher(host, port, 3*time.Second, 1000),
-		haystack.TracerOptionsFactory.Tag(tag[0], value),
-		haystack.TracerOptionsFactory.Propagator(opentracing.HTTPHeaders,
-			haystack.NewTextMapPropagator(haystack.PropagatorOpts{
-				TraceIDKEYName:       c.TraceIDHeaderName,
-				ParentSpanIDKEYName:  c.ParentIDHeaderName,
-				SpanIDKEYName:        c.SpanIDHeaderName,
-				BaggagePrefixKEYName: c.BaggagePrefixHeaderName,
-			}, haystack.DefaultCodex{})),
-		haystack.TracerOptionsFactory.Logger(logs.NewHaystackLogger(logger)),
-	)
-
-	// Without this, child spans are getting the NOOP tracer
-	opentracing.SetGlobalTracer(tracer)
-
-	log.Debug().Msg("haystack tracer configured")
-
-	return tracer, closer, nil
-}
diff --git a/pkg/tracing/instana/instana.go b/pkg/tracing/instana/instana.go
deleted file mode 100644
index edb2ee14e5..0000000000
--- a/pkg/tracing/instana/instana.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package instana
-
-import (
-	"io"
-
-	instana "github.com/instana/go-sensor"
-	"github.com/opentracing/opentracing-go"
-	"github.com/rs/zerolog/log"
-	"github.com/traefik/traefik/v3/pkg/logs"
-)
-
-// Name sets the name of this tracer.
-const Name = "instana"
-
-// Config provides configuration settings for an instana tracer.
-type Config struct {
-	LocalAgentHost    string `description:"Sets the Instana Agent host." json:"localAgentHost,omitempty" toml:"localAgentHost,omitempty" yaml:"localAgentHost,omitempty"`
-	LocalAgentPort    int    `description:"Sets the Instana Agent port." json:"localAgentPort,omitempty" toml:"localAgentPort,omitempty" yaml:"localAgentPort,omitempty"`
-	LogLevel          string `description:"Sets the log level for the Instana tracer. ('error','warn','info','debug')" json:"logLevel,omitempty" toml:"logLevel,omitempty" yaml:"logLevel,omitempty" export:"true"`
-	EnableAutoProfile bool   `description:"Enables automatic profiling for the Traefik process." json:"enableAutoProfile,omitempty" toml:"enableAutoProfile,omitempty" yaml:"enableAutoProfile,omitempty" export:"true"`
-}
-
-// SetDefaults sets the default values.
-func (c *Config) SetDefaults() {
-	c.LocalAgentPort = 42699
-	c.LogLevel = "info"
-}
-
-// Setup sets up the tracer.
-func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) {
-	// set default logLevel
-	logLevel := instana.Info
-
-	// check/set logLevel overrides
-	switch c.LogLevel {
-	case "error":
-		logLevel = instana.Error
-	case "warn":
-		logLevel = instana.Warn
-	case "debug":
-		logLevel = instana.Debug
-	}
-
-	logger := log.With().Str(logs.TracingProviderName, Name).Logger()
-	instana.SetLogger(logs.NewInstanaLogger(logger))
-
-	tracer := instana.NewTracerWithOptions(&instana.Options{
-		Service:           serviceName,
-		LogLevel:          logLevel,
-		AgentPort:         c.LocalAgentPort,
-		AgentHost:         c.LocalAgentHost,
-		EnableAutoProfile: c.EnableAutoProfile,
-	})
-
-	// Without this, child spans are getting the NOOP tracer
-	opentracing.SetGlobalTracer(tracer)
-
-	logger.Debug().Msg("Instana tracer configured")
-
-	return tracer, nil, nil
-}
diff --git a/pkg/tracing/jaeger/jaeger.go b/pkg/tracing/jaeger/jaeger.go
deleted file mode 100644
index 64eeb8e180..0000000000
--- a/pkg/tracing/jaeger/jaeger.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package jaeger
-
-import (
-	"fmt"
-	"io"
-
-	"github.com/opentracing/opentracing-go"
-	"github.com/rs/zerolog/log"
-	"github.com/traefik/traefik/v3/pkg/logs"
-	jaegercli "github.com/uber/jaeger-client-go"
-	jaegercfg "github.com/uber/jaeger-client-go/config"
-	"github.com/uber/jaeger-client-go/zipkin"
-	jaegermet "github.com/uber/jaeger-lib/metrics"
-)
-
-// Name sets the name of this tracer.
-const Name = "jaeger"
-
-// Config provides configuration settings for a jaeger tracer.
-type Config struct {
-	SamplingServerURL          string     `description:"Sets the sampling server URL." json:"samplingServerURL,omitempty" toml:"samplingServerURL,omitempty" yaml:"samplingServerURL,omitempty"`
-	SamplingType               string     `description:"Sets the sampling type." json:"samplingType,omitempty" toml:"samplingType,omitempty" yaml:"samplingType,omitempty" export:"true"`
-	SamplingParam              float64    `description:"Sets the sampling parameter." json:"samplingParam,omitempty" toml:"samplingParam,omitempty" yaml:"samplingParam,omitempty" export:"true"`
-	LocalAgentHostPort         string     `description:"Sets the Jaeger Agent host:port." json:"localAgentHostPort,omitempty" toml:"localAgentHostPort,omitempty" yaml:"localAgentHostPort,omitempty"`
-	Gen128Bit                  bool       `description:"Generates 128 bits span IDs." json:"gen128Bit,omitempty" toml:"gen128Bit,omitempty" yaml:"gen128Bit,omitempty" export:"true"`
-	Propagation                string     `description:"Sets the propagation format (jaeger/b3)." json:"propagation,omitempty" toml:"propagation,omitempty" yaml:"propagation,omitempty" export:"true"`
-	TraceContextHeaderName     string     `description:"Sets the header name used to store the trace ID." json:"traceContextHeaderName,omitempty" toml:"traceContextHeaderName,omitempty" yaml:"traceContextHeaderName,omitempty" export:"true"`
-	Collector                  *Collector `description:"Defines the collector information." json:"collector,omitempty" toml:"collector,omitempty" yaml:"collector,omitempty" export:"true"`
-	DisableAttemptReconnecting bool       `description:"Disables the periodic re-resolution of the agent's hostname and reconnection if there was a change." json:"disableAttemptReconnecting,omitempty" toml:"disableAttemptReconnecting,omitempty" yaml:"disableAttemptReconnecting,omitempty" export:"true"`
-}
-
-// SetDefaults sets the default values.
-func (c *Config) SetDefaults() {
-	c.SamplingServerURL = "http://localhost:5778/sampling"
-	c.SamplingType = "const"
-	c.SamplingParam = 1.0
-	c.LocalAgentHostPort = "127.0.0.1:6831"
-	c.Propagation = "jaeger"
-	c.Gen128Bit = false
-	c.TraceContextHeaderName = jaegercli.TraceContextHeaderName
-	c.DisableAttemptReconnecting = true
-}
-
-// Collector provides configuration settings for jaeger collector.
-type Collector struct {
-	Endpoint string `description:"Instructs reporter to send spans to jaeger-collector at this URL." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
-	User     string `description:"User for basic http authentication when sending spans to jaeger-collector." json:"user,omitempty" toml:"user,omitempty" yaml:"user,omitempty" loggable:"false"`
-	Password string `description:"Password for basic http authentication when sending spans to jaeger-collector." json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty" loggable:"false"`
-}
-
-// SetDefaults sets the default values.
-func (c *Collector) SetDefaults() {
-	c.Endpoint = ""
-	c.User = ""
-	c.Password = ""
-}
-
-// Setup sets up the tracer.
-func (c *Config) Setup(componentName string) (opentracing.Tracer, io.Closer, error) {
-	reporter := &jaegercfg.ReporterConfig{
-		LogSpans:                   true,
-		LocalAgentHostPort:         c.LocalAgentHostPort,
-		DisableAttemptReconnecting: c.DisableAttemptReconnecting,
-	}
-
-	if c.Collector != nil {
-		reporter.CollectorEndpoint = c.Collector.Endpoint
-		reporter.User = c.Collector.User
-		reporter.Password = c.Collector.Password
-	}
-
-	jcfg := &jaegercfg.Configuration{
-		Sampler: &jaegercfg.SamplerConfig{
-			SamplingServerURL: c.SamplingServerURL,
-			Type:              c.SamplingType,
-			Param:             c.SamplingParam,
-		},
-		Reporter: reporter,
-		Headers: &jaegercli.HeadersConfig{
-			TraceContextHeaderName: c.TraceContextHeaderName,
-		},
-	}
-
-	// Overrides existing tracer's Configuration with environment variables.
-	_, err := jcfg.FromEnv()
-	if err != nil {
-		return nil, nil, err
-	}
-
-	jMetricsFactory := jaegermet.NullFactory
-
-	logger := log.With().Str(logs.TracingProviderName, Name).Logger()
-
-	opts := []jaegercfg.Option{
-		jaegercfg.Logger(logs.NewJaegerLogger(logger)),
-		jaegercfg.Metrics(jMetricsFactory),
-		jaegercfg.Gen128Bit(c.Gen128Bit),
-	}
-
-	switch c.Propagation {
-	case "b3":
-		p := zipkin.NewZipkinB3HTTPHeaderPropagator()
-		opts = append(opts,
-			jaegercfg.Injector(opentracing.HTTPHeaders, p),
-			jaegercfg.Extractor(opentracing.HTTPHeaders, p),
-		)
-	case "jaeger", "":
-	default:
-		return nil, nil, fmt.Errorf("unknown propagation format: %s", c.Propagation)
-	}
-
-	// Initialize tracer with a logger and a metrics factory
-	closer, err := jcfg.InitGlobalTracer(
-		componentName,
-		opts...,
-	)
-	if err != nil {
-		logger.Warn().Err(err).Msg("Could not initialize jaeger tracer")
-		return nil, nil, err
-	}
-	logger.Debug().Msg("Jaeger tracer configured")
-
-	return opentracing.GlobalTracer(), closer, nil
-}
diff --git a/pkg/tracing/opentelemetry/opentelemetry.go b/pkg/tracing/opentelemetry/opentelemetry.go
index c59fbd4104..2e13bc20cc 100644
--- a/pkg/tracing/opentelemetry/opentelemetry.go
+++ b/pkg/tracing/opentelemetry/opentelemetry.go
@@ -5,20 +5,21 @@ import (
 	"fmt"
 	"io"
 	"net"
+	"net/url"
+	"time"
 
-	"github.com/opentracing/opentracing-go"
 	"github.com/rs/zerolog/log"
 	"github.com/traefik/traefik/v3/pkg/types"
 	"github.com/traefik/traefik/v3/pkg/version"
 	"go.opentelemetry.io/otel"
-	oteltracer "go.opentelemetry.io/otel/bridge/opentracing"
+	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
 	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
 	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/sdk/resource"
 	sdktrace "go.opentelemetry.io/otel/sdk/trace"
-	semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
+	semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
 	"go.opentelemetry.io/otel/trace"
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/encoding/gzip"
@@ -26,85 +27,108 @@ import (
 
 // Config provides configuration settings for the open-telemetry tracer.
 type Config struct {
-	// NOTE: as no gRPC option is implemented yet, the type is empty and is used as a boolean for upward compatibility purposes.
-	GRPC *struct{} `description:"gRPC specific configuration for the OpenTelemetry collector." json:"grpc,omitempty" toml:"grpc,omitempty" yaml:"grpc,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
-
-	Address  string            `description:"Sets the address (host:port) of the collector endpoint." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`
-	Path     string            `description:"Sets the URL path of the collector endpoint." json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty" export:"true"`
-	Insecure bool              `description:"Disables client transport security for the exporter." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true"`
-	Headers  map[string]string `description:"Defines additional headers to be sent with the payloads." json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"`
-	TLS      *types.ClientTLS  `description:"Defines client transport security parameters." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
+	GRPC *GRPC `description:"gRPC configuration for the OpenTelemetry collector." json:"grpc,omitempty" toml:"grpc,omitempty" yaml:"grpc,omitempty" export:"true"`
+	HTTP *HTTP `description:"HTTP configuration for the OpenTelemetry collector." json:"http,omitempty" toml:"http,omitempty" yaml:"http,omitempty" export:"true"`
+}
+
+// GRPC provides configuration settings for the gRPC open-telemetry tracer.
+type GRPC struct {
+	Endpoint string `description:"Sets the gRPC endpoint (host:port) of the collector." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
+
+	Insecure bool             `description:"Disables client transport security for the exporter." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true"`
+	TLS      *types.ClientTLS `description:"Defines client transport security parameters." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
+}
+
+// SetDefaults sets the default values.
+func (c *GRPC) SetDefaults() {
+	c.Endpoint = "localhost:4317"
+}
+
+// HTTP provides configuration settings for the HTTP open-telemetry tracer.
+type HTTP struct {
+	Endpoint string           `description:"Sets the HTTP endpoint (scheme://host:port/v1/traces) of the collector." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
+	TLS      *types.ClientTLS `description:"Defines client transport security parameters." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
 }
 
 // SetDefaults sets the default values.
-func (c *Config) SetDefaults() {
-	c.Address = "localhost:4318"
+func (c *HTTP) SetDefaults() {
+	c.Endpoint = "localhost:4318"
 }
 
 // Setup sets up the tracer.
-func (c *Config) Setup(componentName string) (opentracing.Tracer, io.Closer, error) {
+func (c *Config) Setup(serviceName string, sampleRate float64, globalAttributes map[string]string, headers map[string]string) (trace.Tracer, io.Closer, error) {
 	var (
 		err      error
 		exporter *otlptrace.Exporter
 	)
 	if c.GRPC != nil {
-		exporter, err = c.setupGRPCExporter()
+		exporter, err = c.setupGRPCExporter(headers)
 	} else {
-		exporter, err = c.setupHTTPExporter()
+		exporter, err = c.setupHTTPExporter(headers)
 	}
 	if err != nil {
 		return nil, nil, fmt.Errorf("setting up exporter: %w", err)
 	}
 
-	bt := oteltracer.NewBridgeTracer()
-	bt.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
+	attr := []attribute.KeyValue{
+		semconv.ServiceNameKey.String(serviceName),
+		semconv.ServiceVersionKey.String(version.Version),
+	}
 
-	bt.SetOpenTelemetryTracer(otel.Tracer(componentName, trace.WithInstrumentationVersion(version.Version)))
-	opentracing.SetGlobalTracer(bt)
+	for k, v := range globalAttributes {
+		attr = append(attr, attribute.String(k, v))
+	}
 
 	res, err := resource.New(context.Background(),
-		resource.WithAttributes(semconv.ServiceNameKey.String("traefik")),
-		resource.WithAttributes(semconv.ServiceVersionKey.String(version.Version)),
+		resource.WithAttributes(attr...),
 		resource.WithFromEnv(),
 		resource.WithTelemetrySDK(),
+		resource.WithOSType(),
+		resource.WithProcessCommandArgs(),
 	)
 	if err != nil {
 		return nil, nil, fmt.Errorf("building resource: %w", err)
 	}
 
+	// Register the trace exporter with a TracerProvider, using a batch
+	// span processor to aggregate spans before export.
+	bsp := sdktrace.NewBatchSpanProcessor(exporter)
 	tracerProvider := sdktrace.NewTracerProvider(
+		sdktrace.WithSampler(sdktrace.TraceIDRatioBased(sampleRate)),
 		sdktrace.WithResource(res),
-		sdktrace.WithBatcher(exporter),
+		sdktrace.WithSpanProcessor(bsp),
 	)
+
 	otel.SetTracerProvider(tracerProvider)
+	otel.SetTextMapPropagator(propagation.TraceContext{})
 
 	log.Debug().Msg("OpenTelemetry tracer configured")
 
-	return bt, tpCloser{provider: tracerProvider}, err
+	return tracerProvider.Tracer("github.com/traefik/traefik"), &tpCloser{provider: tracerProvider}, err
 }
 
-func (c *Config) setupHTTPExporter() (*otlptrace.Exporter, error) {
-	host, port, err := net.SplitHostPort(c.Address)
+func (c *Config) setupHTTPExporter(headers map[string]string) (*otlptrace.Exporter, error) {
+	endpoint, err := url.Parse(c.HTTP.Endpoint)
 	if err != nil {
-		return nil, fmt.Errorf("invalid collector address %q: %w", c.Address, err)
+		return nil, fmt.Errorf("invalid collector endpoint %q: %w", c.HTTP.Endpoint, err)
 	}
 
 	opts := []otlptracehttp.Option{
-		otlptracehttp.WithEndpoint(fmt.Sprintf("%s:%s", host, port)),
-		otlptracehttp.WithHeaders(c.Headers),
+		otlptracehttp.WithEndpoint(endpoint.Host),
+		otlptracehttp.WithHeaders(headers),
 		otlptracehttp.WithCompression(otlptracehttp.GzipCompression),
 	}
 
-	if c.Insecure {
+	if endpoint.Scheme == "http" {
 		opts = append(opts, otlptracehttp.WithInsecure())
 	}
 
-	if c.Path != "" {
-		opts = append(opts, otlptracehttp.WithURLPath(c.Path))
+	if endpoint.Path != "" {
+		opts = append(opts, otlptracehttp.WithURLPath(endpoint.Path))
 	}
 
-	if c.TLS != nil {
-		tlsConfig, err := c.TLS.CreateTLSConfig(context.Background())
+	if c.HTTP.TLS != nil {
+		tlsConfig, err := c.HTTP.TLS.CreateTLSConfig(context.Background())
 		if err != nil {
 			return nil, fmt.Errorf("creating TLS client config: %w", err)
 		}
@@ -115,24 +139,24 @@ func (c *Config) setupHTTPExporter() (*otlptrace.Exporter, error) {
 	return otlptrace.New(context.Background(), otlptracehttp.NewClient(opts...))
 }
 
-func (c *Config) setupGRPCExporter() (*otlptrace.Exporter, error) {
-	host, port, err := net.SplitHostPort(c.Address)
+func (c *Config) setupGRPCExporter(headers map[string]string) (*otlptrace.Exporter, error) {
+	host, port, err := net.SplitHostPort(c.GRPC.Endpoint)
 	if err != nil {
-		return nil, fmt.Errorf("invalid collector address %q: %w", c.Address, err)
+		return nil, fmt.Errorf("invalid collector address %q: %w", c.GRPC.Endpoint, err)
 	}
 
 	opts := []otlptracegrpc.Option{
 		otlptracegrpc.WithEndpoint(fmt.Sprintf("%s:%s", host, port)),
-		otlptracegrpc.WithHeaders(c.Headers),
+		otlptracegrpc.WithHeaders(headers),
 		otlptracegrpc.WithCompressor(gzip.Name),
 	}
 
-	if c.Insecure {
+	if c.GRPC.Insecure {
 		opts = append(opts, otlptracegrpc.WithInsecure())
 	}
 
-	if c.TLS != nil {
-		tlsConfig, err := c.TLS.CreateTLSConfig(context.Background())
+	if c.GRPC.TLS != nil {
+		tlsConfig, err := c.GRPC.TLS.CreateTLSConfig(context.Background())
 		if err != nil {
 			return nil, fmt.Errorf("creating TLS client config: %w", err)
 		}
@@ -148,6 +172,13 @@ type tpCloser struct {
 	provider *sdktrace.TracerProvider
 }
 
-func (t tpCloser) Close() error {
-	return t.provider.Shutdown(context.Background())
+func (t *tpCloser) Close() error {
+	if t == nil {
+		return nil
+	}
+
+	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
+	defer cancel()
+
+	return t.provider.Shutdown(ctx)
 }
diff --git a/pkg/tracing/operation_name.go b/pkg/tracing/operation_name.go
deleted file mode 100644
index 54e875569e..0000000000
--- a/pkg/tracing/operation_name.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package tracing
-
-import (
-	"crypto/sha256"
-	"encoding/hex"
-	"strings"
-
-	"github.com/rs/zerolog/log"
-)
-
-// TraceNameHashLength defines the number of characters to use from the head of the generated hash.
-const TraceNameHashLength = 8
-
-// OperationNameMaxLengthNumber defines the number of static characters in a Span Trace name:
-// 8 chars for hash + 2 chars for '_'.
-const OperationNameMaxLengthNumber = 10
-
-func generateOperationName(prefix string, parts []string, sep string, spanLimit int) string {
-	name := prefix + " " + strings.Join(parts, sep)
-
-	maxLength := OperationNameMaxLengthNumber + len(prefix) + 1
-
-	if spanLimit > 0 && len(name) > spanLimit {
-		if spanLimit < maxLength {
-			log.Warn().Msgf("SpanNameLimit cannot be lesser than %d: falling back on %d", maxLength, maxLength+3)
-			spanLimit = maxLength + 3
-		}
-
-		limit := (spanLimit - maxLength) / 2
-
-		var fragments []string
-		for _, value := range parts {
-			fragments = append(fragments, truncateString(value, limit))
-		}
-		fragments = append(fragments, computeHash(name))
-
-		name = prefix + " " + strings.Join(fragments, sep)
-	}
-
-	return name
-}
-
-// truncateString reduces the length of the 'str' argument to 'num' - 3 and adds a '...' suffix to the tail.
-func truncateString(str string, num int) string {
-	text := str
-	if len(str) > num {
-		if num > 3 {
-			num -= 3
-		}
-		text = str[0:num] + "..."
-	}
-	return text
-}
-
-// computeHash returns the first TraceNameHashLength character of the sha256 hash for 'name' argument.
-func computeHash(name string) string {
-	data := []byte(name)
-	hash := sha256.New()
-	if _, err := hash.Write(data); err != nil {
-		// Impossible case
-		log.Error().Str("OperationName", name).Err(err).Msgf("Failed to create Span name hash for %s", name)
-	}
-
-	return hex.EncodeToString(hash.Sum(nil))[:TraceNameHashLength]
-}
diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go
index d8923f510d..6bb3829202 100644
--- a/pkg/tracing/tracing.go
+++ b/pkg/tracing/tracing.go
@@ -2,182 +2,213 @@ package tracing
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"io"
+	"net"
 	"net/http"
+	"strconv"
 
-	"github.com/opentracing/opentracing-go"
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/rs/zerolog/log"
+	"github.com/traefik/traefik/v3/pkg/config/static"
+	"github.com/traefik/traefik/v3/pkg/tracing/opentelemetry"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/propagation"
+	semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
+	"go.opentelemetry.io/otel/trace"
 )
 
-type contextKey int
-
-const (
-	// SpanKindNoneEnum Span kind enum none.
-	SpanKindNoneEnum ext.SpanKindEnum = "none"
-	tracingKey       contextKey       = iota
-)
-
-// WithTracing Adds Tracing into the context.
-func WithTracing(ctx context.Context, tracing *Tracing) context.Context {
-	return context.WithValue(ctx, tracingKey, tracing)
+// Backend is an abstraction for tracking backend (OpenTelemetry, ...).
+type Backend interface {
+	Setup(serviceName string, sampleRate float64, globalAttributes map[string]string, headers map[string]string) (trace.Tracer, io.Closer, error)
 }
 
-// FromContext Gets Tracing from context.
-func FromContext(ctx context.Context) (*Tracing, error) {
-	if ctx == nil {
-		panic("nil context")
+// NewTracing Creates a Tracing.
+func NewTracing(conf *static.Tracing) (trace.Tracer, io.Closer, error) {
+	var backend Backend
+
+	if conf.OTLP != nil {
+		backend = conf.OTLP
 	}
 
-	tracer, ok := ctx.Value(tracingKey).(*Tracing)
-	if !ok {
-		return nil, errors.New("unable to find tracing in the context")
+	if backend == nil {
+		log.Debug().Msg("Could not initialize tracing, using OpenTelemetry by default")
+		defaultBackend := &opentelemetry.Config{}
+		backend = defaultBackend
 	}
-	return tracer, nil
+
+	return backend.Setup(conf.ServiceName, conf.SampleRate, conf.GlobalAttributes, conf.Headers)
 }
 
-// Backend is an abstraction for tracking backend (Jaeger, Zipkin, ...).
-type Backend interface {
-	Setup(componentName string) (opentracing.Tracer, io.Closer, error)
+// TracerFromContext extracts the trace.Tracer from the given context.
+func TracerFromContext(ctx context.Context) trace.Tracer {
+	span := trace.SpanFromContext(ctx)
+	if span != nil && span.TracerProvider() != nil {
+		return span.TracerProvider().Tracer("github.com/traefik/traefik")
+	}
+
+	return nil
 }
 
-// Tracing middleware.
-type Tracing struct {
-	ServiceName   string `description:"Sets the name for this service" export:"true"`
-	SpanNameLimit int    `description:"Sets the maximum character limit for span names (default 0 = no limit)" export:"true"`
+// ExtractCarrierIntoContext reads cross-cutting concerns from the carrier into a Context.
+func ExtractCarrierIntoContext(ctx context.Context, headers http.Header) context.Context {
+	propagator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
+	return propagator.Extract(ctx, propagation.HeaderCarrier(headers))
+}
 
-	tracer opentracing.Tracer
-	closer io.Closer
+// InjectContextIntoCarrier sets cross-cutting concerns from the request context into the request headers.
+func InjectContextIntoCarrier(req *http.Request) {
+	propagator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
+	propagator.Inject(req.Context(), propagation.HeaderCarrier(req.Header))
 }
 
-// NewTracing Creates a Tracing.
-func NewTracing(serviceName string, spanNameLimit int, tracingBackend Backend) (*Tracing, error) {
-	tracing := &Tracing{
-		ServiceName:   serviceName,
-		SpanNameLimit: spanNameLimit,
+// SetStatusErrorf flags the span as in error and log an event.
+func SetStatusErrorf(ctx context.Context, format string, args ...interface{}) {
+	if span := trace.SpanFromContext(ctx); span != nil {
+		span.SetStatus(codes.Error, fmt.Sprintf(format, args...))
 	}
+}
 
-	var err error
-	tracing.tracer, tracing.closer, err = tracingBackend.Setup(serviceName)
-	if err != nil {
-		return nil, err
+// LogClientRequest used to add span attributes from the request as a Client.
+// TODO: the semconv does not implement Semantic Convention v1.23.0.
+func LogClientRequest(span trace.Span, r *http.Request) {
+	if r == nil || span == nil {
+		return
 	}
-	return tracing, nil
-}
 
-// StartSpan delegates to opentracing.Tracer.
-func (t *Tracing) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
-	return t.tracer.StartSpan(operationName, opts...)
-}
+	// Common attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes
+	span.SetAttributes(semconv.HTTPRequestMethodKey.String(r.Method))
+	span.SetAttributes(semconv.NetworkProtocolVersion(proto(r.Proto)))
 
-// StartSpanf delegates to StartSpan.
-func (t *Tracing) StartSpanf(r *http.Request, spanKind ext.SpanKindEnum, opPrefix string, opParts []string, separator string, opts ...opentracing.StartSpanOption) (opentracing.Span, *http.Request, func()) {
-	operationName := generateOperationName(opPrefix, opParts, separator, t.SpanNameLimit)
+	// Client attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#http-client
+	span.SetAttributes(semconv.URLFull(r.URL.String()))
+	span.SetAttributes(semconv.URLScheme(r.URL.Scheme))
+	span.SetAttributes(semconv.UserAgentOriginal(r.UserAgent()))
 
-	return StartSpan(r, operationName, spanKind, opts...)
+	host, port, err := net.SplitHostPort(r.URL.Host)
+	if err != nil {
+		span.SetAttributes(attribute.String("network.peer.address", host))
+		span.SetAttributes(semconv.ServerAddress(r.URL.Host))
+		switch r.URL.Scheme {
+		case "http":
+			span.SetAttributes(attribute.String("network.peer.port", "80"))
+			span.SetAttributes(semconv.ServerPort(80))
+		case "https":
+			span.SetAttributes(attribute.String("network.peer.port", "443"))
+			span.SetAttributes(semconv.ServerPort(443))
+		}
+	} else {
+		span.SetAttributes(attribute.String("network.peer.address", host))
+		span.SetAttributes(attribute.String("network.peer.port", port))
+		intPort, _ := strconv.Atoi(port)
+		span.SetAttributes(semconv.ServerAddress(host))
+		span.SetAttributes(semconv.ServerPort(intPort))
+	}
 }
 
-// Inject delegates to opentracing.Tracer.
-func (t *Tracing) Inject(sm opentracing.SpanContext, format, carrier interface{}) error {
-	return t.tracer.Inject(sm, format, carrier)
-}
+// LogServerRequest used to add span attributes from the request as a Server.
+// TODO: the semconv does not implement Semantic Convention v1.23.0.
+func LogServerRequest(span trace.Span, r *http.Request) {
+	if r == nil {
+		return
+	}
 
-// Extract delegates to opentracing.Tracer.
-func (t *Tracing) Extract(format, carrier interface{}) (opentracing.SpanContext, error) {
-	return t.tracer.Extract(format, carrier)
-}
+	// Common attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes
+	span.SetAttributes(semconv.HTTPRequestMethodKey.String(r.Method))
+	span.SetAttributes(semconv.NetworkProtocolVersion(proto(r.Proto)))
 
-// IsEnabled determines if tracing was successfully activated.
-func (t *Tracing) IsEnabled() bool {
-	return t != nil && t.tracer != nil
-}
+	// Server attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#http-server-semantic-conventions
+	span.SetAttributes(semconv.HTTPRequestBodySize(int(r.ContentLength)))
+	span.SetAttributes(semconv.URLPath(r.URL.Path))
+	span.SetAttributes(semconv.URLQuery(r.URL.RawQuery))
+	span.SetAttributes(semconv.URLScheme(r.Header.Get("X-Forwarded-Proto")))
+	span.SetAttributes(semconv.UserAgentOriginal(r.UserAgent()))
+	span.SetAttributes(semconv.ServerAddress(r.Host))
 
-// Close tracer.
-func (t *Tracing) Close() {
-	if t.closer != nil {
-		err := t.closer.Close()
-		if err != nil {
-			log.Warn().Err(err).Send()
-		}
+	host, port, err := net.SplitHostPort(r.RemoteAddr)
+	if err != nil {
+		span.SetAttributes(semconv.ClientAddress(r.RemoteAddr))
+		span.SetAttributes(attribute.String("network.peer.address", r.RemoteAddr))
+	} else {
+		span.SetAttributes(attribute.String("network.peer.address", host))
+		span.SetAttributes(attribute.String("network.peer.port", port))
+		span.SetAttributes(semconv.ClientAddress(host))
+		intPort, _ := strconv.Atoi(port)
+		span.SetAttributes(semconv.ClientPort(intPort))
 	}
+
+	span.SetAttributes(semconv.ClientSocketAddress(r.Header.Get("X-Forwarded-For")))
 }
 
-// LogRequest used to create span tags from the request.
-func LogRequest(span opentracing.Span, r *http.Request) {
-	if span != nil && r != nil {
-		ext.HTTPMethod.Set(span, r.Method)
-		ext.HTTPUrl.Set(span, r.URL.String())
-		span.SetTag("http.host", r.Host)
+func proto(proto string) string {
+	switch proto {
+	case "HTTP/1.0":
+		return "1.0"
+	case "HTTP/1.1":
+		return "1.1"
+	case "HTTP/2":
+		return "2"
+	case "HTTP/3":
+		return "3"
+	default:
+		return proto
 	}
 }
 
 // LogResponseCode used to log response code in span.
-func LogResponseCode(span opentracing.Span, code int) {
+func LogResponseCode(span trace.Span, code int, spanKind trace.SpanKind) {
 	if span != nil {
-		ext.HTTPStatusCode.Set(span, uint16(code))
-		if code >= http.StatusInternalServerError {
-			ext.Error.Set(span, true)
+		var status codes.Code
+		var desc string
+		switch spanKind {
+		case trace.SpanKindServer:
+			status, desc = ServerStatus(code)
+		case trace.SpanKindClient:
+			status, desc = ClientStatus(code)
+		default:
+			status, desc = DefaultStatus(code)
 		}
-	}
-}
-
-// GetSpan used to retrieve span from request context.
-func GetSpan(r *http.Request) opentracing.Span {
-	return opentracing.SpanFromContext(r.Context())
-}
-
-// InjectRequestHeaders used to inject OpenTracing headers into the request.
-func InjectRequestHeaders(r *http.Request) {
-	if span := GetSpan(r); span != nil {
-		err := opentracing.GlobalTracer().Inject(
-			span.Context(),
-			opentracing.HTTPHeaders,
-			opentracing.HTTPHeadersCarrier(r.Header))
-		if err != nil {
-			log.Ctx(r.Context()).Error().Err(err).Send()
+		span.SetStatus(status, desc)
+		if code > 0 {
+			span.SetAttributes(semconv.HTTPResponseStatusCode(code))
 		}
 	}
 }
 
-// LogEventf logs an event to the span in the request context.
-func LogEventf(r *http.Request, format string, args ...interface{}) {
-	if span := GetSpan(r); span != nil {
-		span.LogKV("event", fmt.Sprintf(format, args...))
+// ServerStatus returns a span status code and message for an HTTP status code
+// value returned by a server. Status codes in the 400-499 range are not
+// returned as errors.
+func ServerStatus(code int) (codes.Code, string) {
+	if code < 100 || code >= 600 {
+		return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code)
 	}
-}
-
-// StartSpan starts a new span from the one in the request context.
-func StartSpan(r *http.Request, operationName string, spanKind ext.SpanKindEnum, opts ...opentracing.StartSpanOption) (opentracing.Span, *http.Request, func()) {
-	span, ctx := opentracing.StartSpanFromContext(r.Context(), operationName, opts...)
-
-	switch spanKind {
-	case ext.SpanKindRPCClientEnum:
-		ext.SpanKindRPCClient.Set(span)
-	case ext.SpanKindRPCServerEnum:
-		ext.SpanKindRPCServer.Set(span)
-	case ext.SpanKindProducerEnum:
-		ext.SpanKindProducer.Set(span)
-	case ext.SpanKindConsumerEnum:
-		ext.SpanKindConsumer.Set(span)
-	default:
-		// noop
+	if code >= 500 {
+		return codes.Error, ""
 	}
-
-	r = r.WithContext(ctx)
-	return span, r, func() { span.Finish() }
+	return codes.Unset, ""
 }
 
-// SetError flags the span associated with this request as in error.
-func SetError(r *http.Request) {
-	if span := GetSpan(r); span != nil {
-		ext.Error.Set(span, true)
+// ClientStatus returns a span status code and message for an HTTP status code
+// value returned by a server. Status codes in the 400-499 range are not
+// returned as errors.
+func ClientStatus(code int) (codes.Code, string) {
+	if code < 100 || code >= 600 {
+		return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code)
+	}
+	if code >= 400 {
+		return codes.Error, ""
 	}
+	return codes.Unset, ""
 }
 
-// SetErrorWithEvent flags the span associated with this request as in error and log an event.
-func SetErrorWithEvent(r *http.Request, format string, args ...interface{}) {
-	SetError(r)
-	LogEventf(r, format, args...)
+// DefaultStatus returns a span status code and message for an HTTP status code
+// value generated internally.
+func DefaultStatus(code int) (codes.Code, string) {
+	if code < 100 || code >= 600 {
+		return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code)
+	}
+	if code >= 500 {
+		return codes.Error, ""
+	}
+	return codes.Unset, ""
 }
diff --git a/pkg/tracing/zipkin/zipkin.go b/pkg/tracing/zipkin/zipkin.go
deleted file mode 100644
index 598f38037d..0000000000
--- a/pkg/tracing/zipkin/zipkin.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package zipkin
-
-import (
-	"io"
-	"time"
-
-	"github.com/opentracing/opentracing-go"
-	zipkinot "github.com/openzipkin-contrib/zipkin-go-opentracing"
-	"github.com/openzipkin/zipkin-go"
-	"github.com/openzipkin/zipkin-go/reporter/http"
-	"github.com/rs/zerolog/log"
-)
-
-// Name sets the name of this tracer.
-const Name = "zipkin"
-
-// Config provides configuration settings for a zipkin tracer.
-type Config struct {
-	HTTPEndpoint string  `description:"Sets the HTTP Endpoint to report traces to." json:"httpEndpoint,omitempty" toml:"httpEndpoint,omitempty" yaml:"httpEndpoint,omitempty"`
-	SameSpan     bool    `description:"Uses SameSpan RPC style traces." json:"sameSpan,omitempty" toml:"sameSpan,omitempty" yaml:"sameSpan,omitempty" export:"true"`
-	ID128Bit     bool    `description:"Uses 128 bits root span IDs." json:"id128Bit,omitempty" toml:"id128Bit,omitempty" yaml:"id128Bit,omitempty" export:"true"`
-	SampleRate   float64 `description:"Sets the rate between 0.0 and 1.0 of requests to trace." json:"sampleRate,omitempty" toml:"sampleRate,omitempty" yaml:"sampleRate,omitempty" export:"true"`
-}
-
-// SetDefaults sets the default values.
-func (c *Config) SetDefaults() {
-	c.HTTPEndpoint = "http://localhost:9411/api/v2/spans"
-	c.SameSpan = false
-	c.ID128Bit = true
-	c.SampleRate = 1.0
-}
-
-// Setup sets up the tracer.
-func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) {
-	// create our local endpoint
-	endpoint, err := zipkin.NewEndpoint(serviceName, "0.0.0.0:0")
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// create our sampler
-	sampler, err := zipkin.NewBoundarySampler(c.SampleRate, time.Now().Unix())
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// create the span reporter
-	reporter := http.NewReporter(c.HTTPEndpoint)
-
-	// create the native Zipkin tracer
-	nativeTracer, err := zipkin.NewTracer(
-		reporter,
-		zipkin.WithLocalEndpoint(endpoint),
-		zipkin.WithSharedSpans(c.SameSpan),
-		zipkin.WithTraceID128Bit(c.ID128Bit),
-		zipkin.WithSampler(sampler),
-	)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// wrap the Zipkin native tracer with the OpenTracing Bridge
-	tracer := zipkinot.Wrap(nativeTracer)
-
-	// Without this, child spans are getting the NOOP tracer
-	opentracing.SetGlobalTracer(tracer)
-
-	log.Debug().Msg("Zipkin tracer configured")
-
-	return tracer, reporter, nil
-}


Test patch:
diff --git a/integration/tracing_test.go b/integration/tracing_test.go
index f2a1f29ad3..328b63d172 100644
--- a/integration/tracing_test.go
+++ b/integration/tracing_test.go
@@ -1,20 +1,26 @@
 package integration
 
 import (
+	"encoding/json"
+	"io"
 	"net/http"
+	"net/url"
 	"os"
+	"strings"
 	"time"
 
 	"github.com/go-check/check"
+	"github.com/tidwall/gjson"
 	"github.com/traefik/traefik/v3/integration/try"
 	checker "github.com/vdemeester/shakers"
 )
 
 type TracingSuite struct {
 	BaseSuite
-	whoamiIP   string
-	whoamiPort int
-	tracerIP   string
+	whoamiIP        string
+	whoamiPort      int
+	tempoIP         string
+	otelCollectorIP string
 }
 
 type TracingTemplate struct {
@@ -22,39 +28,52 @@ type TracingTemplate struct {
 	WhoamiPort             int
 	IP                     string
 	TraceContextHeaderName string
+	IsHTTP                 bool
 }
 
 func (s *TracingSuite) SetUpSuite(c *check.C) {
 	s.createComposeProject(c, "tracing")
 	s.composeUp(c)
+}
+
+func (s *TracingSuite) SetUpTest(c *check.C) {
+	s.composeUp(c, "tempo", "otel-collector", "whoami")
 
 	s.whoamiIP = s.getComposeServiceIP(c, "whoami")
 	s.whoamiPort = 80
-}
 
-func (s *TracingSuite) startZipkin(c *check.C) {
-	s.composeUp(c, "zipkin")
-	s.tracerIP = s.getComposeServiceIP(c, "zipkin")
+	// Wait for whoami to turn ready.
+	err := try.GetRequest("http://"+s.whoamiIP+":80", 30*time.Second, try.StatusCodeIs(http.StatusOK))
+	c.Assert(err, checker.IsNil)
+
+	s.tempoIP = s.getComposeServiceIP(c, "tempo")
+
+	// Wait for tempo to turn ready.
+	err = try.GetRequest("http://"+s.tempoIP+":3200/ready", 30*time.Second, try.StatusCodeIs(http.StatusOK))
+	c.Assert(err, checker.IsNil)
+
+	s.otelCollectorIP = s.getComposeServiceIP(c, "otel-collector")
 
-	// Wait for Zipkin to turn ready.
-	err := try.GetRequest("http://"+s.tracerIP+":9411/api/v2/services", 20*time.Second, try.StatusCodeIs(http.StatusOK))
+	// Wait for otel collector to turn ready.
+	err = try.GetRequest("http://"+s.otelCollectorIP+":13133/", 30*time.Second, try.StatusCodeIs(http.StatusOK))
 	c.Assert(err, checker.IsNil)
 }
 
-func (s *TracingSuite) TestZipkinRateLimit(c *check.C) {
-	s.startZipkin(c)
-	// defer s.composeStop(c, "zipkin")
+func (s *TracingSuite) TearDownTest(c *check.C) {
+	s.composeStop(c, "tempo")
+}
 
-	file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{
+func (s *TracingSuite) TestOpentelemetryBasic_HTTP(c *check.C) {
+	file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
 		WhoamiIP:   s.whoamiIP,
 		WhoamiPort: s.whoamiPort,
-		IP:         s.tracerIP,
+		IP:         s.otelCollectorIP,
+		IsHTTP:     true,
 	})
 	defer os.Remove(file)
 
 	cmd, display := s.traefikCmd(withConfigFile(file))
 	defer display(c)
-
 	err := cmd.Start()
 	c.Assert(err, checker.IsNil)
 	defer s.killCmd(cmd)
@@ -63,44 +82,46 @@ func (s *TracingSuite) TestZipkinRateLimit(c *check.C) {
 	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
 	c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
-	c.Assert(err, checker.IsNil)
-	err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
-	c.Assert(err, checker.IsNil)
-	err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests))
+	err = try.GetRequest("http://127.0.0.1:8000/basic", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
 	c.Assert(err, checker.IsNil)
 
-	// sleep for 4 seconds to be certain the configured time period has elapsed
-	// then test another request and verify a 200 status code
-	time.Sleep(4 * time.Second)
-	err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
-	c.Assert(err, checker.IsNil)
+	contains := []map[string]string{
+		{
+			"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
 
-	// continue requests at 3 second intervals to test the other rate limit time period
-	time.Sleep(3 * time.Second)
-	err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
-	c.Assert(err, checker.IsNil)
+			"batches.0.scopeSpans.0.spans.0.name":                                                           "EntryPoint",
+			"batches.0.scopeSpans.0.spans.0.kind":                                                           "SPAN_KIND_SERVER",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue":    "GET",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue":            "web",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue":               "/basic",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
 
-	time.Sleep(3 * time.Second)
-	err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
-	c.Assert(err, checker.IsNil)
+			"batches.0.scopeSpans.0.spans.1.name":                                                         "Router",
+			"batches.0.scopeSpans.0.spans.1.kind":                                                         "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue":  "router0@file",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
 
-	time.Sleep(3 * time.Second)
-	err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests))
-	c.Assert(err, checker.IsNil)
+			"batches.0.scopeSpans.0.spans.2.name": "Service",
+			"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
 
-	err = try.GetRequest("http://"+s.tracerIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service1/router1@file", "ratelimit-1@file"))
-	c.Assert(err, checker.IsNil)
-}
+			"batches.0.scopeSpans.0.spans.3.name":                                                           "ReverseProxy",
+			"batches.0.scopeSpans.0.spans.3.kind":                                                           "SPAN_KIND_CLIENT",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"url.scheme\").value.stringValue":             "http",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"user_agent.original\").value.stringValue":    "Go-http-client/1.1",
+		},
+	}
 
-func (s *TracingSuite) TestZipkinRetry(c *check.C) {
-	s.startZipkin(c)
-	defer s.composeStop(c, "zipkin")
+	checkTraceContent(c, s.tempoIP, contains)
+}
 
-	file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{
+func (s *TracingSuite) TestOpentelemetryBasic_gRPC(c *check.C) {
+	file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
 		WhoamiIP:   s.whoamiIP,
-		WhoamiPort: 81,
-		IP:         s.tracerIP,
+		WhoamiPort: s.whoamiPort,
+		IP:         s.otelCollectorIP,
+		IsHTTP:     false,
 	})
 	defer os.Remove(file)
 
@@ -114,59 +135,45 @@ func (s *TracingSuite) TestZipkinRetry(c *check.C) {
 	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
 	c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://127.0.0.1:8000/retry", 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway))
+	err = try.GetRequest("http://127.0.0.1:8000/basic", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
 	c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://"+s.tracerIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service2/router2@file", "retry@file"))
-	c.Assert(err, checker.IsNil)
-}
+	contains := []map[string]string{
+		{
+			"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
 
-func (s *TracingSuite) TestZipkinAuth(c *check.C) {
-	s.startZipkin(c)
-	defer s.composeStop(c, "zipkin")
+			"batches.0.scopeSpans.0.spans.0.name":                                                           "EntryPoint",
+			"batches.0.scopeSpans.0.spans.0.kind":                                                           "SPAN_KIND_SERVER",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue":    "GET",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue":            "web",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue":               "/basic",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
 
-	file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{
-		WhoamiIP:   s.whoamiIP,
-		WhoamiPort: s.whoamiPort,
-		IP:         s.tracerIP,
-	})
-	defer os.Remove(file)
-
-	cmd, display := s.traefikCmd(withConfigFile(file))
-	defer display(c)
-	err := cmd.Start()
-	c.Assert(err, checker.IsNil)
-	defer s.killCmd(cmd)
-
-	// wait for traefik
-	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
-	c.Assert(err, checker.IsNil)
-
-	err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
-	c.Assert(err, checker.IsNil)
+			"batches.0.scopeSpans.0.spans.1.name":                                                         "Router",
+			"batches.0.scopeSpans.0.spans.1.kind":                                                         "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue":  "router0@file",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
 
-	err = try.GetRequest("http://"+s.tracerIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("entrypoint web", "basic-auth@file"))
-	c.Assert(err, checker.IsNil)
-}
+			"batches.0.scopeSpans.0.spans.2.name": "Service",
+			"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
 
-func (s *TracingSuite) startJaeger(c *check.C) {
-	s.composeUp(c, "jaeger", "whoami")
-	s.tracerIP = s.getComposeServiceIP(c, "jaeger")
+			"batches.0.scopeSpans.0.spans.3.name":                                                           "ReverseProxy",
+			"batches.0.scopeSpans.0.spans.3.kind":                                                           "SPAN_KIND_CLIENT",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"url.scheme\").value.stringValue":             "http",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"user_agent.original\").value.stringValue":    "Go-http-client/1.1",
+		},
+	}
 
-	// Wait for Jaeger to turn ready.
-	err := try.GetRequest("http://"+s.tracerIP+":16686/api/services", 20*time.Second, try.StatusCodeIs(http.StatusOK))
-	c.Assert(err, checker.IsNil)
+	checkTraceContent(c, s.tempoIP, contains)
 }
 
-func (s *TracingSuite) TestJaegerRateLimit(c *check.C) {
-	s.startJaeger(c)
-	defer s.composeStop(c, "jaeger")
-
-	file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
-		WhoamiIP:               s.whoamiIP,
-		WhoamiPort:             s.whoamiPort,
-		IP:                     s.tracerIP,
-		TraceContextHeaderName: "uber-trace-id",
+func (s *TracingSuite) TestOpentelemetryRateLimit(c *check.C) {
+	file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
+		WhoamiIP:   s.whoamiIP,
+		WhoamiPort: s.whoamiPort,
+		IP:         s.otelCollectorIP,
 	})
 	defer os.Remove(file)
 
@@ -205,19 +212,91 @@ func (s *TracingSuite) TestJaegerRateLimit(c *check.C) {
 	err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests))
 	c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("forward service1/router1@file", "ratelimit-1@file"))
-	c.Assert(err, checker.IsNil)
+	contains := []map[string]string{
+		{
+			"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
+
+			"batches.0.scopeSpans.0.spans.0.name":                                                           "EntryPoint",
+			"batches.0.scopeSpans.0.spans.0.kind":                                                           "SPAN_KIND_SERVER",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue":    "GET",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue":            "web",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue":               "/ratelimit",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
+
+			"batches.0.scopeSpans.0.spans.1.name":                                                         "Router",
+			"batches.0.scopeSpans.0.spans.1.kind":                                                         "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue":  "router1@file",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
+
+			"batches.0.scopeSpans.0.spans.2.name": "Retry",
+			"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
+
+			"batches.0.scopeSpans.0.spans.3.name": "RateLimiter",
+			"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
+
+			"batches.0.scopeSpans.0.spans.4.name": "Service",
+			"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
+
+			"batches.0.scopeSpans.0.spans.5.name":                                                           "ReverseProxy",
+			"batches.0.scopeSpans.0.spans.5.kind":                                                           "SPAN_KIND_CLIENT",
+			"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"url.scheme\").value.stringValue":             "http",
+			"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
+			"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"user_agent.original\").value.stringValue":    "Go-http-client/1.1",
+		},
+		{
+			"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
+
+			"batches.0.scopeSpans.0.spans.0.name":                                                           "EntryPoint",
+			"batches.0.scopeSpans.0.spans.0.kind":                                                           "SPAN_KIND_SERVER",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue":    "GET",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue":            "web",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue":               "/ratelimit",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "429",
+
+			"batches.0.scopeSpans.0.spans.1.name":                                                         "Router",
+			"batches.0.scopeSpans.0.spans.1.kind":                                                         "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue":  "router1@file",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
+
+			"batches.0.scopeSpans.0.spans.2.name": "Retry",
+			"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
+
+			"batches.0.scopeSpans.0.spans.3.name": "RateLimiter",
+			"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
+
+			"batches.0.scopeSpans.0.spans.4.name": "Retry",
+			"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
+			"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.resend_count\").value.intValue":          "1",
+
+			"batches.0.scopeSpans.0.spans.5.name": "RateLimiter",
+			"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
+
+			"batches.0.scopeSpans.0.spans.6.name": "Retry",
+			"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
+			"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"http.resend_count\").value.intValue":          "2",
+
+			"batches.0.scopeSpans.0.spans.7.name": "RateLimiter",
+			"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
+		},
+	}
+
+	checkTraceContent(c, s.tempoIP, contains)
 }
 
-func (s *TracingSuite) TestJaegerRetry(c *check.C) {
-	s.startJaeger(c)
-	defer s.composeStop(c, "jaeger")
-
-	file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
-		WhoamiIP:               s.whoamiIP,
-		WhoamiPort:             81,
-		IP:                     s.tracerIP,
-		TraceContextHeaderName: "uber-trace-id",
+func (s *TracingSuite) TestOpentelemetryRetry(c *check.C) {
+	file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
+		WhoamiIP:   s.whoamiIP,
+		WhoamiPort: 81,
+		IP:         s.otelCollectorIP,
 	})
 	defer os.Remove(file)
 
@@ -234,19 +313,75 @@ func (s *TracingSuite) TestJaegerRetry(c *check.C) {
 	err = try.GetRequest("http://127.0.0.1:8000/retry", 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway))
 	c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("forward service2/router2@file", "retry@file"))
-	c.Assert(err, checker.IsNil)
+	contains := []map[string]string{
+		{
+			"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
+
+			"batches.0.scopeSpans.0.spans.0.name":                                                           "EntryPoint",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue":    "GET",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue":               "/retry",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
+			"batches.0.scopeSpans.0.spans.0.status.code":                                                    "STATUS_CODE_ERROR",
+
+			"batches.0.scopeSpans.0.spans.1.name": "Router",
+			"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue":  "router2@file",
+
+			"batches.0.scopeSpans.0.spans.2.name": "Retry",
+			"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
+
+			"batches.0.scopeSpans.0.spans.3.name": "Service",
+			"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
+
+			"batches.0.scopeSpans.0.spans.4.name":                                                           "ReverseProxy",
+			"batches.0.scopeSpans.0.spans.4.kind":                                                           "SPAN_KIND_CLIENT",
+			"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"url.scheme\").value.stringValue":             "http",
+			"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
+			"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"user_agent.original\").value.stringValue":    "Go-http-client/1.1",
+
+			"batches.0.scopeSpans.0.spans.5.name": "Retry",
+			"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
+			"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.resend_count\").value.intValue":          "1",
+
+			"batches.0.scopeSpans.0.spans.6.name": "Service",
+			"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
+
+			"batches.0.scopeSpans.0.spans.7.name":                                                           "ReverseProxy",
+			"batches.0.scopeSpans.0.spans.7.kind":                                                           "SPAN_KIND_CLIENT",
+			"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"url.scheme\").value.stringValue":             "http",
+			"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
+			"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"user_agent.original\").value.stringValue":    "Go-http-client/1.1",
+
+			"batches.0.scopeSpans.0.spans.8.name": "Retry",
+			"batches.0.scopeSpans.0.spans.8.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
+			"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.resend_count\").value.intValue":          "2",
+
+			"batches.0.scopeSpans.0.spans.9.name": "Service",
+			"batches.0.scopeSpans.0.spans.9.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.9.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
+
+			"batches.0.scopeSpans.0.spans.10.name":                                                           "ReverseProxy",
+			"batches.0.scopeSpans.0.spans.10.kind":                                                           "SPAN_KIND_CLIENT",
+			"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"url.scheme\").value.stringValue":             "http",
+			"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
+			"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"user_agent.original\").value.stringValue":    "Go-http-client/1.1",
+		},
+	}
+
+	checkTraceContent(c, s.tempoIP, contains)
 }
 
-func (s *TracingSuite) TestJaegerAuth(c *check.C) {
-	s.startJaeger(c)
-	defer s.composeStop(c, "jaeger")
-
-	file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
-		WhoamiIP:               s.whoamiIP,
-		WhoamiPort:             s.whoamiPort,
-		IP:                     s.tracerIP,
-		TraceContextHeaderName: "uber-trace-id",
+func (s *TracingSuite) TestOpentelemetryAuth(c *check.C) {
+	file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
+		WhoamiIP:   s.whoamiIP,
+		WhoamiPort: s.whoamiPort,
+		IP:         s.otelCollectorIP,
 	})
 	defer os.Remove(file)
 
@@ -263,63 +398,101 @@ func (s *TracingSuite) TestJaegerAuth(c *check.C) {
 	err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
 	c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("EntryPoint web", "basic-auth@file"))
-	c.Assert(err, checker.IsNil)
-}
+	contains := []map[string]string{
+		{
+			"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
 
-func (s *TracingSuite) TestJaegerCustomHeader(c *check.C) {
-	s.startJaeger(c)
-	defer s.composeStop(c, "jaeger")
+			"batches.0.scopeSpans.0.spans.0.name":                                                           "EntryPoint",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue":    "GET",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue":               "/auth",
+			"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "401",
 
-	file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
-		WhoamiIP:               s.whoamiIP,
-		WhoamiPort:             s.whoamiPort,
-		IP:                     s.tracerIP,
-		TraceContextHeaderName: "powpow",
-	})
-	defer os.Remove(file)
+			"batches.0.scopeSpans.0.spans.1.name":                                                         "Router",
+			"batches.0.scopeSpans.0.spans.1.kind":                                                         "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue":  "router3@file",
+			"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service3@file",
 
-	cmd, display := s.traefikCmd(withConfigFile(file))
-	defer display(c)
-	err := cmd.Start()
-	c.Assert(err, checker.IsNil)
-	defer s.killCmd(cmd)
+			"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
 
-	// wait for traefik
-	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
+			"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
+			"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "basic-auth@file",
+		},
+	}
+
+	checkTraceContent(c, s.tempoIP, contains)
+}
+
+func checkTraceContent(c *check.C, tempoIP string, expectedJSON []map[string]string) {
+	baseURL, err := url.Parse("http://" + tempoIP + ":3200/api/search")
 	c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
+	req := &http.Request{
+		Method: http.MethodGet,
+		URL:    baseURL,
+	}
+	// Wait for traces to be available.
+	time.Sleep(10 * time.Second)
+	resp, err := try.Response(req, 5*time.Second)
 	c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("EntryPoint web", "basic-auth@file"))
+	out := &TraceResponse{}
+	content, err := io.ReadAll(resp.Body)
+	c.Assert(err, checker.IsNil)
+	err = json.Unmarshal(content, &out)
 	c.Assert(err, checker.IsNil)
-}
 
-func (s *TracingSuite) TestJaegerAuthCollector(c *check.C) {
-	s.startJaeger(c)
-	defer s.composeStop(c, "jaeger")
+	if len(out.Traces) == 0 {
+		c.Fatalf("expected at least one trace, got %d (%s)", len(out.Traces), string(content))
+	}
 
-	file := s.adaptFile(c, "fixtures/tracing/simple-jaeger-collector.toml", TracingTemplate{
-		WhoamiIP:   s.whoamiIP,
-		WhoamiPort: s.whoamiPort,
-		IP:         s.tracerIP,
-	})
-	defer os.Remove(file)
+	var contents []string
+	for _, t := range out.Traces {
+		baseURL, err := url.Parse("http://" + tempoIP + ":3200/api/traces/" + t.TraceID)
+		c.Assert(err, checker.IsNil)
 
-	cmd, display := s.traefikCmd(withConfigFile(file))
-	defer display(c)
-	err := cmd.Start()
-	c.Assert(err, checker.IsNil)
-	defer s.killCmd(cmd)
+		req := &http.Request{
+			Method: http.MethodGet,
+			URL:    baseURL,
+		}
 
-	// wait for traefik
-	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
-	c.Assert(err, checker.IsNil)
+		resp, err := try.Response(req, 5*time.Second)
+		c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
-	c.Assert(err, checker.IsNil)
+		content, err := io.ReadAll(resp.Body)
+		c.Assert(err, checker.IsNil)
 
-	err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("EntryPoint web", "basic-auth@file"))
-	c.Assert(err, checker.IsNil)
+		contents = append(contents, string(content))
+	}
+
+	for _, expected := range expectedJSON {
+		containsAll(c, expected, contents)
+	}
+}
+
+func containsAll(c *check.C, expectedJSON map[string]string, contents []string) {
+	for k, v := range expectedJSON {
+		found := false
+		for _, content := range contents {
+			if gjson.Get(content, k).String() == v {
+				found = true
+				break
+			}
+		}
+
+		if !found {
+			c.Log("[" + strings.Join(contents, ",") + "]")
+			c.Errorf("missing element: \nKey: %q\nValue: %q ", k, v)
+		}
+	}
+}
+
+// TraceResponse contains a list of traces.
+type TraceResponse struct {
+	Traces []Trace `json:"traces"`
+}
+
+// Trace represents a simplified grafana tempo trace.
+type Trace struct {
+	TraceID string `json:"traceID"`
 }
diff --git a/pkg/api/handler_overview_test.go b/pkg/api/handler_overview_test.go
index 0e0165904a..3e8743a81e 100644
--- a/pkg/api/handler_overview_test.go
+++ b/pkg/api/handler_overview_test.go
@@ -18,7 +18,6 @@ import (
 	"github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd"
 	"github.com/traefik/traefik/v3/pkg/provider/kubernetes/ingress"
 	"github.com/traefik/traefik/v3/pkg/provider/rest"
-	"github.com/traefik/traefik/v3/pkg/tracing/jaeger"
 	"github.com/traefik/traefik/v3/pkg/types"
 )
 
@@ -259,9 +258,7 @@ func TestHandler_Overview(t *testing.T) {
 				Metrics: &types.Metrics{
 					Prometheus: &types.Prometheus{},
 				},
-				Tracing: &static.Tracing{
-					Jaeger: &jaeger.Config{},
-				},
+				Tracing: &static.Tracing{},
 			},
 			confDyn: runtime.Configuration{},
 			expected: expected{
diff --git a/pkg/api/testdata/overview-features.json b/pkg/api/testdata/overview-features.json
index 5df280da09..a3db11a751 100644
--- a/pkg/api/testdata/overview-features.json
+++ b/pkg/api/testdata/overview-features.json
@@ -2,7 +2,7 @@
 	"features": {
 		"accessLog": false,
 		"metrics": "Prometheus",
-		"tracing": "Jaeger"
+		"tracing": ""
 	},
 	"http": {
 		"middlewares": {
diff --git a/pkg/logs/haystack_test.go b/pkg/logs/haystack_test.go
deleted file mode 100644
index a6342bd99f..0000000000
--- a/pkg/logs/haystack_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package logs
-
-import (
-	"bytes"
-	"os"
-	"testing"
-	"time"
-
-	"github.com/rs/zerolog"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestNewHaystackLogger(t *testing.T) {
-	buf := bytes.NewBuffer(nil)
-	cwb := zerolog.ConsoleWriter{Out: buf, TimeFormat: time.RFC3339, NoColor: true}
-
-	out := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}, cwb)
-
-	logger := NewHaystackLogger(zerolog.New(out).With().Caller().Logger())
-
-	logger.Info("foo")
-
-	assert.Equal(t, "<nil> INF haystack_test.go:21 > foo\n", buf.String())
-}
diff --git a/pkg/logs/jaeger_test.go b/pkg/logs/jaeger_test.go
deleted file mode 100644
index 7ab6fe53d4..0000000000
--- a/pkg/logs/jaeger_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package logs
-
-import (
-	"bytes"
-	"os"
-	"testing"
-	"time"
-
-	"github.com/rs/zerolog"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestNewJaegerLogger(t *testing.T) {
-	buf := bytes.NewBuffer(nil)
-	cwb := zerolog.ConsoleWriter{Out: buf, TimeFormat: time.RFC3339, NoColor: true}
-
-	out := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}, cwb)
-
-	logger := NewJaegerLogger(zerolog.New(out).With().Caller().Logger())
-
-	logger.Infof("foo")
-
-	assert.Equal(t, "<nil> DBG jaeger_test.go:21 > foo\n", buf.String())
-}
diff --git a/pkg/middlewares/auth/forward_test.go b/pkg/middlewares/auth/forward_test.go
index 0f300fc71e..e3afd68826 100644
--- a/pkg/middlewares/auth/forward_test.go
+++ b/pkg/middlewares/auth/forward_test.go
@@ -8,15 +8,22 @@ import (
 	"net/http/httptest"
 	"testing"
 
-	"github.com/opentracing/opentracing-go"
-	"github.com/opentracing/opentracing-go/mocktracer"
+	"github.com/containous/alice"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
+	"github.com/traefik/traefik/v3/pkg/config/static"
 	tracingMiddleware "github.com/traefik/traefik/v3/pkg/middlewares/tracing"
 	"github.com/traefik/traefik/v3/pkg/testhelpers"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"github.com/traefik/traefik/v3/pkg/tracing/opentelemetry"
+	"github.com/traefik/traefik/v3/pkg/version"
 	"github.com/vulcand/oxy/v2/forward"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/sdk/resource"
+	sdktrace "go.opentelemetry.io/otel/sdk/trace"
+	"go.opentelemetry.io/otel/sdk/trace/tracetest"
+	semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
 )
 
 func TestForwardAuthFail(t *testing.T) {
@@ -452,8 +459,8 @@ func Test_writeHeader(t *testing.T) {
 
 func TestForwardAuthUsesTracing(t *testing.T) {
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if r.Header.Get("Mockpfx-Ids-Traceid") == "" {
-			t.Errorf("expected Mockpfx-Ids-Traceid header to be present in request")
+		if r.Header.Get("Traceparent") == "" {
+			t.Errorf("expected Traceparent header to be present in request")
 		}
 	}))
 	t.Cleanup(server.Close)
@@ -464,15 +471,44 @@ func TestForwardAuthUsesTracing(t *testing.T) {
 		Address: server.URL,
 	}
 
-	tracer := mocktracer.New()
-	opentracing.SetGlobalTracer(tracer)
+	exporter := tracetest.NewInMemoryExporter()
 
-	tr, _ := tracing.NewTracing("testApp", 100, &mockBackend{tracer})
+	tres, err := resource.New(context.Background(),
+		resource.WithAttributes(semconv.ServiceNameKey.String("traefik")),
+		resource.WithAttributes(semconv.ServiceVersionKey.String(version.Version)),
+		resource.WithFromEnv(),
+		resource.WithTelemetrySDK(),
+	)
+	require.NoError(t, err)
+
+	tracerProvider := sdktrace.NewTracerProvider(
+		sdktrace.WithSampler(sdktrace.AlwaysSample()),
+		sdktrace.WithResource(tres),
+		sdktrace.WithBatcher(exporter),
+	)
+	otel.SetTracerProvider(tracerProvider)
+
+	config := &static.Tracing{
+		ServiceName: "testApp",
+		SampleRate:  1,
+		OTLP: &opentelemetry.Config{
+			HTTP: &opentelemetry.HTTP{
+				Endpoint: "http://127.0.0.1:8080",
+			},
+		},
+	}
+	tr, closer, err := tracing.NewTracing(config)
+	require.NoError(t, err)
+	t.Cleanup(func() {
+		_ = closer.Close()
+	})
 
-	next, err := NewForward(context.Background(), next, auth, "authTest")
+	next, err = NewForward(context.Background(), next, auth, "authTest")
 	require.NoError(t, err)
 
-	next = tracingMiddleware.NewEntryPoint(context.Background(), tr, "tracingTest", next)
+	chain := alice.New(tracingMiddleware.WrapEntryPointHandler(context.Background(), tr, "tracingTest"))
+	next, err = chain.Then(next)
+	require.NoError(t, err)
 
 	ts := httptest.NewServer(next)
 	t.Cleanup(ts.Close)
@@ -482,11 +518,3 @@ func TestForwardAuthUsesTracing(t *testing.T) {
 	require.NoError(t, err)
 	assert.Equal(t, http.StatusOK, res.StatusCode)
 }
-
-type mockBackend struct {
-	opentracing.Tracer
-}
-
-func (b *mockBackend) Setup(componentName string) (opentracing.Tracer, io.Closer, error) {
-	return b.Tracer, io.NopCloser(nil), nil
-}
diff --git a/pkg/middlewares/headers/headers_test.go b/pkg/middlewares/headers/headers_test.go
index 61cf3779a3..8e365ab544 100644
--- a/pkg/middlewares/headers/headers_test.go
+++ b/pkg/middlewares/headers/headers_test.go
@@ -14,7 +14,7 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/traefik/traefik/v3/pkg/config/dynamic"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/trace"
 )
 
 func TestNew_withoutOptions(t *testing.T) {
@@ -109,10 +109,11 @@ func Test_headers_getTracingInformation(t *testing.T) {
 		name:    "testing",
 	}
 
-	name, trace := mid.GetTracingInformation()
+	name, typeName, spanKind := mid.GetTracingInformation()
 
 	assert.Equal(t, "testing", name)
-	assert.Equal(t, tracing.SpanKindNoneEnum, trace)
+	assert.Equal(t, "Headers", typeName)
+	assert.Equal(t, trace.SpanKindInternal, spanKind)
 }
 
 // This test is an adapted version of net/http/httputil.Test1xxResponses test.
diff --git a/pkg/middlewares/tracing/entrypoint_test.go b/pkg/middlewares/tracing/entrypoint_test.go
index e8528e0484..b3cb60d678 100644
--- a/pkg/middlewares/tracing/entrypoint_test.go
+++ b/pkg/middlewares/tracing/entrypoint_test.go
@@ -6,81 +6,69 @@ import (
 	"net/http/httptest"
 	"testing"
 
-	"github.com/opentracing/opentracing-go/ext"
 	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	"github.com/traefik/traefik/v3/pkg/tracing"
+	"go.opentelemetry.io/otel/attribute"
 )
 
 func TestEntryPointMiddleware(t *testing.T) {
 	type expected struct {
-		Tags          map[string]interface{}
-		OperationName string
+		name       string
+		attributes []attribute.KeyValue
 	}
 
 	testCases := []struct {
-		desc          string
-		entryPoint    string
-		spanNameLimit int
-		tracing       *trackingBackenMock
-		expected      expected
+		desc       string
+		entryPoint string
+		expected   expected
 	}{
 		{
-			desc:          "no truncation test",
-			entryPoint:    "test",
-			spanNameLimit: 0,
-			tracing: &trackingBackenMock{
-				tracer: &MockTracer{Span: &MockSpan{Tags: make(map[string]interface{})}},
-			},
+			desc:       "basic test",
+			entryPoint: "test",
 			expected: expected{
-				Tags: map[string]interface{}{
-					"span.kind":   ext.SpanKindRPCServerEnum,
-					"http.method": http.MethodGet,
-					"component":   "",
-					"http.url":    "http://www.test.com",
-					"http.host":   "www.test.com",
+				name: "EntryPoint",
+				attributes: []attribute.KeyValue{
+					attribute.String("span.kind", "server"),
+					attribute.String("entry_point", "test"),
+					attribute.String("http.request.method", "GET"),
+					attribute.String("network.protocol.version", "1.1"),
+					attribute.Int64("http.request.body.size", int64(0)),
+					attribute.String("url.path", "/search"),
+					attribute.String("url.query", "q=Opentelemetry"),
+					attribute.String("url.scheme", "http"),
+					attribute.String("user_agent.original", "entrypoint-test"),
+					attribute.String("server.address", "www.test.com"),
+					attribute.String("network.peer.address", "10.0.0.1"),
+					attribute.String("network.peer.port", "1234"),
+					attribute.String("client.address", "10.0.0.1"),
+					attribute.Int64("client.port", int64(1234)),
+					attribute.String("client.socket.address", ""),
+					attribute.Int64("http.response.status_code", int64(404)),
 				},
-				OperationName: "EntryPoint test www.test.com",
-			},
-		},
-		{
-			desc:          "basic test",
-			entryPoint:    "test",
-			spanNameLimit: 25,
-			tracing: &trackingBackenMock{
-				tracer: &MockTracer{Span: &MockSpan{Tags: make(map[string]interface{})}},
-			},
-			expected: expected{
-				Tags: map[string]interface{}{
-					"span.kind":   ext.SpanKindRPCServerEnum,
-					"http.method": http.MethodGet,
-					"component":   "",
-					"http.url":    "http://www.test.com",
-					"http.host":   "www.test.com",
-				},
-				OperationName: "EntryPoint te... ww... 0c15301b",
 			},
 		},
 	}
 
 	for _, test := range testCases {
 		t.Run(test.desc, func(t *testing.T) {
-			newTracing, err := tracing.NewTracing("", test.spanNameLimit, test.tracing)
-			require.NoError(t, err)
-
-			req := httptest.NewRequest(http.MethodGet, "http://www.test.com", nil)
+			req := httptest.NewRequest(http.MethodGet, "http://www.test.com/search?q=Opentelemetry", nil)
 			rw := httptest.NewRecorder()
+			req.RemoteAddr = "10.0.0.1:1234"
+			req.Header.Set("User-Agent", "entrypoint-test")
+			req.Header.Set("X-Forwarded-Proto", "http")
 
-			next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
-				span := test.tracing.tracer.(*MockTracer).Span
-
-				tags := span.Tags
-				assert.Equal(t, test.expected.Tags, tags)
-				assert.Equal(t, test.expected.OperationName, span.OpName)
+			next := http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
+				rw.WriteHeader(http.StatusNotFound)
 			})
 
-			handler := NewEntryPoint(context.Background(), newTracing, test.entryPoint, next)
+			tracer := &mockTracer{}
+
+			handler := newEntryPoint(context.Background(), tracer, test.entryPoint, next)
 			handler.ServeHTTP(rw, req)
+
+			for _, span := range tracer.spans {
+				assert.Equal(t, test.expected.name, span.name)
+				assert.Equal(t, test.expected.attributes, span.attributes)
+			}
 		})
 	}
 }
diff --git a/pkg/middlewares/tracing/forwarder_test.go b/pkg/middlewares/tracing/forwarder_test.go
deleted file mode 100644
index e56c475025..0000000000
--- a/pkg/middlewares/tracing/forwarder_test.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package tracing
-
-import (
-	"context"
-	"net/http"
-	"net/http/httptest"
-	"testing"
-
-	"github.com/opentracing/opentracing-go/ext"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	"github.com/traefik/traefik/v3/pkg/tracing"
-)
-
-func TestNewForwarder(t *testing.T) {
-	type expected struct {
-		Tags          map[string]interface{}
-		OperationName string
-	}
-
-	testCases := []struct {
-		desc          string
-		spanNameLimit int
-		tracing       *trackingBackenMock
-		service       string
-		router        string
-		expected      expected
-	}{
-		{
-			desc:          "Simple Forward Tracer without truncation and hashing",
-			spanNameLimit: 101,
-			tracing: &trackingBackenMock{
-				tracer: &MockTracer{Span: &MockSpan{Tags: make(map[string]interface{})}},
-			},
-			service: "some-service.domain.tld",
-			router:  "some-service.domain.tld",
-			expected: expected{
-				Tags: map[string]interface{}{
-					"http.host":            "www.test.com",
-					"http.method":          "GET",
-					"http.url":             "http://www.test.com/toto",
-					"traefik.service.name": "some-service.domain.tld",
-					"traefik.router.name":  "some-service.domain.tld",
-					"span.kind":            ext.SpanKindRPCClientEnum,
-				},
-				OperationName: "forward some-service.domain.tld/some-service.domain.tld",
-			},
-		},
-		{
-			desc:          "Simple Forward Tracer with truncation and hashing",
-			spanNameLimit: 101,
-			tracing: &trackingBackenMock{
-				tracer: &MockTracer{Span: &MockSpan{Tags: make(map[string]interface{})}},
-			},
-			service: "some-service-100.slug.namespace.environment.domain.tld",
-			router:  "some-service-100.slug.namespace.environment.domain.tld",
-			expected: expected{
-				Tags: map[string]interface{}{
-					"http.host":            "www.test.com",
-					"http.method":          "GET",
-					"http.url":             "http://www.test.com/toto",
-					"traefik.service.name": "some-service-100.slug.namespace.environment.domain.tld",
-					"traefik.router.name":  "some-service-100.slug.namespace.environment.domain.tld",
-					"span.kind":            ext.SpanKindRPCClientEnum,
-				},
-				OperationName: "forward some-service-100.slug.namespace.enviro.../some-service-100.slug.namespace.enviro.../bc4a0d48",
-			},
-		},
-		{
-			desc:          "Exactly 101 chars",
-			spanNameLimit: 101,
-			tracing: &trackingBackenMock{
-				tracer: &MockTracer{Span: &MockSpan{Tags: make(map[string]interface{})}},
-			},
-			service: "some-service1.namespace.environment.domain.tld",
-			router:  "some-service1.namespace.environment.domain.tld",
-			expected: expected{
-				Tags: map[string]interface{}{
-					"http.host":            "www.test.com",
-					"http.method":          "GET",
-					"http.url":             "http://www.test.com/toto",
-					"traefik.service.name": "some-service1.namespace.environment.domain.tld",
-					"traefik.router.name":  "some-service1.namespace.environment.domain.tld",
-					"span.kind":            ext.SpanKindRPCClientEnum,
-				},
-				OperationName: "forward some-service1.namespace.environment.domain.tld/some-service1.namespace.environment.domain.tld",
-			},
-		},
-		{
-			desc:          "More than 101 chars",
-			spanNameLimit: 101,
-			tracing: &trackingBackenMock{
-				tracer: &MockTracer{Span: &MockSpan{Tags: make(map[string]interface{})}},
-			},
-			service: "some-service1.frontend.namespace.environment.domain.tld",
-			router:  "some-service1.backend.namespace.environment.domain.tld",
-			expected: expected{
-				Tags: map[string]interface{}{
-					"http.host":            "www.test.com",
-					"http.method":          "GET",
-					"http.url":             "http://www.test.com/toto",
-					"traefik.service.name": "some-service1.frontend.namespace.environment.domain.tld",
-					"traefik.router.name":  "some-service1.backend.namespace.environment.domain.tld",
-					"span.kind":            ext.SpanKindRPCClientEnum,
-				},
-				OperationName: "forward some-service1.frontend.namespace.envir.../some-service1.backend.namespace.enviro.../fa49dd23",
-			},
-		},
-	}
-
-	for _, test := range testCases {
-		t.Run(test.desc, func(t *testing.T) {
-			newTracing, err := tracing.NewTracing("", test.spanNameLimit, test.tracing)
-			require.NoError(t, err)
-
-			req := httptest.NewRequest(http.MethodGet, "http://www.test.com/toto", nil)
-			req = req.WithContext(tracing.WithTracing(req.Context(), newTracing))
-
-			rw := httptest.NewRecorder()
-
-			next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
-				span := test.tracing.tracer.(*MockTracer).Span
-
-				tags := span.Tags
-				assert.Equal(t, test.expected.Tags, tags)
-				assert.LessOrEqual(t, len(test.expected.OperationName), test.spanNameLimit,
-					"the len of the operation name %q [len: %d] doesn't respect limit %d",
-					test.expected.OperationName, len(test.expected.OperationName), test.spanNameLimit)
-				assert.Equal(t, test.expected.OperationName, span.OpName)
-			})
-
-			handler := NewForwarder(context.Background(), test.router, test.service, next)
-			handler.ServeHTTP(rw, req)
-		})
-	}
-}
diff --git a/pkg/middlewares/tracing/mock_tracing_test.go b/pkg/middlewares/tracing/mock_tracing_test.go
index 33aac1ee6c..a44345f6ac 100644
--- a/pkg/middlewares/tracing/mock_tracing_test.go
+++ b/pkg/middlewares/tracing/mock_tracing_test.go
@@ -1,70 +1,62 @@
 package tracing
 
 import (
-	"io"
+	"context"
 
-	"github.com/opentracing/opentracing-go"
-	"github.com/opentracing/opentracing-go/log"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/trace"
+	"go.opentelemetry.io/otel/trace/embedded"
 )
 
-type MockTracer struct {
-	Span *MockSpan
+type mockTracerProvider struct {
+	embedded.TracerProvider
 }
 
-// StartSpan belongs to the Tracer interface.
-func (n MockTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
-	n.Span.OpName = operationName
-	return n.Span
-}
+var _ trace.TracerProvider = mockTracerProvider{}
 
-// Inject belongs to the Tracer interface.
-func (n MockTracer) Inject(sp opentracing.SpanContext, format, carrier interface{}) error {
-	return nil
+func (p mockTracerProvider) Tracer(string, ...trace.TracerOption) trace.Tracer {
+	return &mockTracer{}
 }
 
-// Extract belongs to the Tracer interface.
-func (n MockTracer) Extract(format, carrier interface{}) (opentracing.SpanContext, error) {
-	return nil, opentracing.ErrSpanContextNotFound
-}
+type mockTracer struct {
+	embedded.Tracer
 
-// MockSpanContext a span context mock.
-type MockSpanContext struct{}
+	spans []*mockSpan
+}
 
-func (n MockSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {}
+var _ trace.Tracer = &mockTracer{}
 
-// MockSpan a span mock.
-type MockSpan struct {
-	OpName string
-	Tags   map[string]interface{}
+func (t *mockTracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
+	config := trace.NewSpanStartConfig(opts...)
+	span := &mockSpan{}
+	span.SetName(name)
+	span.SetAttributes(attribute.String("span.kind", config.SpanKind().String()))
+	span.SetAttributes(config.Attributes()...)
+	t.spans = append(t.spans, span)
+	return trace.ContextWithSpan(ctx, span), span
 }
 
-func (n MockSpan) Context() opentracing.SpanContext { return MockSpanContext{} }
-func (n MockSpan) SetBaggageItem(key, val string) opentracing.Span {
-	return MockSpan{Tags: make(map[string]interface{})}
-}
-func (n MockSpan) BaggageItem(key string) string { return "" }
-func (n MockSpan) SetTag(key string, value interface{}) opentracing.Span {
-	n.Tags[key] = value
-	return n
-}
-func (n MockSpan) LogFields(fields ...log.Field)                          {}
-func (n MockSpan) LogKV(keyVals ...interface{})                           {}
-func (n MockSpan) Finish()                                                {}
-func (n MockSpan) FinishWithOptions(opts opentracing.FinishOptions)       {}
-func (n MockSpan) SetOperationName(operationName string) opentracing.Span { return n }
-func (n MockSpan) Tracer() opentracing.Tracer                             { return MockTracer{} }
-func (n MockSpan) LogEvent(event string)                                  {}
-func (n MockSpan) LogEventWithPayload(event string, payload interface{})  {}
-func (n MockSpan) Log(data opentracing.LogData)                           {}
-func (n *MockSpan) Reset() {
-	n.Tags = make(map[string]interface{})
-}
+// mockSpan is an implementation of Span that preforms no operations.
+type mockSpan struct {
+	embedded.Span
 
-type trackingBackenMock struct {
-	tracer opentracing.Tracer
+	name       string
+	attributes []attribute.KeyValue
 }
 
-func (t *trackingBackenMock) Setup(componentName string) (opentracing.Tracer, io.Closer, error) {
-	opentracing.SetGlobalTracer(t.tracer)
-	return t.tracer, nil, nil
+var _ trace.Span = &mockSpan{}
+
+func (*mockSpan) SpanContext() trace.SpanContext     { return trace.SpanContext{} }
+func (*mockSpan) IsRecording() bool                  { return false }
+func (s *mockSpan) SetStatus(_ codes.Code, _ string) {}
+func (s *mockSpan) SetAttributes(kv ...attribute.KeyValue) {
+	s.attributes = append(s.attributes, kv...)
 }
+func (s *mockSpan) End(...trace.SpanEndOption)                  {}
+func (s *mockSpan) RecordError(_ error, _ ...trace.EventOption) {}
+func (s *mockSpan) AddEvent(_ string, _ ...trace.EventOption)   {}
+
+func (s *mockSpan) SetName(name string) { s.name = name }
+
+func (*mockSpan) TracerProvider() trace.TracerProvider { return mockTracerProvider{} }
diff --git a/pkg/middlewares/tracing/router_test.go b/pkg/middlewares/tracing/router_test.go
new file mode 100644
index 0000000000..b220cdabe2
--- /dev/null
+++ b/pkg/middlewares/tracing/router_test.go
@@ -0,0 +1,86 @@
+package tracing
+
+import (
+	"context"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/trace"
+)
+
+func TestNewRouter(t *testing.T) {
+	type expected struct {
+		attributes []attribute.KeyValue
+		name       string
+	}
+
+	testCases := []struct {
+		desc       string
+		service    string
+		router     string
+		routerRule string
+		expected   []expected
+	}{
+		{
+			desc:       "base",
+			service:    "myService",
+			router:     "myRouter",
+			routerRule: "Path(`/`)",
+			expected: []expected{
+				{
+					name: "EntryPoint",
+					attributes: []attribute.KeyValue{
+						attribute.String("span.kind", "server"),
+					},
+				},
+				{
+					name: "Router",
+					attributes: []attribute.KeyValue{
+						attribute.String("span.kind", "internal"),
+						attribute.String("http.request.method", "GET"),
+						attribute.Int64("http.response.status_code", int64(404)),
+						attribute.String("network.protocol.version", "1.1"),
+						attribute.String("server.address", "www.test.com"),
+						attribute.Int64("server.port", int64(80)),
+						attribute.String("url.full", "http://www.test.com/traces?p=OpenTelemetry"),
+						attribute.String("url.scheme", "http"),
+						attribute.String("traefik.service.name", "myService"),
+						attribute.String("traefik.router.name", "myRouter"),
+						attribute.String("http.route", "Path(`/`)"),
+						attribute.String("user_agent.original", "router-test"),
+					},
+				},
+			},
+		},
+	}
+
+	for _, test := range testCases {
+		t.Run(test.desc, func(t *testing.T) {
+			req := httptest.NewRequest(http.MethodGet, "http://www.test.com/traces?p=OpenTelemetry", nil)
+			req.RemoteAddr = "10.0.0.1:1234"
+			req.Header.Set("User-Agent", "router-test")
+
+			tracer := &mockTracer{}
+			tracingCtx, entryPointSpan := tracer.Start(req.Context(), "EntryPoint", trace.WithSpanKind(trace.SpanKindServer))
+			defer entryPointSpan.End()
+
+			req = req.WithContext(tracingCtx)
+
+			rw := httptest.NewRecorder()
+			next := http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
+				rw.WriteHeader(http.StatusNotFound)
+			})
+
+			handler := newRouter(context.Background(), test.router, test.routerRule, test.service, next)
+			handler.ServeHTTP(rw, req)
+
+			for i, span := range tracer.spans {
+				assert.Equal(t, test.expected[i].name, span.name)
+				assert.Equal(t, test.expected[i].attributes, span.attributes)
+			}
+		})
+	}
+}
diff --git a/pkg/middlewares/tracing/service_test.go b/pkg/middlewares/tracing/service_test.go
new file mode 100644
index 0000000000..c78510fafa
--- /dev/null
+++ b/pkg/middlewares/tracing/service_test.go
@@ -0,0 +1,80 @@
+package tracing
+
+import (
+	"context"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/trace"
+)
+
+func TestNewService(t *testing.T) {
+	type expected struct {
+		attributes []attribute.KeyValue
+		name       string
+	}
+
+	testCases := []struct {
+		desc     string
+		service  string
+		expected []expected
+	}{
+		{
+			desc:    "base",
+			service: "myService",
+			expected: []expected{
+				{
+					name: "EntryPoint",
+					attributes: []attribute.KeyValue{
+						attribute.String("span.kind", "server"),
+					},
+				},
+				{
+					name: "Service",
+					attributes: []attribute.KeyValue{
+						attribute.String("span.kind", "internal"),
+						attribute.String("http.request.method", "GET"),
+						attribute.Int64("http.response.status_code", int64(404)),
+						attribute.String("network.protocol.version", "1.1"),
+						attribute.String("server.address", "www.test.com"),
+						attribute.Int64("server.port", int64(80)),
+						attribute.String("url.full", "http://www.test.com/traces?p=OpenTelemetry"),
+						attribute.String("url.scheme", "http"),
+						attribute.String("traefik.service.name", "myService"),
+						attribute.String("user_agent.original", "service-test"),
+					},
+				},
+			},
+		},
+	}
+
+	for _, test := range testCases {
+		t.Run(test.desc, func(t *testing.T) {
+			req := httptest.NewRequest(http.MethodGet, "http://www.test.com/traces?p=OpenTelemetry", nil)
+			req.RemoteAddr = "10.0.0.1:1234"
+			req.Header.Set("User-Agent", "service-test")
+
+			tracer := &mockTracer{}
+			tracingCtx, entryPointSpan := tracer.Start(req.Context(), "EntryPoint", trace.WithSpanKind(trace.SpanKindServer))
+			defer entryPointSpan.End()
+
+			req = req.WithContext(tracingCtx)
+
+			rw := httptest.NewRecorder()
+			next := http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
+				rw.WriteHeader(http.StatusNotFound)
+			})
+
+			handler := NewService(context.Background(), test.service, next)
+			handler.ServeHTTP(rw, req)
+
+			for i, span := range tracer.spans {
+				assert.Equal(t, test.expected[i].name, span.name)
+				assert.Equal(t, test.expected[i].attributes, span.attributes)
+			}
+		})
+	}
+}
diff --git a/pkg/redactor/redactor_config_test.go b/pkg/redactor/redactor_config_test.go
index f785ec72db..0a6b174e9f 100644
--- a/pkg/redactor/redactor_config_test.go
+++ b/pkg/redactor/redactor_config_test.go
@@ -30,12 +30,7 @@ import (
 	"github.com/traefik/traefik/v3/pkg/provider/kv/zk"
 	"github.com/traefik/traefik/v3/pkg/provider/rest"
 	traefiktls "github.com/traefik/traefik/v3/pkg/tls"
-	"github.com/traefik/traefik/v3/pkg/tracing/datadog"
-	"github.com/traefik/traefik/v3/pkg/tracing/elastic"
-	"github.com/traefik/traefik/v3/pkg/tracing/haystack"
-	"github.com/traefik/traefik/v3/pkg/tracing/instana"
-	"github.com/traefik/traefik/v3/pkg/tracing/jaeger"
-	"github.com/traefik/traefik/v3/pkg/tracing/zipkin"
+	"github.com/traefik/traefik/v3/pkg/tracing/opentelemetry"
 	"github.com/traefik/traefik/v3/pkg/types"
 )
 
@@ -850,58 +845,19 @@ func TestDo_staticConfiguration(t *testing.T) {
 	}
 
 	config.Tracing = &static.Tracing{
-		ServiceName:   "myServiceName",
-		SpanNameLimit: 42,
-		Jaeger: &jaeger.Config{
-			SamplingServerURL:      "foobar",
-			SamplingType:           "foobar",
-			SamplingParam:          42,
-			LocalAgentHostPort:     "foobar",
-			Gen128Bit:              true,
-			Propagation:            "foobar",
-			TraceContextHeaderName: "foobar",
-			Collector: &jaeger.Collector{
+		ServiceName: "myServiceName",
+		Headers: map[string]string{
+			"foobar": "foobar",
+		},
+		GlobalAttributes: map[string]string{
+			"foobar": "foobar",
+		},
+		SampleRate: 42,
+		OTLP: &opentelemetry.Config{
+			HTTP: &opentelemetry.HTTP{
 				Endpoint: "foobar",
-				User:     "foobar",
-				Password: "foobar",
-			},
-			DisableAttemptReconnecting: true,
-		},
-		Zipkin: &zipkin.Config{
-			HTTPEndpoint: "foobar",
-			SameSpan:     true,
-			ID128Bit:     true,
-			SampleRate:   42,
-		},
-		Datadog: &datadog.Config{
-			LocalAgentHostPort:         "foobar",
-			LocalAgentSocket:           "foobar",
-			GlobalTags:                 map[string]string{"foobar": "foobar"},
-			Debug:                      true,
-			PrioritySampling:           true,
-			TraceIDHeaderName:          "foobar",
-			ParentIDHeaderName:         "foobar",
-			SamplingPriorityHeaderName: "foobar",
-			BagagePrefixHeaderName:     "foobar",
-		},
-		Instana: &instana.Config{
-			LocalAgentHost: "foobar",
-			LocalAgentPort: 4242,
-			LogLevel:       "foobar",
-		},
-		Haystack: &haystack.Config{
-			LocalAgentHost:          "foobar",
-			LocalAgentPort:          42,
-			GlobalTag:               "foobar",
-			TraceIDHeaderName:       "foobar",
-			ParentIDHeaderName:      "foobar",
-			SpanIDHeaderName:        "foobar",
-			BaggagePrefixHeaderName: "foobar",
-		},
-		Elastic: &elastic.Config{
-			ServerURL:          "foobar",
-			SecretToken:        "foobar",
-			ServiceEnvironment: "foobar",
+				TLS:      nil,
+			},
 		},
 	}
 
diff --git a/pkg/redactor/testdata/anonymized-static-config.json b/pkg/redactor/testdata/anonymized-static-config.json
index a8db724607..97e678c85b 100644
--- a/pkg/redactor/testdata/anonymized-static-config.json
+++ b/pkg/redactor/testdata/anonymized-static-config.json
@@ -344,57 +344,17 @@
   },
   "tracing": {
     "serviceName": "myServiceName",
-    "spanNameLimit": 42,
-    "jaeger": {
-      "samplingServerURL": "xxxx",
-      "samplingType": "foobar",
-      "samplingParam": 42,
-      "localAgentHostPort": "xxxx",
-      "gen128Bit": true,
-      "propagation": "foobar",
-      "traceContextHeaderName": "foobar",
-      "collector": {
-        "endpoint": "xxxx",
-        "user": "xxxx",
-        "password": "xxxx"
-      },
-      "disableAttemptReconnecting": true
-    },
-    "zipkin": {
-      "httpEndpoint": "xxxx",
-      "sameSpan": true,
-      "id128Bit": true,
-      "sampleRate": 42
-    },
-    "datadog": {
-      "localAgentHostPort": "xxxx",
-      "localAgentSocket": "xxxx",
-      "globalTags": {
-        "foobar": "foobar"
-      },
-      "debug": true,
-      "prioritySampling": true,
-      "traceIDHeaderName": "foobar",
-      "parentIDHeaderName": "foobar",
-      "samplingPriorityHeaderName": "foobar",
-      "bagagePrefixHeaderName": "foobar"
-    },
-    "instana": {
-      "localAgentHost": "xxxx",
-      "logLevel": "foobar"
+    "headers": {
+      "foobar": "foobar"
     },
-    "haystack": {
-      "localAgentHost": "xxxx",
-      "globalTag": "foobar",
-      "traceIDHeaderName": "foobar",
-      "parentIDHeaderName": "foobar",
-      "spanIDHeaderName": "foobar",
-      "baggagePrefixHeaderName": "foobar"
+    "globalAttributes": {
+      "foobar": "foobar"
     },
-    "elastic": {
-      "serverURL": "xxxx",
-      "secretToken": "xxxx",
-      "serviceEnvironment": "foobar"
+    "sampleRate": 42,
+    "otlp": {
+      "http": {
+        "endpoint": "xxxx"
+      }
     }
   },
   "hostResolver": {
@@ -447,4 +407,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/tracing/opentelemetry/opentelemetry_test.go b/pkg/tracing/opentelemetry/opentelemetry_test.go
index 40fcca1592..ad7f13a4d9 100644
--- a/pkg/tracing/opentelemetry/opentelemetry_test.go
+++ b/pkg/tracing/opentelemetry/opentelemetry_test.go
@@ -1,4 +1,4 @@
-package opentelemetry
+package opentelemetry_test
 
 import (
 	"compress/gzip"
@@ -7,14 +7,16 @@ import (
 	"io"
 	"net/http"
 	"net/http/httptest"
-	"strings"
 	"testing"
 	"time"
 
+	"github.com/containous/alice"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	mtracing "github.com/traefik/traefik/v3/pkg/middlewares/tracing"
+	"github.com/traefik/traefik/v3/pkg/config/static"
+	tracingMiddle "github.com/traefik/traefik/v3/pkg/middlewares/tracing"
 	"github.com/traefik/traefik/v3/pkg/tracing"
+	"github.com/traefik/traefik/v3/pkg/tracing/opentelemetry"
 	"go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp"
 )
 
@@ -68,14 +70,25 @@ func TestTracing(t *testing.T) {
 	}))
 	t.Cleanup(collector.Close)
 
-	newTracing, err := tracing.NewTracing("", 0, &Config{
-		Insecure: true,
-		Address:  strings.TrimPrefix(collector.URL, "http://"),
-	})
+	tracingConfig := &static.Tracing{
+		ServiceName: "traefik",
+		SampleRate:  1.0,
+		OTLP: &opentelemetry.Config{
+			HTTP: &opentelemetry.HTTP{
+				Endpoint: collector.URL,
+			},
+		},
+	}
+
+	newTracing, closer, err := tracing.NewTracing(tracingConfig)
 	require.NoError(t, err)
-	t.Cleanup(newTracing.Close)
+	t.Cleanup(func() {
+		_ = closer.Close()
+	})
 
-	epHandler := mtracing.NewEntryPoint(context.Background(), newTracing, "test", http.NotFoundHandler())
+	chain := alice.New(tracingMiddle.WrapEntryPointHandler(context.Background(), newTracing, "test"))
+	epHandler, err := chain.Then(http.NotFoundHandler())
+	require.NoError(t, err)
 
 	for _, test := range tests {
 		t.Run(test.desc, func(t *testing.T) {
diff --git a/pkg/tracing/operation_name_test.go b/pkg/tracing/operation_name_test.go
deleted file mode 100644
index 4c9c746bd5..0000000000
--- a/pkg/tracing/operation_name_test.go
+++ /dev/null
@@ -1,135 +0,0 @@
-package tracing
-
-import (
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-func Test_generateOperationName(t *testing.T) {
-	testCases := []struct {
-		desc      string
-		prefix    string
-		parts     []string
-		sep       string
-		spanLimit int
-		expected  string
-	}{
-		{
-			desc:     "empty",
-			expected: " ",
-		},
-		{
-			desc:      "with prefix, without parts",
-			prefix:    "foo",
-			parts:     []string{},
-			sep:       "-",
-			spanLimit: 0,
-			expected:  "foo ",
-		},
-		{
-			desc:      "with prefix, without parts, too small span limit",
-			prefix:    "foo",
-			parts:     []string{},
-			sep:       "-",
-			spanLimit: 1,
-			expected:  "foo 6c2d2c76",
-		},
-		{
-			desc:      "with prefix, with parts",
-			prefix:    "foo",
-			parts:     []string{"fii", "fuu", "fee", "faa"},
-			sep:       "-",
-			spanLimit: 0,
-			expected:  "foo fii-fuu-fee-faa",
-		},
-		{
-			desc:      "with prefix, with parts, with span limit",
-			prefix:    "foo",
-			parts:     []string{"fff", "ooo", "ooo", "bbb", "aaa", "rrr"},
-			sep:       "-",
-			spanLimit: 20,
-			expected:  "foo fff-ooo-ooo-bbb-aaa-rrr-1a8e8ac1",
-		},
-	}
-
-	for _, test := range testCases {
-		test := test
-		t.Run(test.desc, func(t *testing.T) {
-			t.Parallel()
-
-			opName := generateOperationName(test.prefix, test.parts, test.sep, test.spanLimit)
-			assert.Equal(t, test.expected, opName)
-		})
-	}
-}
-
-func TestComputeHash(t *testing.T) {
-	testCases := []struct {
-		desc     string
-		text     string
-		expected string
-	}{
-		{
-			desc:     "hashing",
-			text:     "some very long piece of text",
-			expected: "0c6e798b",
-		},
-		{
-			desc:     "short text less than limit 10",
-			text:     "short",
-			expected: "f9b0078b",
-		},
-	}
-
-	for _, test := range testCases {
-		test := test
-		t.Run(test.desc, func(t *testing.T) {
-			t.Parallel()
-
-			actual := computeHash(test.text)
-
-			assert.Equal(t, test.expected, actual)
-		})
-	}
-}
-
-func TestTruncateString(t *testing.T) {
-	testCases := []struct {
-		desc     string
-		text     string
-		limit    int
-		expected string
-	}{
-		{
-			desc:     "short text less than limit 10",
-			text:     "short",
-			limit:    10,
-			expected: "short",
-		},
-		{
-			desc:     "basic truncate with limit 10",
-			text:     "some very long piece of text",
-			limit:    10,
-			expected: "some ve...",
-		},
-		{
-			desc:     "truncate long FQDN to 39 chars",
-			text:     "some-service-100.slug.namespace.environment.domain.tld",
-			limit:    39,
-			expected: "some-service-100.slug.namespace.envi...",
-		},
-	}
-
-	for _, test := range testCases {
-		test := test
-		t.Run(test.desc, func(t *testing.T) {
-			t.Parallel()
-
-			actual := truncateString(test.text, test.limit)
-
-			assert.Equal(t, test.expected, actual)
-			assert.LessOrEqual(t, len(actual), test.limit)
-		})
-	}
-}