mirror of
https://github.com/traefik/traefik.git
synced 2025-08-06 06:37:09 +02:00
Merge branch v3.5 into master
This commit is contained in:
commit
24cede62ee
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,17 +1,16 @@
|
||||
<!--
|
||||
PLEASE READ THIS MESSAGE.
|
||||
|
||||
Documentation fixes or enhancements:
|
||||
- for Traefik v2: use branch v2.11
|
||||
- for Traefik v3: use branch v3.4
|
||||
Documentation:
|
||||
- for Traefik v2: use branch v2.11 (fixes only)
|
||||
- for Traefik v3: use branch v3.5
|
||||
|
||||
Bug fixes:
|
||||
- for Traefik v2: use branch v2.11
|
||||
- for Traefik v3: use branch v3.4
|
||||
Bug:
|
||||
- for Traefik v2: use branch v2.11 (security fixes only)
|
||||
- for Traefik v3: use branch v3.5
|
||||
|
||||
Enhancements:
|
||||
- for Traefik v2: we only accept bug fixes
|
||||
- for Traefik v3: use branch master
|
||||
- use branch master
|
||||
|
||||
HOW TO WRITE A GOOD PULL REQUEST? https://doc.traefik.io/traefik/contributing/submitting-pull-requests/
|
||||
|
||||
|
33
.github/workflows/test-integration.yaml
vendored
33
.github/workflows/test-integration.yaml
vendored
@ -36,7 +36,21 @@ jobs:
|
||||
touch webui/static/index.html
|
||||
|
||||
- name: Build binary
|
||||
run: make binary
|
||||
run: make binary-linux-amd64
|
||||
|
||||
- name: Save go cache build
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
- name: Artifact traefik binary
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: traefik
|
||||
path: ./dist/linux/amd64/traefik
|
||||
retention-days: 1
|
||||
|
||||
test-integration:
|
||||
runs-on: ubuntu-latest
|
||||
@ -65,8 +79,21 @@ jobs:
|
||||
mkdir webui/static
|
||||
touch webui/static/index.html
|
||||
|
||||
- name: Build binary
|
||||
run: make binary
|
||||
- name: Download traefik binary
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: traefik
|
||||
path: ./dist/linux/amd64/
|
||||
|
||||
- name: Make binary executable
|
||||
run: chmod +x ./dist/linux/amd64/traefik
|
||||
|
||||
- name: Restore go cache build
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
- name: Generate go test Slice
|
||||
id: test_split
|
||||
|
68
CHANGELOG.md
68
CHANGELOG.md
@ -1,3 +1,71 @@
|
||||
## [v3.5.0](https://github.com/traefik/traefik/tree/v3.5.0) (2025-07-23)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.5.0-rc1...v3.5.0)
|
||||
|
||||
**Enhancements:**
|
||||
- **[acme]** OCSP stapling ([#8393](https://github.com/traefik/traefik/pull/8393) by [alekitto](https://github.com/alekitto))
|
||||
- **[acme]** Add acme.httpChallenge.delay option ([#11643](https://github.com/traefik/traefik/pull/11643) by [ldez](https://github.com/ldez))
|
||||
- **[acme]** Allow configuration of ACME provider http timeout ([#11637](https://github.com/traefik/traefik/pull/11637) by [tkw1536](https://github.com/tkw1536))
|
||||
- **[healthcheck]** Add url option to healthcheck command ([#11711](https://github.com/traefik/traefik/pull/11711) by [Nelwhix](https://github.com/Nelwhix))
|
||||
- **[healthcheck]** Add unhealthy Interval to the health check configuration ([#10610](https://github.com/traefik/traefik/pull/10610) by [sswastik02](https://github.com/sswastik02))
|
||||
- **[k8s/gatewayapi]** Bump sigs.k8s.io/gateway-api to v1.3.0 ([#11719](https://github.com/traefik/traefik/pull/11719) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[k8s/ingress]** Make the behavior of prefix matching in Ingress consistent with Kubernetes doc ([#11203](https://github.com/traefik/traefik/pull/11203) by [charlie0129](https://github.com/charlie0129))
|
||||
- **[k8s]** NGINX Ingress Provider ([#11844](https://github.com/traefik/traefik/pull/11844) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[middleware,authentication]** Handle context canceled in ForwardAuth middleware ([#11817](https://github.com/traefik/traefik/pull/11817) by [bengentree](https://github.com/bengentree))
|
||||
- **[plugins]** Ability to enable unsafe in yaegi through plugin manifest ([#11589](https://github.com/traefik/traefik/pull/11589) by [Rydez](https://github.com/Rydez))
|
||||
- **[tls]** Introduce X25519MLKEM768 for Post-Quantum-Secure TLS ([#11731](https://github.com/traefik/traefik/pull/11731) by [fzoli](https://github.com/fzoli))
|
||||
- **[webui]** Migrate Traefik Proxy dashboard UI to React ([#11674](https://github.com/traefik/traefik/pull/11674) by [gndz07](https://github.com/gndz07))
|
||||
- **[webui]** Improve visualization for StatusRewrites option of errors middleware ([#11806](https://github.com/traefik/traefik/pull/11806) by [sevensolutions](https://github.com/sevensolutions))
|
||||
|
||||
**Bug fixes:**
|
||||
- **[healthcheck]** Revert 11711 adding url param to healthcheck command ([#11927](https://github.com/traefik/traefik/pull/11927) by [lbenguigui](https://github.com/lbenguigui))
|
||||
- **[logs,metrics,tracing,accesslogs,otel]** Add missing resource attributes detectors ([#11874](https://github.com/traefik/traefik/pull/11874) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[logs,tracing,k8s,otel]** Add k8s resource attributes automatically ([#11906](https://github.com/traefik/traefik/pull/11906) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[metrics,otel]** Add resourceAttributes option to OTel metrics ([#11908](https://github.com/traefik/traefik/pull/11908) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware,tracing]** Introduce trace verbosity config and produce less spans by default ([#11870](https://github.com/traefik/traefik/pull/11870) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
**Documentation:**
|
||||
- **[docker,ecs,docker/swarm,consulcatalog,nomad]** Add constraints key limitations for label providers ([#11893](https://github.com/traefik/traefik/pull/11893) by [bluepuma77](https://github.com/bluepuma77))
|
||||
- **[k8s]** Add extended NGinX annotation support documentation ([#11920](https://github.com/traefik/traefik/pull/11920) by [nmengin](https://github.com/nmengin))
|
||||
- Remove dead link to Peka blog ([#11934](https://github.com/traefik/traefik/pull/11934) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Prepare release v3.5.0-rc2 ([#11899](https://github.com/traefik/traefik/pull/11899) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Prepare release v3.5.0-rc1 ([#11865](https://github.com/traefik/traefik/pull/11865) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
**Misc:**
|
||||
- Merge branch v3.4 into v3.5 ([#11933](https://github.com/traefik/traefik/pull/11933) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge branch v3.4 into v3.5 ([#11898](https://github.com/traefik/traefik/pull/11898) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge branch v3.4 into master ([#11863](https://github.com/traefik/traefik/pull/11863) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge branch v3.4 into master ([#11861](https://github.com/traefik/traefik/pull/11861) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge branch v3.4 into master ([#11857](https://github.com/traefik/traefik/pull/11857) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge branch v3.4 into master ([#11855](https://github.com/traefik/traefik/pull/11855) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge branch v3.4 into master ([#11813](https://github.com/traefik/traefik/pull/11813) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge branch v3.4 into master ([#11758](https://github.com/traefik/traefik/pull/11758) by [mmatur](https://github.com/mmatur))
|
||||
- Merge v3.4 into master ([#11752](https://github.com/traefik/traefik/pull/11752) by [mmatur](https://github.com/mmatur))
|
||||
- Merge branch v3.4 into master ([#11708](https://github.com/traefik/traefik/pull/11708) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v3.4.5](https://github.com/traefik/traefik/tree/v3.4.5) (2025-07-23)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.4.4...v3.4.5)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[http3]** Bump github.com/quic-go/quic-go to v0.54.0 ([#11919](https://github.com/traefik/traefik/pull/11919) by [GreyXor](https://github.com/GreyXor))
|
||||
|
||||
**Documentation:**
|
||||
- Fix typo in entrypoints page ([#11914](https://github.com/traefik/traefik/pull/11914) by [adk-swisstopo](https://github.com/adk-swisstopo))
|
||||
|
||||
**Misc:**
|
||||
- Merge branch v2.11 into v3.4 ([#11930](https://github.com/traefik/traefik/pull/11930) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge branch v2.11 into v3.4 ([#11926](https://github.com/traefik/traefik/pull/11926) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
## [v2.11.28](https://github.com/traefik/traefik/tree/v2.11.28) (2025-07-23)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.27...v2.11.28)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[logs]** Redact logged install configuration ([#11907](https://github.com/traefik/traefik/pull/11907) by [jspdown](https://github.com/jspdown))
|
||||
- **[plugins]** Fix client arbitrary file access during archive extraction zipslip ([#11911](https://github.com/traefik/traefik/pull/11911) by [odaysec](https://github.com/odaysec))
|
||||
- **[server]** Disable MPTCP by default ([#11918](https://github.com/traefik/traefik/pull/11918) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
**Documentation:**
|
||||
- **[k8s/crd,k8s]** Remove all mentions of ordering for TLSOption CurvePreferences field ([#11924](https://github.com/traefik/traefik/pull/11924) by [jnoordsij](https://github.com/jnoordsij))
|
||||
|
||||
## [v3.5.0-rc2](https://github.com/traefik/traefik/tree/v3.5.0-rc2) (2025-07-11)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.5.0-rc1...v3.5.0-rc2)
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -93,7 +93,7 @@ test-unit:
|
||||
|
||||
.PHONY: test-integration
|
||||
#? test-integration: Run the integration tests
|
||||
test-integration: binary
|
||||
test-integration:
|
||||
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -test.timeout=20m -failfast -v $(TESTFLAGS)
|
||||
|
||||
.PHONY: test-gateway-api-conformance
|
||||
|
@ -152,7 +152,7 @@ We use [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## Credits
|
||||
|
||||
Kudos to [Peka](http://peka.byethost11.com/photoblog/) for his awesome work on the gopher's logo!.
|
||||
Kudos to Peka for his awesome work on the gopher's logo!.
|
||||
|
||||
The gopher's logo of Traefik is licensed under the Creative Commons 3.0 Attributions license.
|
||||
|
||||
|
@ -2,7 +2,6 @@ package healthcheck
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -23,26 +22,11 @@ func NewCmd(traefikConfiguration *static.Configuration, loaders []cli.ResourceLo
|
||||
}
|
||||
}
|
||||
|
||||
func runCmd(traefikConfiguration *static.Configuration) func(args []string) error {
|
||||
return func(args []string) error {
|
||||
fs := flag.NewFlagSet("healthcheck", flag.ContinueOnError)
|
||||
urlFlag := fs.String("url", "", "")
|
||||
fs.SetOutput(os.Stderr)
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func runCmd(traefikConfiguration *static.Configuration) func(_ []string) error {
|
||||
return func(_ []string) error {
|
||||
traefikConfiguration.SetEffectiveConfiguration()
|
||||
|
||||
var resp *http.Response
|
||||
var errPing error
|
||||
if *urlFlag != "" {
|
||||
client := &http.Client{Timeout: 5 * time.Second}
|
||||
resp, errPing = client.Head(*urlFlag)
|
||||
} else {
|
||||
resp, errPing = Do(*traefikConfiguration)
|
||||
}
|
||||
|
||||
resp, errPing := Do(*traefikConfiguration)
|
||||
if resp != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -22,7 +23,7 @@ func init() {
|
||||
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
|
||||
}
|
||||
|
||||
func setupLogger(staticConfiguration *static.Configuration) error {
|
||||
func setupLogger(ctx context.Context, staticConfiguration *static.Configuration) error {
|
||||
// Validate that the experimental flag is set up at this point,
|
||||
// rather than validating the static configuration before the setupLogger call.
|
||||
// This ensures that validation messages are not logged using an un-configured logger.
|
||||
@ -39,16 +40,16 @@ func setupLogger(staticConfiguration *static.Configuration) error {
|
||||
zerolog.SetGlobalLevel(logLevel)
|
||||
|
||||
// create logger
|
||||
logCtx := zerolog.New(w).With().Timestamp()
|
||||
logger := zerolog.New(w).With().Timestamp()
|
||||
if logLevel <= zerolog.DebugLevel {
|
||||
logCtx = logCtx.Caller()
|
||||
logger = logger.Caller()
|
||||
}
|
||||
|
||||
log.Logger = logCtx.Logger().Level(logLevel)
|
||||
log.Logger = logger.Logger().Level(logLevel)
|
||||
|
||||
if staticConfiguration.Log != nil && staticConfiguration.Log.OTLP != nil {
|
||||
var err error
|
||||
log.Logger, err = logs.SetupOTelLogger(log.Logger, staticConfiguration.Log.OTLP)
|
||||
log.Logger, err = logs.SetupOTelLogger(ctx, log.Logger, staticConfiguration.Log.OTLP)
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting up OpenTelemetry logger: %w", err)
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
stdlog "log"
|
||||
@ -40,6 +39,7 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/provider/traefik"
|
||||
"github.com/traefik/traefik/v3/pkg/proxy"
|
||||
"github.com/traefik/traefik/v3/pkg/proxy/httputil"
|
||||
"github.com/traefik/traefik/v3/pkg/redactor"
|
||||
"github.com/traefik/traefik/v3/pkg/safe"
|
||||
"github.com/traefik/traefik/v3/pkg/server"
|
||||
"github.com/traefik/traefik/v3/pkg/server/middleware"
|
||||
@ -90,7 +90,10 @@ Complete documentation is available at https://traefik.io`,
|
||||
}
|
||||
|
||||
func runCmd(staticConfiguration *static.Configuration) error {
|
||||
if err := setupLogger(staticConfiguration); err != nil {
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
||||
if err := setupLogger(ctx, staticConfiguration); err != nil {
|
||||
return fmt.Errorf("setting up logger: %w", err)
|
||||
}
|
||||
|
||||
@ -104,12 +107,11 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
log.Info().Str("version", version.Version).
|
||||
Msgf("Traefik version %s built on %s", version.Version, version.BuildDate)
|
||||
|
||||
jsonConf, err := json.Marshal(staticConfiguration)
|
||||
redactedStaticConfiguration, err := redactor.RemoveCredentials(staticConfiguration)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Could not marshal static configuration")
|
||||
log.Debug().Interface("staticConfiguration", staticConfiguration).Msg("Static configuration loaded [struct]")
|
||||
log.Error().Err(err).Msg("Could not redact static configuration")
|
||||
} else {
|
||||
log.Debug().RawJSON("staticConfiguration", jsonConf).Msg("Static configuration loaded [json]")
|
||||
log.Debug().RawJSON("staticConfiguration", []byte(redactedStaticConfiguration)).Msg("Static configuration loaded [json]")
|
||||
}
|
||||
|
||||
if staticConfiguration.Global.CheckNewVersion {
|
||||
@ -123,8 +125,6 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
if staticConfiguration.Ping != nil {
|
||||
staticConfiguration.Ping.WithContext(ctx)
|
||||
}
|
||||
@ -210,8 +210,8 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
||||
}
|
||||
}
|
||||
metricsRegistry := metrics.NewMultiRegistry(metricRegistries)
|
||||
accessLog := setupAccessLog(staticConfiguration.AccessLog)
|
||||
tracer, tracerCloser := setupTracing(staticConfiguration.Tracing)
|
||||
accessLog := setupAccessLog(ctx, staticConfiguration.AccessLog)
|
||||
tracer, tracerCloser := setupTracing(ctx, staticConfiguration.Tracing)
|
||||
observabilityMgr := middleware.NewObservabilityMgr(*staticConfiguration, metricsRegistry, semConvMetricRegistry, accessLog, tracer, tracerCloser)
|
||||
|
||||
// Entrypoints
|
||||
@ -586,12 +586,12 @@ func appendCertMetric(gauge gokitmetrics.Gauge, certificate *x509.Certificate) {
|
||||
gauge.With(labels...).Set(notAfter)
|
||||
}
|
||||
|
||||
func setupAccessLog(conf *types.AccessLog) *accesslog.Handler {
|
||||
func setupAccessLog(ctx context.Context, conf *types.AccessLog) *accesslog.Handler {
|
||||
if conf == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
accessLoggerMiddleware, err := accesslog.NewHandler(conf)
|
||||
accessLoggerMiddleware, err := accesslog.NewHandler(ctx, conf)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Unable to create access logger")
|
||||
return nil
|
||||
@ -600,12 +600,12 @@ func setupAccessLog(conf *types.AccessLog) *accesslog.Handler {
|
||||
return accessLoggerMiddleware
|
||||
}
|
||||
|
||||
func setupTracing(conf *static.Tracing) (*tracing.Tracer, io.Closer) {
|
||||
func setupTracing(ctx context.Context, conf *static.Tracing) (*tracing.Tracer, io.Closer) {
|
||||
if conf == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
tracer, closer, err := tracing.NewTracing(conf)
|
||||
tracer, closer, err := tracing.NewTracing(ctx, conf)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Unable to create tracer")
|
||||
return nil, nil
|
||||
|
@ -384,11 +384,11 @@ spec:
|
||||
|
||||
### Curve Preferences
|
||||
|
||||
This option allows to set the preferred elliptic curves in a specific order.
|
||||
This option allows to set the enabled elliptic curves for key exchange.
|
||||
|
||||
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
|
||||
|
||||
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||
See [CurvePreferences](https://godoc.org/crypto/tls#Config.CurvePreferences) and [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Dynamic configuration
|
||||
|
@ -706,3 +706,14 @@ and Traefik now keeps them encoded to avoid any ambiguity.
|
||||
| `/foo/../bar` | PathPrefix(`/bar`) | Match | Match |
|
||||
| `/foo/%2E%2E/bar` | PathPrefix(`/foo`) | Match | No match |
|
||||
| `/foo/%2E%2E/bar` | PathPrefix(`/bar`) | No match | Match |
|
||||
|
||||
## v2.11.28
|
||||
|
||||
### MultiPath TCP
|
||||
|
||||
Since `v2.11.28`, the MultiPath TCP support introduced with `v2.11.26` has been removed.
|
||||
It appears that enabling MPTCP on some platforms can cause Traefik to stop with the following error logs message:
|
||||
|
||||
- `set tcp X.X.X.X:X->X.X.X.X:X: setsockopt: operation not supported`
|
||||
|
||||
However, it can be re-enabled by setting the `multipathtcp` variable in the GODEBUG environment variable, see the related [go documentation](https://go.dev/doc/godebug#go-124).
|
||||
|
@ -319,3 +319,53 @@ and Traefik now keeps them encoded to avoid any ambiguity.
|
||||
| `/foo/../bar` | PathPrefix(`/bar`) | Match | Match |
|
||||
| `/foo/%2E%2E/bar` | PathPrefix(`/foo`) | Match | No match |
|
||||
| `/foo/%2E%2E/bar` | PathPrefix(`/bar`) | No match | Match |
|
||||
|
||||
## v3.4.5
|
||||
|
||||
### MultiPath TCP
|
||||
|
||||
Since `v3.4.5`, the MultiPath TCP support introduced with `v3.4.2` has been removed.
|
||||
It appears that enabling MPTCP on some platforms can cause Traefik to stop with the following error logs message:
|
||||
|
||||
- `set tcp X.X.X.X:X->X.X.X.X:X: setsockopt: operation not supported`
|
||||
|
||||
However, it can be re-enabled by setting the `multipathtcp` variable in the GODEBUG environment variable, see the related [go documentation](https://go.dev/doc/godebug#go-124).
|
||||
|
||||
## v3.5.0
|
||||
|
||||
### Observability
|
||||
|
||||
#### TraceVerbosity on Routers and Entrypoints
|
||||
|
||||
Starting with `v3.5.0`, a new `traceVerbosity` option is available for both entrypoints and routers.
|
||||
This option allows you to control the level of detail for tracing spans.
|
||||
Routers can override the value inherited from their entrypoint.
|
||||
|
||||
**Impact:**
|
||||
|
||||
- If you rely on tracing, review your configuration to explicitly set the desired verbosity level.
|
||||
- Existing configurations will default to `minimal` unless overridden, which will result in fewer spans being generated than before.
|
||||
|
||||
Possible values are:
|
||||
|
||||
- `minimal`: produces a single server span and one client span for each request processed by a router.
|
||||
- `detailed`: enables the creation of additional spans for each middleware executed for each request processed by a router.
|
||||
|
||||
See the updated documentation for [entrypoints](../reference/install-configuration/entrypoints.md) and [dynamic routers](../reference/dynamic-configuration/file.md#observability-options).
|
||||
|
||||
#### K8s Resource Attributes
|
||||
|
||||
Since `v3.5.0`, the semconv attributes `k8s.pod.name` and `k8s.pod.uid` are injected automatically in OTel resource attributes when OTel tracing/logs/metrics are enabled.
|
||||
|
||||
For that purpose, the following right has to be added to the Traefik Kubernetes RBACs:
|
||||
|
||||
```yaml
|
||||
...
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- get
|
||||
...
|
||||
```
|
||||
|
@ -340,6 +340,54 @@ accesslog:
|
||||
|
||||
The OpenTelemetry Logger exporter will export access logs to the collector using HTTPS by default to https://localhost:4318/v1/logs, see the [gRPC Section](#grpc-configuration) to use gRPC.
|
||||
|
||||
### `serviceName`
|
||||
|
||||
_Optional, Default="traefik"_
|
||||
|
||||
Defines the service name resource attribute.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
accesslog:
|
||||
otlp:
|
||||
serviceName: name
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[accesslog]
|
||||
[accesslog.otlp]
|
||||
serviceName = "name"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--accesslog.otlp.serviceName=name
|
||||
```
|
||||
|
||||
### `ressourceAttributes`
|
||||
|
||||
_Optional, Default=empty_
|
||||
|
||||
Defines additional resource attributes to be sent to the collector.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
accesslog:
|
||||
otlp:
|
||||
resourceAttributes:
|
||||
attr1: foo
|
||||
attr2: bar
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[accesslog]
|
||||
[accesslog.otlp.resourceAttributes]
|
||||
attr1 = "foo"
|
||||
attr2 = "bar"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--accesslog.otlp.resourceAttributes.attr1=foo
|
||||
--accesslog.otlp.resourceAttributes.attr2=bar
|
||||
```
|
||||
|
||||
### HTTP configuration
|
||||
|
||||
_Optional_
|
||||
|
@ -219,6 +219,54 @@ log:
|
||||
|
||||
The OpenTelemetry Logger exporter will export logs to the collector using HTTPS by default to https://localhost:4318/v1/logs, see the [gRPC Section](#grpc-configuration) to use gRPC.
|
||||
|
||||
### `serviceName`
|
||||
|
||||
_Optional, Default="traefik"_
|
||||
|
||||
Defines the service name resource attribute.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
log:
|
||||
otlp:
|
||||
serviceName: name
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[log]
|
||||
[log.otlp]
|
||||
serviceName = "name"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--log.otlp.serviceName=name
|
||||
```
|
||||
|
||||
### `ressourceAttributes`
|
||||
|
||||
_Optional, Default=empty_
|
||||
|
||||
Defines additional resource attributes to be sent to the collector.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
log:
|
||||
otlp:
|
||||
resourceAttributes:
|
||||
attr1: foo
|
||||
attr2: bar
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[log]
|
||||
[log.otlp.resourceAttributes]
|
||||
attr1 = "foo"
|
||||
attr2 = "bar"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--log.otlp.resourceAttributes.attr1=foo
|
||||
--log.otlp.resourceAttributes.attr2=bar
|
||||
```
|
||||
|
||||
### HTTP configuration
|
||||
|
||||
_Optional_
|
||||
|
@ -143,7 +143,7 @@ metrics:
|
||||
|
||||
_Optional, Default="traefik"_
|
||||
|
||||
OTEL service name to use.
|
||||
Defines the service name resource attribute.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
metrics:
|
||||
@ -160,6 +160,31 @@ metrics:
|
||||
```bash tab="CLI"
|
||||
--metrics.otlp.serviceName=name
|
||||
```
|
||||
#### `ressourceAttributes`
|
||||
|
||||
_Optional, Default=empty_
|
||||
|
||||
Defines additional resource attributes to be sent to the collector.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
metrics:
|
||||
otlp:
|
||||
resourceAttributes:
|
||||
attr1: foo
|
||||
attr2: bar
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[metrics]
|
||||
[metrics.otlp.resourceAttributes]
|
||||
attr1 = "foo"
|
||||
attr2 = "bar"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--metrics.otlp.resourceAttributes.attr1=foo
|
||||
--metrics.otlp.resourceAttributes.attr2=bar
|
||||
```
|
||||
|
||||
### HTTP configuration
|
||||
|
||||
|
@ -169,6 +169,7 @@
|
||||
- "traefik.http.routers.router0.middlewares=foobar, foobar"
|
||||
- "traefik.http.routers.router0.observability.accesslogs=true"
|
||||
- "traefik.http.routers.router0.observability.metrics=true"
|
||||
- "traefik.http.routers.router0.observability.traceverbosity=foobar"
|
||||
- "traefik.http.routers.router0.observability.tracing=true"
|
||||
- "traefik.http.routers.router0.priority=42"
|
||||
- "traefik.http.routers.router0.rule=foobar"
|
||||
@ -185,6 +186,7 @@
|
||||
- "traefik.http.routers.router1.middlewares=foobar, foobar"
|
||||
- "traefik.http.routers.router1.observability.accesslogs=true"
|
||||
- "traefik.http.routers.router1.observability.metrics=true"
|
||||
- "traefik.http.routers.router1.observability.traceverbosity=foobar"
|
||||
- "traefik.http.routers.router1.observability.tracing=true"
|
||||
- "traefik.http.routers.router1.priority=42"
|
||||
- "traefik.http.routers.router1.rule=foobar"
|
||||
|
@ -22,8 +22,9 @@
|
||||
sans = ["foobar", "foobar"]
|
||||
[http.routers.Router0.observability]
|
||||
accessLogs = true
|
||||
tracing = true
|
||||
metrics = true
|
||||
tracing = true
|
||||
traceVerbosity = "foobar"
|
||||
[http.routers.Router1]
|
||||
entryPoints = ["foobar", "foobar"]
|
||||
middlewares = ["foobar", "foobar"]
|
||||
@ -44,8 +45,9 @@
|
||||
sans = ["foobar", "foobar"]
|
||||
[http.routers.Router1.observability]
|
||||
accessLogs = true
|
||||
tracing = true
|
||||
metrics = true
|
||||
tracing = true
|
||||
traceVerbosity = "foobar"
|
||||
[http.services]
|
||||
[http.services.Service01]
|
||||
[http.services.Service01.failover]
|
||||
|
@ -27,8 +27,9 @@ http:
|
||||
- foobar
|
||||
observability:
|
||||
accessLogs: true
|
||||
tracing: true
|
||||
metrics: true
|
||||
tracing: true
|
||||
traceVerbosity: foobar
|
||||
Router1:
|
||||
entryPoints:
|
||||
- foobar
|
||||
@ -54,8 +55,9 @@ http:
|
||||
- foobar
|
||||
observability:
|
||||
accessLogs: true
|
||||
tracing: true
|
||||
metrics: true
|
||||
tracing: true
|
||||
traceVerbosity: foobar
|
||||
services:
|
||||
Service01:
|
||||
failover:
|
||||
|
@ -92,10 +92,21 @@ spec:
|
||||
More info: https://doc.traefik.io/traefik/v3.5/routing/routers/#observability
|
||||
properties:
|
||||
accessLogs:
|
||||
description: AccessLogs enables access logs for this router.
|
||||
type: boolean
|
||||
metrics:
|
||||
description: Metrics enables metrics for this router.
|
||||
type: boolean
|
||||
traceVerbosity:
|
||||
default: minimal
|
||||
description: TraceVerbosity defines the verbosity level
|
||||
of the tracing for this router.
|
||||
enum:
|
||||
- minimal
|
||||
- detailed
|
||||
type: string
|
||||
tracing:
|
||||
description: Tracing enables tracing for this router.
|
||||
type: boolean
|
||||
type: object
|
||||
priority:
|
||||
@ -2551,7 +2562,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v3.5/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
@ -15,6 +15,14 @@ rules:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
# The pods right is needed to inject k8s.pod.uid and k8s.pod.name OTel attributes.
|
||||
# When OTel tracing/logs/metrics are not enabled, this rule is not needed.
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- discovery.k8s.io
|
||||
resources:
|
||||
|
@ -11,6 +11,14 @@ rules:
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
# The pods get right is needed to inject k8s.pod.uid and k8s.pod.name in OTel attributes.
|
||||
# When OTel tracing/logs/metrics are not enabled, this rule is not needed.
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
|
@ -199,6 +199,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
|
||||
| `traefik/http/routers/Router0/middlewares/1` | `foobar` |
|
||||
| `traefik/http/routers/Router0/observability/accessLogs` | `true` |
|
||||
| `traefik/http/routers/Router0/observability/metrics` | `true` |
|
||||
| `traefik/http/routers/Router0/observability/traceVerbosity` | `foobar` |
|
||||
| `traefik/http/routers/Router0/observability/tracing` | `true` |
|
||||
| `traefik/http/routers/Router0/priority` | `42` |
|
||||
| `traefik/http/routers/Router0/rule` | `foobar` |
|
||||
@ -218,6 +219,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
|
||||
| `traefik/http/routers/Router1/middlewares/1` | `foobar` |
|
||||
| `traefik/http/routers/Router1/observability/accessLogs` | `true` |
|
||||
| `traefik/http/routers/Router1/observability/metrics` | `true` |
|
||||
| `traefik/http/routers/Router1/observability/traceVerbosity` | `foobar` |
|
||||
| `traefik/http/routers/Router1/observability/tracing` | `true` |
|
||||
| `traefik/http/routers/Router1/priority` | `42` |
|
||||
| `traefik/http/routers/Router1/rule` | `foobar` |
|
||||
|
@ -0,0 +1,114 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.1
|
||||
name: tlsoptions.traefik.containo.us
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
names:
|
||||
kind: TLSOption
|
||||
listKind: TLSOptionList
|
||||
plural: tlsoptions
|
||||
singular: tlsoption
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: |-
|
||||
TLSOption is the CRD implementation of a Traefik TLS Option, allowing to configure some parameters of the TLS connection.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#tls-options
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: TLSOptionSpec defines the desired state of a TLSOption.
|
||||
properties:
|
||||
alpnProtocols:
|
||||
description: |-
|
||||
ALPNProtocols defines the list of supported application level protocols for the TLS handshake, in order of preference.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#alpn-protocols
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
cipherSuites:
|
||||
description: |-
|
||||
CipherSuites defines the list of supported cipher suites for TLS versions up to TLS 1.2.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#cipher-suites
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
clientAuth:
|
||||
description: ClientAuth defines the server's policy for TLS Client
|
||||
Authentication.
|
||||
properties:
|
||||
clientAuthType:
|
||||
description: ClientAuthType defines the client authentication
|
||||
type to apply.
|
||||
enum:
|
||||
- NoClientCert
|
||||
- RequestClientCert
|
||||
- RequireAnyClientCert
|
||||
- VerifyClientCertIfGiven
|
||||
- RequireAndVerifyClientCert
|
||||
type: string
|
||||
secretNames:
|
||||
description: SecretNames defines the names of the referenced Kubernetes
|
||||
Secret storing certificate details.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
maxVersion:
|
||||
description: |-
|
||||
MaxVersion defines the maximum TLS version that Traefik will accept.
|
||||
Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13.
|
||||
Default: None.
|
||||
type: string
|
||||
minVersion:
|
||||
description: |-
|
||||
MinVersion defines the minimum TLS version that Traefik will accept.
|
||||
Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13.
|
||||
Default: VersionTLS10.
|
||||
type: string
|
||||
preferServerCipherSuites:
|
||||
description: |-
|
||||
PreferServerCipherSuites defines whether the server chooses a cipher suite among his own instead of among the client's.
|
||||
It is enabled automatically when minVersion or maxVersion is set.
|
||||
Deprecated: https://github.com/golang/go/issues/45430
|
||||
type: boolean
|
||||
sniStrict:
|
||||
description: SniStrict defines whether Traefik allows connections
|
||||
from clients connections that do not specify a server_name extension.
|
||||
type: boolean
|
||||
type: object
|
||||
required:
|
||||
- metadata
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
@ -92,10 +92,21 @@ spec:
|
||||
More info: https://doc.traefik.io/traefik/v3.5/routing/routers/#observability
|
||||
properties:
|
||||
accessLogs:
|
||||
description: AccessLogs enables access logs for this router.
|
||||
type: boolean
|
||||
metrics:
|
||||
description: Metrics enables metrics for this router.
|
||||
type: boolean
|
||||
traceVerbosity:
|
||||
default: minimal
|
||||
description: TraceVerbosity defines the verbosity level
|
||||
of the tracing for this router.
|
||||
enum:
|
||||
- minimal
|
||||
- detailed
|
||||
type: string
|
||||
tracing:
|
||||
description: Tracing enables tracing for this router.
|
||||
type: boolean
|
||||
type: object
|
||||
priority:
|
||||
|
@ -78,7 +78,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v3.5/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
@ -83,39 +83,40 @@ additionalArguments:
|
||||
|
||||
## Configuration Options
|
||||
|
||||
| Field | Description | Default | Required |
|
||||
|:-----------------|:--------|:--------|:---------|
|
||||
| `address` | Define the port, and optionally the hostname, on which to listen for incoming connections and packets.<br /> It also defines the protocol to use (TCP or UDP).<br /> If no protocol is specified, the default is TCP. The format is:`[host]:port[/tcp\|/udp] | - | Yes |
|
||||
| `asDefault` | Mark the `entryPoint` to be in the list of default `entryPoints`.<br /> `entryPoints`in this list are used (by default) on HTTP and TCP routers that do not define their own `entryPoints` option.<br /> More information [here](#asdefault). | false | No |
|
||||
| `forwardedHeaders.trustedIPs` | Set the IPs or CIDR from where Traefik trusts the forwarded headers information (`X-Forwarded-*`). | - | No |
|
||||
| `forwardedHeaders.insecure` | Set the insecure mode to always trust the forwarded headers information (`X-Forwarded-*`).<br />We recommend to use this option only for tests purposes, not in production. | false | No |
|
||||
| `http.redirections.`<br />`entryPoint.to` | The target element to enable (permanent) redirecting of all incoming requests on an entry point to another one. <br /> The target element can be an entry point name (ex: `websecure`), or a port (`:443`). | - | Yes |
|
||||
| `http.redirections.`<br />`entryPoint.scheme` | The target scheme to use for (permanent) redirection of all incoming requests. | https | No |
|
||||
| `http.redirections.`<br />`entryPoint.permanent` | Enable permanent redirecting of all incoming requests on an entry point to another one changing the scheme. <br /> The target element, it can be an entry point name (ex: `websecure`), or a port (`:443`). | false | No |
|
||||
| `http.redirections.`<br />`entryPoint.priority` | Default priority applied to the routers attached to the `entryPoint`.| MaxInt32-1 (2147483646) | No |
|
||||
| `http.encodeQuerySemicolons` | Enable query semicolons encoding. <br /> Use this option to avoid non-encoded semicolons to be interpreted as query parameter separators by Traefik. <br /> When using this option, the non-encoded semicolons characters in query will be transmitted encoded to the backend.<br /> More information [here](#encodequerysemicolons). | false | No |
|
||||
| `http.sanitizePath` | Defines whether to enable the request path sanitization.<br /> More information [here](#sanitizepath). | false | No |
|
||||
| `http.middlewares` | Set the list of middlewares that are prepended by default to the list of middlewares of each router associated to the named entry point. <br />More information [here](#httpmiddlewares). | - | No |
|
||||
| `http.tls` | Enable TLS on every router attached to the `entryPoint`. <br /> If no certificate are set, a default self-signed certificate is generates by Traefik. <br /> We recommend to not use self signed certificates in production.| - | No |
|
||||
| `http.tls.options` | Apply TLS options on every router attached to the `entryPoint`. <br /> The TLS options can be overidden per router. <br /> More information in the [dedicated section](../../routing/providers/kubernetes-crd.md#kind-tlsoption). | - | No |
|
||||
| `http.tls.certResolver` | Apply a certificate resolver on every router attached to the `entryPoint`. <br /> The TLS options can be overidden per router. <br /> More information in the [dedicated section](../install-configuration/tls/certificate-resolvers/overview.md). | - | No |
|
||||
| `http2.maxConcurrentStreams` | Set the number of concurrent streams per connection that each client is allowed to initiate. <br /> The value must be greater than zero. | 250 | No |
|
||||
| `http3` | Enable HTTP/3 protocol on the `entryPoint`. <br /> HTTP/3 requires a TCP `entryPoint`. as HTTP/3 always starts as a TCP connection that then gets upgraded to UDP. In most scenarios, this `entryPoint` is the same as the one used for TLS traffic.<br /> More information [here](#http3. | - | No |
|
||||
| `http3.advertisedPort` | Set the UDP port to advertise as the HTTP/3 authority. <br /> It defaults to the entryPoint's address port. <br /> It can be used to override the authority in the `alt-svc` header, for example if the public facing port is different from where Traefik is listening. | - | No |
|
||||
| `observability.accessLogs` | Defines whether a router attached to this EntryPoint produces access-logs by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
|
||||
| `observability.metrics` | Defines whether a router attached to this EntryPoint produces metrics by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
|
||||
| `observability.tracing` | Defines whether a router attached to this EntryPoint produces traces by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
|
||||
| `proxyProtocol.trustedIPs` | Enable PROXY protocol with Trusted IPs. <br /> Traefik supports [PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2. <br /> If PROXY protocol header parsing is enabled for the entry point, this entry point can accept connections with or without PROXY protocol headers. <br /> If the PROXY protocol header is passed, then the version is determined automatically.<br /> More information [here](#proxyprotocol-and-load-balancers). | - | No |
|
||||
| `proxyProtocol.insecure` | Enable PROXY protocol trusting every incoming connection. <br /> Every remote client address will be replaced (`trustedIPs`) won't have any effect). <br /> Traefik supports [PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2. <br /> If PROXY protocol header parsing is enabled for the entry point, this entry point can accept connections with or without PROXY protocol headers. <br /> If the PROXY protocol header is passed, then the version is determined automatically.<br />We recommend to use this option only for tests purposes, not in production.<br /> More information [here](#proxyprotocol-and-load-balancers). | - | No |
|
||||
| `reusePort` | Enable `entryPoints` from the same or different processes listening on the same TCP/UDP port by utilizing the `SO_REUSEPORT` socket option. <br /> It also allows the kernel to act like a load balancer to distribute incoming connections between entry points..<br /> More information [here](#reuseport). | false | No |
|
||||
| `transport.`<br />`respondingTimeouts.`<br />`readTimeout` | Set the timeouts for incoming requests to the Traefik instance. This is the maximum duration for reading the entire request, including the body. Setting them has no effect for UDP `entryPoints`.<br /> If zero, no timeout exists. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds. | 60s (seconds) | No |
|
||||
| `transport.`<br />`respondingTimeouts.`<br />`writeTimeout` | Maximum duration before timing out writes of the response. <br /> It covers the time from the end of the request header read to the end of the response write. <br /> If zero, no timeout exists. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds. | 0s (seconds) | No |
|
||||
| `transport.`<br />`respondingTimeouts.`<br />`idleTimeout` | Maximum duration an idle (keep-alive) connection will remain idle before closing itself. <br /> If zero, no timeout exists <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds | 180s (seconds) | No |
|
||||
| `transport.`<br />`lifeCycle.`<br />`graceTimeOut` | Set the duration to give active requests a chance to finish before Traefik stops. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds <br /> In this time frame no new requests are accepted. | 10s (seconds) | No |
|
||||
| `transport.`<br />`lifeCycle.`<br />`requestAcceptGraceTimeout` | Set the duration to keep accepting requests prior to initiating the graceful termination period (as defined by the `transportlifeCycle.graceTimeOut` option). <br /> This option is meant to give downstream load-balancers sufficient time to take Traefik out of rotation. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds | 0s (seconds) | No |
|
||||
| `transport.`<br />`keepAliveMaxRequests` | Set the maximum number of requests Traefik can handle before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). <br /> Zero means no limit. | 0 | No |
|
||||
| `transport.`<br />`keepAliveMaxTime` | Set the maximum duration Traefik can handle requests before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). Zero means no limit. | 0s (seconds) | No |
|
||||
| `udp.timeout` | Define how long to wait on an idle session before releasing the related resources. <br />The Timeout value must be greater than zero. | 3s (seconds)| No |
|
||||
| Field | Description | Default | Required |
|
||||
|:----------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------|:---------|
|
||||
| `address` | Define the port, and optionally the hostname, on which to listen for incoming connections and packets.<br /> It also defines the protocol to use (TCP or UDP).<br /> If no protocol is specified, the default is TCP. The format is:`[host]:port[/tcp\|/udp] | - | Yes |
|
||||
| `asDefault` | Mark the `entryPoint` to be in the list of default `entryPoints`.<br /> `entryPoints`in this list are used (by default) on HTTP and TCP routers that do not define their own `entryPoints` option.<br /> More information [here](#asdefault). | false | No |
|
||||
| `forwardedHeaders.trustedIPs` | Set the IPs or CIDR from where Traefik trusts the forwarded headers information (`X-Forwarded-*`). | - | No |
|
||||
| `forwardedHeaders.insecure` | Set the insecure mode to always trust the forwarded headers information (`X-Forwarded-*`).<br />We recommend to use this option only for tests purposes, not in production. | false | No |
|
||||
| `http.redirections.`<br />`entryPoint.to` | The target element to enable (permanent) redirecting of all incoming requests on an entry point to another one. <br /> The target element can be an entry point name (ex: `websecure`), or a port (`:443`). | - | Yes |
|
||||
| `http.redirections.`<br />`entryPoint.scheme` | The target scheme to use for (permanent) redirection of all incoming requests. | https | No |
|
||||
| `http.redirections.`<br />`entryPoint.permanent` | Enable permanent redirecting of all incoming requests on an entry point to another one changing the scheme. <br /> The target element, it can be an entry point name (ex: `websecure`), or a port (`:443`). | false | No |
|
||||
| `http.redirections.`<br />`entryPoint.priority` | Default priority applied to the routers attached to the `entryPoint`. | MaxInt32-1 (2147483646) | No |
|
||||
| `http.encodeQuerySemicolons` | Enable query semicolons encoding. <br /> Use this option to avoid non-encoded semicolons to be interpreted as query parameter separators by Traefik. <br /> When using this option, the non-encoded semicolons characters in query will be transmitted encoded to the backend.<br /> More information [here](#encodequerysemicolons). | false | No |
|
||||
| `http.sanitizePath` | Defines whether to enable the request path sanitization.<br /> More information [here](#sanitizepath). | false | No |
|
||||
| `http.middlewares` | Set the list of middlewares that are prepended by default to the list of middlewares of each router associated to the named entry point. <br />More information [here](#httpmiddlewares). | - | No |
|
||||
| `http.tls` | Enable TLS on every router attached to the `entryPoint`. <br /> If no certificate are set, a default self-signed certificate is generates by Traefik. <br /> We recommend to not use self signed certificates in production. | - | No |
|
||||
| `http.tls.options` | Apply TLS options on every router attached to the `entryPoint`. <br /> The TLS options can be overidden per router. <br /> More information in the [dedicated section](../../routing/providers/kubernetes-crd.md#kind-tlsoption). | - | No |
|
||||
| `http.tls.certResolver` | Apply a certificate resolver on every router attached to the `entryPoint`. <br /> The TLS options can be overidden per router. <br /> More information in the [dedicated section](../install-configuration/tls/certificate-resolvers/overview.md). | - | No |
|
||||
| `http2.maxConcurrentStreams` | Set the number of concurrent streams per connection that each client is allowed to initiate. <br /> The value must be greater than zero. | 250 | No |
|
||||
| `http3` | Enable HTTP/3 protocol on the `entryPoint`. <br /> HTTP/3 requires a TCP `entryPoint`. as HTTP/3 always starts as a TCP connection that then gets upgraded to UDP. In most scenarios, this `entryPoint` is the same as the one used for TLS traffic.<br /> More information [here](#http3. | - | No |
|
||||
| `http3.advertisedPort` | Set the UDP port to advertise as the HTTP/3 authority. <br /> It defaults to the entryPoint's address port. <br /> It can be used to override the authority in the `alt-svc` header, for example if the public facing port is different from where Traefik is listening. | - | No |
|
||||
| `observability.accessLogs` | Defines whether a router attached to this EntryPoint produces access-logs by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
|
||||
| `observability.metrics` | Defines whether a router attached to this EntryPoint produces metrics by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
|
||||
| `observability.tracing` | Defines whether a router attached to this EntryPoint produces traces by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
|
||||
| `observability.traceVerbosity` | Defines the tracing verbosity level for routers attached to this EntryPoint. Possible values: `minimal` (default), `detailed`. Routers can override this value in their own observability configuration. <br /> More information [here](#traceverbosity). | minimal | No |
|
||||
| `proxyProtocol.trustedIPs` | Enable PROXY protocol with Trusted IPs. <br /> Traefik supports [PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2. <br /> If PROXY protocol header parsing is enabled for the entry point, this entry point can accept connections with or without PROXY protocol headers. <br /> If the PROXY protocol header is passed, then the version is determined automatically.<br /> More information [here](#proxyprotocol-and-load-balancers). | - | No |
|
||||
| `proxyProtocol.insecure` | Enable PROXY protocol trusting every incoming connection. <br /> Every remote client address will be replaced (`trustedIPs`) won't have any effect). <br /> Traefik supports [PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2. <br /> If PROXY protocol header parsing is enabled for the entry point, this entry point can accept connections with or without PROXY protocol headers. <br /> If the PROXY protocol header is passed, then the version is determined automatically.<br />We recommend to use this option only for tests purposes, not in production.<br /> More information [here](#proxyprotocol-and-load-balancers). | - | No |
|
||||
| `reusePort` | Enable `entryPoints` from the same or different processes listening on the same TCP/UDP port by utilizing the `SO_REUSEPORT` socket option. <br /> It also allows the kernel to act like a load balancer to distribute incoming connections between entry points.<br /> More information [here](#reuseport). | false | No |
|
||||
| `transport.`<br />`respondingTimeouts.`<br />`readTimeout` | Set the timeouts for incoming requests to the Traefik instance. This is the maximum duration for reading the entire request, including the body. Setting them has no effect for UDP `entryPoints`.<br /> If zero, no timeout exists. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds. | 60s (seconds) | No |
|
||||
| `transport.`<br />`respondingTimeouts.`<br />`writeTimeout` | Maximum duration before timing out writes of the response. <br /> It covers the time from the end of the request header read to the end of the response write. <br /> If zero, no timeout exists. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds. | 0s (seconds) | No |
|
||||
| `transport.`<br />`respondingTimeouts.`<br />`idleTimeout` | Maximum duration an idle (keep-alive) connection will remain idle before closing itself. <br /> If zero, no timeout exists <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds | 180s (seconds) | No |
|
||||
| `transport.`<br />`lifeCycle.`<br />`graceTimeOut` | Set the duration to give active requests a chance to finish before Traefik stops. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds <br /> In this time frame no new requests are accepted. | 10s (seconds) | No |
|
||||
| `transport.`<br />`lifeCycle.`<br />`requestAcceptGraceTimeout` | Set the duration to keep accepting requests prior to initiating the graceful termination period (as defined by the `transportlifeCycle.graceTimeOut` option). <br /> This option is meant to give downstream load-balancers sufficient time to take Traefik out of rotation. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds | 0s (seconds) | No |
|
||||
| `transport.`<br />`keepAliveMaxRequests` | Set the maximum number of requests Traefik can handle before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). <br /> Zero means no limit. | 0 | No |
|
||||
| `transport.`<br />`keepAliveMaxTime` | Set the maximum duration Traefik can handle requests before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). Zero means no limit. | 0s (seconds) | No |
|
||||
| `udp.timeout` | Define how long to wait on an idle session before releasing the related resources. <br />The Timeout value must be greater than zero. | 3s (seconds) | No |
|
||||
|
||||
### asDefault
|
||||
|
||||
@ -213,7 +214,7 @@ only routers with TLS enabled will be usable with HTTP/3.
|
||||
|
||||
### ProxyProtocol and Load-Balancers
|
||||
|
||||
The replacement of the remote client address will occur only for IP addresses listed in `trustedIPs`. This is where yoåu specify your load balancer IPs or CIDR ranges.
|
||||
The replacement of the remote client address will occur only for IP addresses listed in `trustedIPs`. This is where you specify your load balancer IPs or CIDR ranges.
|
||||
|
||||
When queuing Traefik behind another load-balancer, make sure to configure
|
||||
PROXY protocol on both sides.
|
||||
@ -271,3 +272,13 @@ Use the `reusePort` option with the other option `transport.lifeCycle.gracetimeo
|
||||
to do
|
||||
canary deployments against Traefik itself. Like upgrading Traefik version
|
||||
or reloading the static configuration without any service downtime.
|
||||
|
||||
#### Trace Verbosity
|
||||
|
||||
`observability.traceVerbosity` defines the tracing verbosity level for routers attached to this EntryPoint.
|
||||
Routers can override this value in their own observability configuration.
|
||||
|
||||
Possible values are:
|
||||
|
||||
- `minimal`: produces a single server span and one client span for each request processed by a router.
|
||||
- `detailed`: enables the creation of additional spans for each middleware executed for each request processed by a router.
|
||||
|
@ -27,16 +27,6 @@ $ traefik healthcheck
|
||||
OK: http://:8082/ping
|
||||
```
|
||||
|
||||
### URL Option
|
||||
|
||||
The URL to check can be specified with the `--url` flag, which defaults to `http://localhost:8080/ping`.
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
traefik healthcheck --url=http://localhost:8080/ping
|
||||
```
|
||||
|
||||
## Ping
|
||||
|
||||
The `/ping` health-check URL is enabled with the command-line `--ping` or config file option `[ping]`.
|
||||
|
@ -96,25 +96,27 @@ log:
|
||||
|
||||
#### Configuration Options
|
||||
|
||||
| Field | Description | Default | Required |
|
||||
|:-----------|:-----------------------------------------------------------------------------|:--------|:---------|
|
||||
| `log.otlp.http` | This instructs the exporter to send logs to the OpenTelemetry Collector using HTTP.| | No |
|
||||
| `log.otlp.http.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<scheme>://<host>:<port><path>`) | `https://localhost:4318/v1/logs` | No |
|
||||
| `log.otlp.http.headers` | Additional headers sent with logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
|
||||
| `log.otlp.http.tls` | Defines the Client TLS configuration used by the exporter to send logs to the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.http.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
|
||||
| `log.otlp.http.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.http.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.http.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
|
||||
| `log.otlp.grpc` | This instructs the exporter to send logs to the OpenTelemetry Collector using gRPC.| | No |
|
||||
| `log.otlp.grpc.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<host>:<port>`) | `localhost:4317` | No |
|
||||
| `log.otlp.grpc.headers` | Additional headers sent with logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
|
||||
| `log.otlp.grpc.insecure` | Instructs the exporter to send logs to the OpenTelemetry Collector using an insecure protocol. | false | No |
|
||||
| `log.otlp.grpc.tls` | Defines the Client TLS configuration used by the exporter to send logs to the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.grpc.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
|
||||
| `log.otlp.grpc.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.grpc.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.grpc.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
|
||||
| Field | Description | Default | Required |
|
||||
|:---------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------|:---------|
|
||||
| `log.otlp.serviceName` | Service name used in selected backend. | "traefik" | No |
|
||||
| `log.otlp.resourceAttributes` | Defines additional resource attributes to be sent to the collector. | [] | No |
|
||||
| `log.otlp.http` | This instructs the exporter to send logs to the OpenTelemetry Collector using HTTP. | | No |
|
||||
| `log.otlp.http.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<scheme>://<host>:<port><path>`) | `https://localhost:4318/v1/logs` | No |
|
||||
| `log.otlp.http.headers` | Additional headers sent with logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
|
||||
| `log.otlp.http.tls` | Defines the Client TLS configuration used by the exporter to send logs to the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.http.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
|
||||
| `log.otlp.http.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.http.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.http.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
|
||||
| `log.otlp.grpc` | This instructs the exporter to send logs to the OpenTelemetry Collector using gRPC. | | No |
|
||||
| `log.otlp.grpc.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<host>:<port>`) | `localhost:4317` | No |
|
||||
| `log.otlp.grpc.headers` | Additional headers sent with logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
|
||||
| `log.otlp.grpc.insecure` | Instructs the exporter to send logs to the OpenTelemetry Collector using an insecure protocol. | false | No |
|
||||
| `log.otlp.grpc.tls` | Defines the Client TLS configuration used by the exporter to send logs to the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.grpc.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
|
||||
| `log.otlp.grpc.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.grpc.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
|
||||
| `log.otlp.grpc.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
|
||||
|
||||
## AccessLogs
|
||||
|
||||
@ -256,25 +258,27 @@ accesslog:
|
||||
|
||||
#### Configuration Options
|
||||
|
||||
| Field | Description | Default | Required |
|
||||
|:-----------|:--------------------------|:--------|:---------|
|
||||
| `accesslog.otlp.http` | This instructs the exporter to send access logs to the OpenTelemetry Collector using HTTP.| | No |
|
||||
| `accesslog.otlp.http.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<scheme>://<host>:<port><path>`) | `https://localhost:4318/v1/logs` | No |
|
||||
| `accesslog.otlp.http.headers` | Additional headers sent with access logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
|
||||
| `accesslog.otlp.http.tls` | Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.http.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
|
||||
| `accesslog.otlp.http.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.http.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.http.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
|
||||
| `accesslog.otlp.grpc` | This instructs the exporter to send access logs to the OpenTelemetry Collector using gRPC.| | No |
|
||||
| `accesslog.otlp.grpc.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<host>:<port>`) | `localhost:4317` | No |
|
||||
| `accesslog.otlp.grpc.headers` | Additional headers sent with access logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
|
||||
| `accesslog.otlp.grpc.insecure` | Instructs the exporter to send access logs to the OpenTelemetry Collector using an insecure protocol. | false | No |
|
||||
| `accesslog.otlp.grpc.tls` | Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.grpc.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
|
||||
| `accesslog.otlp.grpc.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.grpc.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.grpc.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
|
||||
| Field | Description | Default | Required |
|
||||
|:---------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------|:---------|
|
||||
| `accesslog.otlp.serviceName` | Defines the service name resource attribute. | "traefik" | No |
|
||||
| `accesslog.otlp.resourceAttributes` | Defines additional resource attributes to be sent to the collector. | [] | No |
|
||||
| `accesslog.otlp.http` | This instructs the exporter to send access logs to the OpenTelemetry Collector using HTTP. | | No |
|
||||
| `accesslog.otlp.http.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<scheme>://<host>:<port><path>`) | `https://localhost:4318/v1/logs` | No |
|
||||
| `accesslog.otlp.http.headers` | Additional headers sent with access logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
|
||||
| `accesslog.otlp.http.tls` | Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.http.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
|
||||
| `accesslog.otlp.http.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.http.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.http.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
|
||||
| `accesslog.otlp.grpc` | This instructs the exporter to send access logs to the OpenTelemetry Collector using gRPC. | | No |
|
||||
| `accesslog.otlp.grpc.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<host>:<port>`) | `localhost:4317` | No |
|
||||
| `accesslog.otlp.grpc.headers` | Additional headers sent with access logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
|
||||
| `accesslog.otlp.grpc.insecure` | Instructs the exporter to send access logs to the OpenTelemetry Collector using an insecure protocol. | false | No |
|
||||
| `accesslog.otlp.grpc.tls` | Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.grpc.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
|
||||
| `accesslog.otlp.grpc.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.grpc.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
|
||||
| `accesslog.otlp.grpc.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
|
||||
|
||||
### CLF format fields
|
||||
|
||||
|
@ -60,29 +60,31 @@ metrics:
|
||||
|
||||
### Configuration Options
|
||||
|
||||
| Field | Description | Default | Required |
|
||||
|:-----------|---------------|:--------|:---------|
|
||||
| `metrics.addInternals` | Enables metrics for internal resources (e.g.: `ping@internal`). | false | No |
|
||||
| `metrics.otlp.addEntryPointsLabels` | Enable metrics on entry points. | true | No |
|
||||
| `metrics.otlp.addRoutersLabels` | Enable metrics on routers. | false | No |
|
||||
| `metrics.otlp.addServicesLabels` | Enable metrics on services.| true | No |
|
||||
| `metrics.otlp.explicitBoundaries` | Explicit boundaries for Histogram data points. | ".005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10" | No |
|
||||
| `metrics.otlp.pushInterval` | Interval at which metrics are sent to the OpenTelemetry Collector. | 10s | No |
|
||||
| `metrics.otlp.http` | This instructs the exporter to send the metrics to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | null/false | No |
|
||||
| `metrics.otlp.http.endpoint` | URL of the OpenTelemetry Collector to send metrics to.<br /> Format="`<scheme>://<host>:<port><path>`" | "http://localhost:4318/v1/metrics" | Yes |
|
||||
| `metrics.otlp.http.headers` | Additional headers sent with metrics by the exporter to the OpenTelemetry Collector. | - | No |
|
||||
| `metrics.otlp.http.tls.ca` | Path to the certificate authority used for the secure connection to the OpenTelemetry Collector,<br />it defaults to the system bundle. | "" | No |
|
||||
| `metrics.otlp.http.tls.cert` | Path to the public certificate used for the secure connection to the OpenTelemetry Collector.<br />When using this option, setting the `key` option is required. | "" | No |
|
||||
| `metrics.otlp.http.tls.key` | This instructs the exporter to send the metrics to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | null/false | No |
|
||||
| `metrics.otlp.http.tls.insecureskipverify` | Allow the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
| `metrics.otlp.grpc` | This instructs the exporter to send metrics to the OpenTelemetry Collector using gRPC. | null/false | No |
|
||||
| `metrics.otlp.grpc.endpoint` | Address of the OpenTelemetry Collector to send metrics to.<br /> Format="`<host>:<port>`" | "localhost:4317" | Yes |
|
||||
| `metrics.otlp.grpc.headers` | Additional headers sent with metrics by the exporter to the OpenTelemetry Collector. | - | No |
|
||||
| `metrics.otlp.http.grpc.insecure` |Allows exporter to send metrics to the OpenTelemetry Collector without using a secured protocol. | false | Yes |
|
||||
| `metrics.otlp.grpc.tls.ca` | Path to the certificate authority used for the secure connection to the OpenTelemetry Collector,<br />it defaults to the system bundle. | - | No |
|
||||
| `metrics.otlp.grpc.tls.cert` | Path to the public certificate used for the secure connection to the OpenTelemetry Collector.<br />When using this option, setting the `key` option is required. | - | No |
|
||||
| `metrics.otlp.grpc.tls.key` | This instructs the exporter to send the metrics to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | null/false | No |
|
||||
| `metrics.otlp.grpc.tls.insecureskipverify` | Allow the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
| Field | Description | Default | Required |
|
||||
|:-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------|:---------|
|
||||
| `metrics.addInternals` | Enables metrics for internal resources (e.g.: `ping@internal`). | false | No |
|
||||
| `metrics.otlp.serviceName` | Defines the service name resource attribute. | "traefik" | No |
|
||||
| `metrics.otlp.resourceAttributes` | Defines additional resource attributes to be sent to the collector. | [] | No |
|
||||
| `metrics.otlp.addEntryPointsLabels` | Enable metrics on entry points. | true | No |
|
||||
| `metrics.otlp.addRoutersLabels` | Enable metrics on routers. | false | No |
|
||||
| `metrics.otlp.addServicesLabels` | Enable metrics on services. | true | No |
|
||||
| `metrics.otlp.explicitBoundaries` | Explicit boundaries for Histogram data points. | ".005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10" | No |
|
||||
| `metrics.otlp.pushInterval` | Interval at which metrics are sent to the OpenTelemetry Collector. | 10s | No |
|
||||
| `metrics.otlp.http` | This instructs the exporter to send the metrics to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | null/false | No |
|
||||
| `metrics.otlp.http.endpoint` | URL of the OpenTelemetry Collector to send metrics to.<br /> Format="`<scheme>://<host>:<port><path>`" | "http://localhost:4318/v1/metrics" | Yes |
|
||||
| `metrics.otlp.http.headers` | Additional headers sent with metrics by the exporter to the OpenTelemetry Collector. | - | No |
|
||||
| `metrics.otlp.http.tls.ca` | Path to the certificate authority used for the secure connection to the OpenTelemetry Collector,<br />it defaults to the system bundle. | "" | No |
|
||||
| `metrics.otlp.http.tls.cert` | Path to the public certificate used for the secure connection to the OpenTelemetry Collector.<br />When using this option, setting the `key` option is required. | "" | No |
|
||||
| `metrics.otlp.http.tls.key` | This instructs the exporter to send the metrics to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | null/false | No |
|
||||
| `metrics.otlp.http.tls.insecureskipverify` | Allow the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
| `metrics.otlp.grpc` | This instructs the exporter to send metrics to the OpenTelemetry Collector using gRPC. | null/false | No |
|
||||
| `metrics.otlp.grpc.endpoint` | Address of the OpenTelemetry Collector to send metrics to.<br /> Format="`<host>:<port>`" | "localhost:4317" | Yes |
|
||||
| `metrics.otlp.grpc.headers` | Additional headers sent with metrics by the exporter to the OpenTelemetry Collector. | - | No |
|
||||
| `metrics.otlp.http.grpc.insecure` | Allows exporter to send metrics to the OpenTelemetry Collector without using a secured protocol. | false | Yes |
|
||||
| `metrics.otlp.grpc.tls.ca` | Path to the certificate authority used for the secure connection to the OpenTelemetry Collector,<br />it defaults to the system bundle. | - | No |
|
||||
| `metrics.otlp.grpc.tls.cert` | Path to the public certificate used for the secure connection to the OpenTelemetry Collector.<br />When using this option, setting the `key` option is required. | - | No |
|
||||
| `metrics.otlp.grpc.tls.key` | This instructs the exporter to send the metrics to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | null/false | No |
|
||||
| `metrics.otlp.grpc.tls.insecureskipverify` | Allow the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
|
||||
## Vendors
|
||||
|
||||
|
@ -36,27 +36,27 @@ tracing: {}
|
||||
|
||||
## Configuration Options
|
||||
|
||||
| Field | Description | Default | Required |
|
||||
|:-------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------|:---------|
|
||||
| `tracing.addInternals` | Enables tracing for internal resources (e.g.: `ping@internal`). | false | No |
|
||||
| `tracing.serviceName` | Service name used in selected backend. | "traefik" | No |
|
||||
| `tracing.sampleRate` | The proportion of requests to trace, specified between 0.0 and 1.0. | 1.0 | No |
|
||||
| `tracing.resourceAttributes` | Defines additional resource attributes to be sent to the collector. | [] | No |
|
||||
| `tracing.capturedRequestHeaders` | Defines the list of request headers to add as attributes.<br />It applies to client and server kind spans.| [] | No |
|
||||
| `tracing.capturedResponseHeaders` | Defines the list of response headers to add as attributes.<br />It applies to client and server kind spans.| [] |False |
|
||||
| `tracing.safeQueryParams` | By default, all query parameters are redacted.<br />Defines the list of query parameters to not redact. | [] | No |
|
||||
| `tracing.otlp.http` | This instructs the exporter to send the tracing to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | null/false | No |
|
||||
| `tracing.otlp.http.endpoint` | URL of the OpenTelemetry Collector to send tracing to.<br /> Format="`<scheme>://<host>:<port><path>`" | "http://localhost:4318/v1/tracing" | Yes |
|
||||
| `tracing.otlp.http.headers` | Additional headers sent with tracing by the exporter to the OpenTelemetry Collector. | | No |
|
||||
| `tracing.otlp.http.tls.ca` | Path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | "" | No |
|
||||
| `tracing.otlp.http.tls.cert` | Path to the public certificate used for the secure connection to the OpenTelemetry Collector. When using this option, setting the `key` option is required. | "" | No |
|
||||
| `tracing.otlp.http.tls.key` | This instructs the exporter to send the tracing to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | ""null/false "" | No |
|
||||
| `tracing.otlp.http.tls.insecureskipverify` |If `insecureSkipVerify` is `true`, the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
| `tracing.otlp.grpc` | This instructs the exporter to send tracing to the OpenTelemetry Collector using gRPC. | false | No |
|
||||
| `tracing.otlp.grpc.endpoint` | Address of the OpenTelemetry Collector to send tracing to.<br /> Format="`<host>:<port>`" | "localhost:4317" | Yes |
|
||||
| `tracing.otlp.grpc.headers` | Additional headers sent with tracing by the exporter to the OpenTelemetry Collector. | [] | No |
|
||||
| `tracing.otlp.grpc.insecure` |Allows exporter to send tracing to the OpenTelemetry Collector without using a secured protocol. | false | Yes |
|
||||
| `tracing.otlp.grpc.tls.ca` | Path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | "" | No |
|
||||
| `tracing.otlp.grpc.tls.cert` | Path to the public certificate used for the secure connection to the OpenTelemetry Collector. When using this option, setting the `key` option is required. | "" | No |
|
||||
| `tracing.otlp.grpc.tls.key` | This instructs the exporter to send the tracing to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | ""null/false "" | No |
|
||||
| `tracing.otlp.grpc.tls.insecureskipverify` |If `insecureSkipVerify` is `true`, the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
| Field | Description | Default | Required |
|
||||
|:-------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------|:---------|
|
||||
| `tracing.addInternals` | Enables tracing for internal resources (e.g.: `ping@internal`). | false | No |
|
||||
| `tracing.serviceName` | Defines the service name resource attribute. | "traefik" | No |
|
||||
| `tracing.resourceAttributes` | Defines additional resource attributes to be sent to the collector. | [] | No |
|
||||
| `tracing.sampleRate` | The proportion of requests to trace, specified between 0.0 and 1.0. | 1.0 | No |
|
||||
| `tracing.capturedRequestHeaders` | Defines the list of request headers to add as attributes.<br />It applies to client and server kind spans. | [] | No |
|
||||
| `tracing.capturedResponseHeaders` | Defines the list of response headers to add as attributes.<br />It applies to client and server kind spans. | [] | False |
|
||||
| `tracing.safeQueryParams` | By default, all query parameters are redacted.<br />Defines the list of query parameters to not redact. | [] | No |
|
||||
| `tracing.otlp.http` | This instructs the exporter to send the tracing to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | null/false | No |
|
||||
| `tracing.otlp.http.endpoint` | URL of the OpenTelemetry Collector to send tracing to.<br /> Format="`<scheme>://<host>:<port><path>`" | "http://localhost:4318/v1/tracing" | Yes |
|
||||
| `tracing.otlp.http.headers` | Additional headers sent with tracing by the exporter to the OpenTelemetry Collector. | | No |
|
||||
| `tracing.otlp.http.tls.ca` | Path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | "" | No |
|
||||
| `tracing.otlp.http.tls.cert` | Path to the public certificate used for the secure connection to the OpenTelemetry Collector. When using this option, setting the `key` option is required. | "" | No |
|
||||
| `tracing.otlp.http.tls.key` | This instructs the exporter to send the tracing to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | ""null/false "" | No |
|
||||
| `tracing.otlp.http.tls.insecureskipverify` | If `insecureSkipVerify` is `true`, the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
| `tracing.otlp.grpc` | This instructs the exporter to send tracing to the OpenTelemetry Collector using gRPC. | false | No |
|
||||
| `tracing.otlp.grpc.endpoint` | Address of the OpenTelemetry Collector to send tracing to.<br /> Format="`<host>:<port>`" | "localhost:4317" | Yes |
|
||||
| `tracing.otlp.grpc.headers` | Additional headers sent with tracing by the exporter to the OpenTelemetry Collector. | [] | No |
|
||||
| `tracing.otlp.grpc.insecure` | Allows exporter to send tracing to the OpenTelemetry Collector without using a secured protocol. | false | Yes |
|
||||
| `tracing.otlp.grpc.tls.ca` | Path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | "" | No |
|
||||
| `tracing.otlp.grpc.tls.cert` | Path to the public certificate used for the secure connection to the OpenTelemetry Collector. When using this option, setting the `key` option is required. | "" | No |
|
||||
| `tracing.otlp.grpc.tls.key` | This instructs the exporter to send the tracing to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | ""null/false "" | No |
|
||||
| `tracing.otlp.grpc.tls.insecureskipverify` | If `insecureSkipVerify` is `true`, the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
|
@ -270,6 +270,10 @@ created. If the expression is empty, all detected containers are included.
|
||||
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
!!! tip "Constraints key limitations"
|
||||
|
||||
Note that `traefik.*` is a reserved label namespace for configuration and can not be used as a key for custom constraints.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
|
@ -112,6 +112,10 @@ created. If the expression is empty, all detected services are included.
|
||||
The expression syntax is based on the ```Tag(`tag`)```, and ```TagRegex(`tag`)``` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
!!! tip "Constraints key limitations"
|
||||
|
||||
Note that `traefik.*` is a reserved label namespace for configuration and can not be used as a key for custom constraints.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
|
@ -191,6 +191,10 @@ created. If the expression is empty, all detected services are included.
|
||||
The expression syntax is based on the ```Tag(`tag`)```, and ```TagRegex(`tag`)``` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
!!! tip "Constraints key limitations"
|
||||
|
||||
Note that `traefik.*` is a reserved label namespace for configuration and can not be used as a key for custom constraints.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
|
@ -49,6 +49,10 @@ If the expression is empty, all detected containers are included.
|
||||
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
!!! tip "Constraints key limitations"
|
||||
|
||||
Note that `traefik.*` is a reserved label namespace for configuration and can not be used as a key for custom constraints.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
|
@ -276,6 +276,10 @@ created. If the expression is empty, all detected containers are included.
|
||||
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
!!! tip "Constraints key limitations"
|
||||
|
||||
Note that `traefik.*` is a reserved label namespace for configuration and can not be used as a key for custom constraints.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
|
@ -36,6 +36,7 @@ http:
|
||||
metrics: false
|
||||
accessLogs: false
|
||||
tracing: false
|
||||
traceVerbosity: detailed
|
||||
```
|
||||
|
||||
```yaml tab="Structured (TOML)"
|
||||
@ -47,6 +48,7 @@ http:
|
||||
metrics = false
|
||||
accessLogs = false
|
||||
tracing = false
|
||||
traceVerbosity = "detailed"
|
||||
```
|
||||
|
||||
```yaml tab="Labels"
|
||||
@ -56,6 +58,7 @@ labels:
|
||||
- "traefik.http.routers.my-router.observability.metrics=false"
|
||||
- "traefik.http.routers.my-router.observability.accessLogs=false"
|
||||
- "traefik.http.routers.my-router.observability.tracing=false"
|
||||
- "traefik.http.routers.my-router.observability.traceVerbosity=detailed"
|
||||
```
|
||||
|
||||
```json tab="Tags"
|
||||
@ -66,15 +69,26 @@ labels:
|
||||
"traefik.http.routers.my-router.service=service-foo",
|
||||
"traefik.http.routers.my-router.observability.metrics=false",
|
||||
"traefik.http.routers.my-router.observability.accessLogs=false",
|
||||
"traefik.http.routers.my-router.observability.tracing=false"
|
||||
"traefik.http.routers.my-router.observability.tracing=false",
|
||||
"traefik.http.routers.my-router.observability.traceVerbosity=detailed"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
| Field | Description | Default | Required |
|
||||
|:------|:------------|:--------|:---------|
|
||||
| `accessLogs` | The `accessLogs` option controls whether the router will produce access-logs. | `true` | No |
|
||||
| `metrics` | The `metrics` option controls whether the router will produce metrics. | `true` | No |
|
||||
| `tracing` | The `tracing` option controls whether the router will produce traces. | `true` | No |
|
||||
| Field | Description | Default | Required |
|
||||
|:-----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------|:---------|
|
||||
| `accessLogs` | The `accessLogs` option controls whether the router will produce access-logs. | `true` | No |
|
||||
| `metrics` | The `metrics` option controls whether the router will produce metrics. | `true` | No |
|
||||
| `tracing` | The `tracing` option controls whether the router will produce traces. | `true` | No |
|
||||
| `traceVerbosity` | The `traceVerbosity` option controls the tracing verbosity level for the router. Possible values: `minimal` (default), `detailed`. If not set, the value is inherited from the entryPoint. | `minimal` | No |
|
||||
|
||||
#### traceVerbosity
|
||||
|
||||
`observability.traceVerbosity` defines the tracing verbosity level for the router.
|
||||
|
||||
Possible values are:
|
||||
|
||||
- `minimal`: produces a single server span and one client span for each request processed by a router.
|
||||
- `detailed`: enables the creation of additional spans for each middleware executed for each request processed by a router.
|
||||
|
@ -106,7 +106,7 @@ tls:
|
||||
|
||||
### Curve Preferences
|
||||
|
||||
This option allows to set the preferred elliptic curves in a specific order.
|
||||
This option allows to set the preferred elliptic curves.
|
||||
|
||||
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
|
||||
|
||||
|
@ -51,7 +51,7 @@ spec:
|
||||
| `minVersion` | Minimum TLS version that is acceptable. | "VersionTLS12" | No |
|
||||
| `maxVersion` | Maximum TLS version that is acceptable.<br />We do not recommend setting this option to disable TLS 1.3. | | No |
|
||||
| `cipherSuites` | List of supported [cipher suites](https://godoc.org/crypto/tls#pkg-constants) for TLS versions up to TLS 1.2.<br />[Cipher suites defined for TLS 1.2 and below cannot be used in TLS 1.3, and vice versa.](https://tools.ietf.org/html/rfc8446)<br />With TLS 1.3, [the cipher suites are not configurable](https://golang.org/doc/go1.12#tls_1_3) (all supported cipher suites are safe in this case). | | No |
|
||||
| `curvePreferences` | List of the elliptic curves references that will be used in an ECDHE handshake, in preference order.<br />Use curves names from [`crypto`](https://godoc.org/crypto/tls#CurveID) or the [RFC](https://tools.ietf.org/html/rfc8446#section-4.2.7).<br />See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information. | | No |
|
||||
| `curvePreferences` | List of the elliptic curves references that will be used in an ECDHE handshake.<br />Use curves names from [`crypto`](https://godoc.org/crypto/tls#CurveID) or the [RFC](https://tools.ietf.org/html/rfc8446#section-4.2.7).<br />See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information. | | No |
|
||||
| `clientAuth.secretNames` | Client Authentication (mTLS) option.<br />List of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace).<br /> The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. | | No |
|
||||
| `clientAuth.clientAuthType` | Client Authentication (mTLS) option.<br />Client authentication type to apply. Available values [here](#client-authentication-mtls). | | No |
|
||||
| `sniStrict` | Allow rejecting connections from clients connections that do not specify a server_name extension.<br />The [default certificate](../../../http/tls/tls-certificates.md#default-certificate) is never served is the option is enabled. | false | No |
|
||||
@ -60,7 +60,7 @@ spec:
|
||||
|
||||
### Client Authentication (mTLS)
|
||||
|
||||
The `clientAuth.clientAuthType` option governs the behaviour as follows:
|
||||
The `clientAuth.clientAuthType` option governs the behavior as follows:
|
||||
|
||||
- `NoClientCert`: disregards any client certificate.
|
||||
- `RequestClientCert`: asks for a certificate but proceeds anyway if none is provided.
|
||||
|
@ -296,99 +296,107 @@ Limitations or behavioral differences are indicated where relevant.
|
||||
|
||||
### Unsupported NGINX Annotations
|
||||
|
||||
All other NGINX annotations not listed above, including but not limited to:
|
||||
!!! question "Want to Add Support for More Annotations?"
|
||||
|
||||
You can help extend support in two ways:
|
||||
|
||||
- [**Open a PR**](../../../contributing/submitting-pull-requests.md) with the new annotation support.
|
||||
- **Reach out** to the [Traefik Labs support team](https://info.traefik.io/request-commercial-support?cta=doc).
|
||||
|
||||
All contributions and suggestions are welcome — let's build this together!
|
||||
|
||||
|
||||
| Annotation | Notes |
|
||||
|-----------------------------------------------------------------------------|------------------------------------------------------|
|
||||
| `nginx.ingress.kubernetes.io/app-root` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/affinity-canary-behavior` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-secret` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-verify-depth` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-verify-client` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-error-page` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-match-cn` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-cache-key` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-cache-duration` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-keepalive` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-keepalive-share-vars` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-keepalive-requests` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-keepalive-timeout` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-proxy-set-headers` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/auth-snippet` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/enable-global-auth` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/canary` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/canary-by-header` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/canary-by-header-value` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/canary-by-header-pattern` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/canary-by-cookie` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/canary-weight` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/canary-weight-total` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/client-body-buffer-size` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/configuration-snippet` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/custom-http-errors` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/disable-proxy-intercept-errors` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/default-backend` | Not supported; use `defaultBackend` in Ingress spec. |
|
||||
| `nginx.ingress.kubernetes.io/limit-rate-after` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/limit-rate` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/limit-whitelist` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/limit-rps` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/limit-rpm` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/limit-burst-multiplier` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/limit-connections` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/global-rate-limit` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/global-rate-limit-window` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/global-rate-limit-key` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/global-rate-limit-ignored-cidrs` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/permanent-redirect` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/permanent-redirect-code` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/temporal-redirect` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/preserve-trailing-slash` | Not supported; Traefik preserves by default. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-cookie-domain` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-cookie-path` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-connect-timeout` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-send-timeout` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-read-timeout` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-next-upstream` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-next-upstream-timeout` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-next-upstream-tries` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-request-buffering` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-redirect-from` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-redirect-to` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-http-version` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-ssl-ciphers` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-ssl-verify-depth` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-ssl-protocols` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/enable-rewrite-log` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/rewrite-target` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/satisfy` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/server-alias` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/server-snippet` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/session-cookie-expires` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/session-cookie-change-on-failure` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/ssl-ciphers` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/ssl-prefer-server-ciphers` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/connection-proxy-header` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/enable-access-log` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/enable-opentracing` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/opentracing-trust-incoming-span` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/enable-opentelemetry` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/enable-modsecurity` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/enable-owasp-core-rules` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/modsecurity-transaction-id` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/modsecurity-snippet` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/mirror-request-body` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/mirror-target` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/mirror-host` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/x-forwarded-prefix` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/upstream-hash-by` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/upstream-vhost` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/denylist-source-range` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/whitelist-source-range` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-buffering` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-buffers-number` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-buffer-size` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-max-temp-file-size` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/stream-snippet` | Not supported. |
|
||||
| `nginx.ingress.kubernetes.io/app-root` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/affinity-canary-behavior` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-secret` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-verify-depth` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-verify-client` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-error-page` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-tls-match-cn` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-cache-key` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-cache-duration` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-keepalive` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-keepalive-share-vars` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-keepalive-requests` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-keepalive-timeout` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-proxy-set-headers` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/auth-snippet` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/enable-global-auth` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/canary` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/canary-by-header` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/canary-by-header-value` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/canary-by-header-pattern` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/canary-by-cookie` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/canary-weight` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/canary-weight-total` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/client-body-buffer-size` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/configuration-snippet` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/custom-http-errors` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/disable-proxy-intercept-errors` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/default-backend` | Not supported yet; use `defaultBackend` in Ingress spec. |
|
||||
| `nginx.ingress.kubernetes.io/limit-rate-after` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/limit-rate` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/limit-whitelist` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/limit-rps` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/limit-rpm` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/limit-burst-multiplier` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/limit-connections` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/global-rate-limit` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/global-rate-limit-window` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/global-rate-limit-key` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/global-rate-limit-ignored-cidrs` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/permanent-redirect` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/permanent-redirect-code` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/temporal-redirect` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/preserve-trailing-slash` | Not supported yet; Traefik preserves by default. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-cookie-domain` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-cookie-path` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-connect-timeout` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-send-timeout` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-read-timeout` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-next-upstream` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-next-upstream-timeout` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-next-upstream-tries` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-request-buffering` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-redirect-from` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-redirect-to` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-http-version` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-ssl-ciphers` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-ssl-verify-depth` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-ssl-protocols` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/enable-rewrite-log` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/rewrite-target` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/satisfy` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/server-alias` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/server-snippet` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/session-cookie-expires` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/session-cookie-change-on-failure` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/ssl-ciphers` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/ssl-prefer-server-ciphers` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/connection-proxy-header` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/enable-access-log` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/enable-opentracing` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/opentracing-trust-incoming-span` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/enable-opentelemetry` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/enable-modsecurity` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/enable-owasp-core-rules` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/modsecurity-transaction-id` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/modsecurity-snippet` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/mirror-request-body` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/mirror-target` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/mirror-host` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/x-forwarded-prefix` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/upstream-hash-by` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/upstream-vhost` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/denylist-source-range` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/whitelist-source-range` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-buffering` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-buffers-number` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-buffer-size` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/proxy-max-temp-file-size` | Not supported yet. |
|
||||
| `nginx.ingress.kubernetes.io/stream-snippet` | Not supported yet. |
|
||||
|
@ -91,7 +91,7 @@ TLS key
|
||||
Defines additional resource attributes (key:value).
|
||||
|
||||
`--accesslog.otlp.servicename`:
|
||||
Set the name for this service. (Default: ```traefik```)
|
||||
Defines the service name resource attribute. (Default: ```traefik```)
|
||||
|
||||
`--api`:
|
||||
Enable api/dashboard. (Default: ```false```)
|
||||
@ -283,13 +283,16 @@ HTTP/3 configuration. (Default: ```false```)
|
||||
UDP port to advertise, on which HTTP/3 is available. (Default: ```0```)
|
||||
|
||||
`--entrypoints.<name>.observability.accesslogs`:
|
||||
(Default: ```true```)
|
||||
Enables access-logs for this entryPoint. (Default: ```true```)
|
||||
|
||||
`--entrypoints.<name>.observability.metrics`:
|
||||
(Default: ```true```)
|
||||
Enables metrics for this entryPoint. (Default: ```true```)
|
||||
|
||||
`--entrypoints.<name>.observability.traceverbosity`:
|
||||
Defines the tracing verbosity level for this entryPoint. (Default: ```minimal```)
|
||||
|
||||
`--entrypoints.<name>.observability.tracing`:
|
||||
(Default: ```true```)
|
||||
Enables tracing for this entryPoint. (Default: ```true```)
|
||||
|
||||
`--entrypoints.<name>.proxyprotocol`:
|
||||
Proxy-Protocol configuration. (Default: ```false```)
|
||||
@ -478,7 +481,7 @@ TLS key
|
||||
Defines additional resource attributes (key:value).
|
||||
|
||||
`--log.otlp.servicename`:
|
||||
Set the name for this service. (Default: ```traefik```)
|
||||
Defines the service name resource attribute. (Default: ```traefik```)
|
||||
|
||||
`--metrics.addinternals`:
|
||||
Enables metrics for internal services (ping, dashboard, etc...). (Default: ```false```)
|
||||
@ -597,8 +600,11 @@ TLS key
|
||||
`--metrics.otlp.pushinterval`:
|
||||
Period between calls to collect a checkpoint. (Default: ```10```)
|
||||
|
||||
`--metrics.otlp.resourceattributes.<name>`:
|
||||
Defines additional resource attributes (key:value).
|
||||
|
||||
`--metrics.otlp.servicename`:
|
||||
OTEL service name to use. (Default: ```traefik```)
|
||||
Defines the service name resource attribute. (Default: ```traefik```)
|
||||
|
||||
`--metrics.prometheus`:
|
||||
Prometheus metrics exporter type. (Default: ```false```)
|
||||
@ -1411,4 +1417,4 @@ Query params to not redact.
|
||||
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
|
||||
|
||||
`--tracing.servicename`:
|
||||
Sets the name for this service. (Default: ```traefik```)
|
||||
Defines the service name resource attribute. (Default: ```traefik```)
|
||||
|
@ -91,7 +91,7 @@ TLS key
|
||||
Defines additional resource attributes (key:value).
|
||||
|
||||
`TRAEFIK_ACCESSLOG_OTLP_SERVICENAME`:
|
||||
Set the name for this service. (Default: ```traefik```)
|
||||
Defines the service name resource attribute. (Default: ```traefik```)
|
||||
|
||||
`TRAEFIK_API`:
|
||||
Enable api/dashboard. (Default: ```false```)
|
||||
@ -283,13 +283,16 @@ Subject alternative names.
|
||||
Default TLS options for the routers linked to the entry point.
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_OBSERVABILITY_ACCESSLOGS`:
|
||||
(Default: ```true```)
|
||||
Enables access-logs for this entryPoint. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_OBSERVABILITY_METRICS`:
|
||||
(Default: ```true```)
|
||||
Enables metrics for this entryPoint. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_OBSERVABILITY_TRACEVERBOSITY`:
|
||||
Defines the tracing verbosity level for this entryPoint. (Default: ```minimal```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_OBSERVABILITY_TRACING`:
|
||||
(Default: ```true```)
|
||||
Enables tracing for this entryPoint. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_PROXYPROTOCOL`:
|
||||
Proxy-Protocol configuration. (Default: ```false```)
|
||||
@ -478,7 +481,7 @@ TLS key
|
||||
Defines additional resource attributes (key:value).
|
||||
|
||||
`TRAEFIK_LOG_OTLP_SERVICENAME`:
|
||||
Set the name for this service. (Default: ```traefik```)
|
||||
Defines the service name resource attribute. (Default: ```traefik```)
|
||||
|
||||
`TRAEFIK_METRICS_ADDINTERNALS`:
|
||||
Enables metrics for internal services (ping, dashboard, etc...). (Default: ```false```)
|
||||
@ -597,8 +600,11 @@ TLS key
|
||||
`TRAEFIK_METRICS_OTLP_PUSHINTERVAL`:
|
||||
Period between calls to collect a checkpoint. (Default: ```10```)
|
||||
|
||||
`TRAEFIK_METRICS_OTLP_RESOURCEATTRIBUTES_<NAME>`:
|
||||
Defines additional resource attributes (key:value).
|
||||
|
||||
`TRAEFIK_METRICS_OTLP_SERVICENAME`:
|
||||
OTEL service name to use. (Default: ```traefik```)
|
||||
Defines the service name resource attribute. (Default: ```traefik```)
|
||||
|
||||
`TRAEFIK_METRICS_PROMETHEUS`:
|
||||
Prometheus metrics exporter type. (Default: ```false```)
|
||||
@ -1411,4 +1417,4 @@ Query params to not redact.
|
||||
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
|
||||
|
||||
`TRAEFIK_TRACING_SERVICENAME`:
|
||||
Sets the name for this service. (Default: ```traefik```)
|
||||
Defines the service name resource attribute. (Default: ```traefik```)
|
||||
|
@ -80,8 +80,9 @@
|
||||
timeout = "42s"
|
||||
[entryPoints.EntryPoint0.observability]
|
||||
accessLogs = true
|
||||
tracing = true
|
||||
metrics = true
|
||||
tracing = true
|
||||
traceVerbosity = "foobar"
|
||||
|
||||
[providers]
|
||||
providersThrottleDuration = "42s"
|
||||
@ -387,6 +388,9 @@
|
||||
[metrics.otlp.http.headers]
|
||||
name0 = "foobar"
|
||||
name1 = "foobar"
|
||||
[metrics.otlp.resourceAttributes]
|
||||
name0 = "foobar"
|
||||
name1 = "foobar"
|
||||
|
||||
[ping]
|
||||
entryPoint = "foobar"
|
||||
|
@ -94,8 +94,9 @@ entryPoints:
|
||||
timeout: 42s
|
||||
observability:
|
||||
accessLogs: true
|
||||
tracing: true
|
||||
metrics: true
|
||||
tracing: true
|
||||
traceVerbosity: foobar
|
||||
providers:
|
||||
providersThrottleDuration: 42s
|
||||
docker:
|
||||
@ -428,6 +429,9 @@ metrics:
|
||||
- 42
|
||||
pushInterval: 42s
|
||||
serviceName: foobar
|
||||
resourceAttributes:
|
||||
name0: foobar
|
||||
name1: foobar
|
||||
ping:
|
||||
entryPoint: foobar
|
||||
manualRouting: true
|
||||
|
@ -1671,7 +1671,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre
|
||||
| [2] | `minVersion` | Defines the [minimum TLS version](../../https/tls.md#minimum-tls-version) that is acceptable. |
|
||||
| [3] | `maxVersion` | Defines the [maximum TLS version](../../https/tls.md#maximum-tls-version) that is acceptable. |
|
||||
| [4] | `cipherSuites` | list of supported [cipher suites](../../https/tls.md#cipher-suites) for TLS versions up to TLS 1.2. |
|
||||
| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake, in preference order. |
|
||||
| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake. |
|
||||
| [6] | `clientAuth` | determines the server's policy for TLS [Client Authentication](../../https/tls.md#client-authentication-mtls). |
|
||||
| [7] | `clientAuth.secretNames` | list of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace). The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. |
|
||||
| [8] | `clientAuth.clientAuthType` | defines the client authentication type to apply. The available values are: `NoClientCert`, `RequestClientCert`, `VerifyClientCertIfGiven` and `RequireAndVerifyClientCert`. |
|
||||
|
5
go.mod
5
go.mod
@ -55,7 +55,7 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // No tag on the repo.
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/quic-go/quic-go v0.49.0
|
||||
github.com/quic-go/quic-go v0.54.0
|
||||
github.com/redis/go-redis/v9 v9.7.3
|
||||
github.com/rs/zerolog v1.33.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
@ -206,7 +206,6 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.16.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.16.5 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
|
||||
github.com/go-zookeeper/zk v1.0.3 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
@ -218,7 +217,6 @@ require (
|
||||
github.com/google/go-cmp v0.7.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-20241029153458-d1b30febd7db // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
@ -293,7 +291,6 @@ require (
|
||||
github.com/nrdcg/porkbun v0.4.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.22.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
|
||||
|
5
go.sum
5
go.sum
@ -421,6 +421,7 @@ github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptd
|
||||
github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk=
|
||||
@ -1033,8 +1034,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.49.0 h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94=
|
||||
github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s=
|
||||
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
|
||||
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
||||
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/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
|
||||
|
@ -648,25 +648,6 @@ func (s *AccessLogSuite) TestAccessLogDisabledForInternals() {
|
||||
|
||||
require.Equal(s.T(), 0, count)
|
||||
|
||||
// Make some requests on the custom ping router in error.
|
||||
req, err = http.NewRequest(http.MethodGet, "http://127.0.0.1:8010/ping-error", nil)
|
||||
require.NoError(s.T(), err)
|
||||
req.Host = "ping-error.docker.local"
|
||||
|
||||
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized), try.BodyContains("X-Forwarded-Host: ping-error.docker.local"))
|
||||
require.NoError(s.T(), err)
|
||||
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized), try.BodyContains("X-Forwarded-Host: ping-error.docker.local"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// Here we verify that the remove of observability doesn't break the metrics for the error page service.
|
||||
req, err = http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/metrics", nil)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("service3"))
|
||||
require.NoError(s.T(), err)
|
||||
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyNotContains("service=\"ping"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// Verify no other Traefik problems.
|
||||
s.checkNoOtherTraefikProblems()
|
||||
}
|
||||
|
@ -92,10 +92,21 @@ spec:
|
||||
More info: https://doc.traefik.io/traefik/v3.5/routing/routers/#observability
|
||||
properties:
|
||||
accessLogs:
|
||||
description: AccessLogs enables access logs for this router.
|
||||
type: boolean
|
||||
metrics:
|
||||
description: Metrics enables metrics for this router.
|
||||
type: boolean
|
||||
traceVerbosity:
|
||||
default: minimal
|
||||
description: TraceVerbosity defines the verbosity level
|
||||
of the tracing for this router.
|
||||
enum:
|
||||
- minimal
|
||||
- detailed
|
||||
type: string
|
||||
tracing:
|
||||
description: Tracing enables tracing for this router.
|
||||
type: boolean
|
||||
type: object
|
||||
priority:
|
||||
@ -2551,7 +2562,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v3.5/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
@ -14,6 +14,10 @@
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
[entryPoints.web.observability]
|
||||
traceVerbosity = "detailed"
|
||||
[entryPoints.web-minimal]
|
||||
address = ":8001"
|
||||
|
||||
# Adding metrics to confirm that there is no wrong interaction with tracing.
|
||||
[metrics]
|
||||
@ -44,9 +48,13 @@
|
||||
## dynamic configuration ##
|
||||
|
||||
[http.routers]
|
||||
[http.routers.routerBasicMinimal]
|
||||
Service = "service0"
|
||||
Rule = "Path(`/basic-minimal`)"
|
||||
[http.routers.routerBasicMinimal.observability]
|
||||
traceVerbosity = "minimal"
|
||||
[http.routers.router0]
|
||||
Service = "service0"
|
||||
Middlewares = []
|
||||
Rule = "Path(`/basic`)"
|
||||
[http.routers.router1]
|
||||
Service = "service1"
|
||||
|
@ -101,13 +101,3 @@ services:
|
||||
traefik.http.routers.ping.entryPoints: ping
|
||||
traefik.http.routers.ping.rule: PathPrefix(`/ping`)
|
||||
traefik.http.routers.ping.service: ping@internal
|
||||
|
||||
traefik.http.routers.ping-error.entryPoints: ping
|
||||
traefik.http.routers.ping-error.rule: PathPrefix(`/ping-error`)
|
||||
traefik.http.routers.ping-error.middlewares: errors, basicauth
|
||||
traefik.http.routers.ping-error.service: ping@internal
|
||||
traefik.http.middlewares.basicauth.basicauth.users: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
|
||||
traefik.http.middlewares.errors.errors.status: 401
|
||||
traefik.http.middlewares.errors.errors.service: service3
|
||||
traefik.http.middlewares.errors.errors.query: /
|
||||
traefik.http.services.service3.loadbalancer.server.port: 80
|
||||
|
21
integration/testdata/rawdata-consul.json
vendored
21
integration/testdata/rawdata-consul.json
vendored
@ -14,8 +14,9 @@
|
||||
"tls": {},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -49,8 +50,9 @@
|
||||
},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -67,8 +69,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -89,8 +92,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -100,7 +104,13 @@
|
||||
},
|
||||
"middlewares": {
|
||||
"compressor@consul": {
|
||||
"compress": {},
|
||||
"compress": {
|
||||
"encodings": [
|
||||
"gzip",
|
||||
"br",
|
||||
"zstd"
|
||||
]
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"Router0@consul"
|
||||
@ -173,6 +183,7 @@
|
||||
"mirror@consul": {
|
||||
"mirroring": {
|
||||
"service": "simplesvc",
|
||||
"mirrorBody": true,
|
||||
"maxBodySize": -1,
|
||||
"mirrors": [
|
||||
{
|
||||
|
@ -9,8 +9,9 @@
|
||||
"priority": 18,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -29,8 +30,9 @@
|
||||
},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
|
18
integration/testdata/rawdata-crd.json
vendored
18
integration/testdata/rawdata-crd.json
vendored
@ -9,8 +9,9 @@
|
||||
"priority": 18,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -29,8 +30,9 @@
|
||||
},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -49,8 +51,9 @@
|
||||
"priority": 46,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -66,8 +69,9 @@
|
||||
"priority": 38,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -83,8 +87,9 @@
|
||||
"priority": 50,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -100,8 +105,9 @@
|
||||
"priority": 35,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"error": [
|
||||
"the service \"other-ns-wrr3@kubernetescrd\" does not exist"
|
||||
|
21
integration/testdata/rawdata-etcd.json
vendored
21
integration/testdata/rawdata-etcd.json
vendored
@ -14,8 +14,9 @@
|
||||
"tls": {},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -49,8 +50,9 @@
|
||||
},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -67,8 +69,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -89,8 +92,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -100,7 +104,13 @@
|
||||
},
|
||||
"middlewares": {
|
||||
"compressor@etcd": {
|
||||
"compress": {},
|
||||
"compress": {
|
||||
"encodings": [
|
||||
"gzip",
|
||||
"br",
|
||||
"zstd"
|
||||
]
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"Router0@etcd"
|
||||
@ -173,6 +183,7 @@
|
||||
"mirror@etcd": {
|
||||
"mirroring": {
|
||||
"service": "simplesvc",
|
||||
"mirrorBody": true,
|
||||
"maxBodySize": -1,
|
||||
"mirrors": [
|
||||
{
|
||||
|
12
integration/testdata/rawdata-gateway.json
vendored
12
integration/testdata/rawdata-gateway.json
vendored
@ -10,8 +10,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -32,8 +33,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -50,8 +52,9 @@
|
||||
"priority": 100008,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -69,8 +72,9 @@
|
||||
"tls": {},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
|
@ -10,8 +10,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -32,8 +33,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -49,8 +51,9 @@
|
||||
"priority": 44,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
|
18
integration/testdata/rawdata-ingress.json
vendored
18
integration/testdata/rawdata-ingress.json
vendored
@ -10,8 +10,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -32,8 +33,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -49,8 +51,9 @@
|
||||
"priority": 50,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -66,8 +69,9 @@
|
||||
"priority": 44,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -83,8 +87,9 @@
|
||||
"priority": 47,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -100,8 +105,9 @@
|
||||
"priority": 47,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
|
@ -10,8 +10,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -32,8 +33,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
|
@ -10,8 +10,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -32,8 +33,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -49,8 +51,9 @@
|
||||
"priority": 47,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
|
22
integration/testdata/rawdata-redis.json
vendored
22
integration/testdata/rawdata-redis.json
vendored
@ -14,8 +14,9 @@
|
||||
"tls": {},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -49,8 +50,9 @@
|
||||
},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -67,8 +69,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -89,8 +92,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -100,7 +104,13 @@
|
||||
},
|
||||
"middlewares": {
|
||||
"compressor@redis": {
|
||||
"compress": {},
|
||||
"compress": {
|
||||
"encodings": [
|
||||
"gzip",
|
||||
"br",
|
||||
"zstd"
|
||||
]
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"Router0@redis"
|
||||
@ -173,6 +183,7 @@
|
||||
"mirror@redis": {
|
||||
"mirroring": {
|
||||
"service": "simplesvc",
|
||||
"mirrorBody": true,
|
||||
"maxBodySize": -1,
|
||||
"mirrors": [
|
||||
{
|
||||
@ -244,6 +255,7 @@
|
||||
"url": "http://10.0.1.3:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
21
integration/testdata/rawdata-zk.json
vendored
21
integration/testdata/rawdata-zk.json
vendored
@ -14,8 +14,9 @@
|
||||
"tls": {},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -49,8 +50,9 @@
|
||||
},
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -67,8 +69,9 @@
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -89,8 +92,9 @@
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
"accessLogs": true,
|
||||
"metrics": true,
|
||||
"tracing": true,
|
||||
"metrics": true
|
||||
"traceVerbosity": "minimal"
|
||||
},
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
@ -100,7 +104,13 @@
|
||||
},
|
||||
"middlewares": {
|
||||
"compressor@zookeeper": {
|
||||
"compress": {},
|
||||
"compress": {
|
||||
"encodings": [
|
||||
"gzip",
|
||||
"br",
|
||||
"zstd"
|
||||
]
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"Router0@zookeeper"
|
||||
@ -173,6 +183,7 @@
|
||||
"mirror@zookeeper": {
|
||||
"mirroring": {
|
||||
"service": "simplesvc",
|
||||
"mirrorBody": true,
|
||||
"maxBodySize": -1,
|
||||
"mirrors": [
|
||||
{
|
||||
|
@ -77,6 +77,104 @@ func (s *TracingSuite) TearDownTest() {
|
||||
s.composeStop("tempo")
|
||||
}
|
||||
|
||||
func (s *TracingSuite) TestOpenTelemetryBasic_HTTP_router_minimalVerbosity() {
|
||||
file := s.adaptFile("fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
|
||||
WhoamiIP: s.whoamiIP,
|
||||
WhoamiPort: s.whoamiPort,
|
||||
IP: s.otelCollectorIP,
|
||||
IsHTTP: true,
|
||||
})
|
||||
|
||||
s.traefikCmd(withConfigFile(file))
|
||||
|
||||
// wait for traefik
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8000/basic-minimal", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
contains := []map[string]string{
|
||||
{
|
||||
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.0.name": "ReverseProxy",
|
||||
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_CLIENT",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue": "1.1",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue": fmt.Sprintf("http://%s/basic-minimal", net.JoinHostPort(s.whoamiIP, "80")),
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.peer.address\").value.stringValue": s.whoamiIP,
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.peer.port\").value.intValue": "80",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"server.address\").value.stringValue": s.whoamiIP,
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"server.port\").value.intValue": "80",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.1.name": "EntryPoint",
|
||||
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_SERVER",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"url.path\").value.stringValue": "/basic-minimal",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"url.query\").value.stringValue": "",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"server.address\").value.stringValue": "127.0.0.1:8000",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"network.peer.address\").value.stringValue": "127.0.0.1",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||
},
|
||||
}
|
||||
|
||||
s.checkTraceContent(contains)
|
||||
}
|
||||
|
||||
func (s *TracingSuite) TestOpenTelemetryBasic_HTTP_entrypoint_minimalVerbosity() {
|
||||
file := s.adaptFile("fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
|
||||
WhoamiIP: s.whoamiIP,
|
||||
WhoamiPort: s.whoamiPort,
|
||||
IP: s.otelCollectorIP,
|
||||
IsHTTP: true,
|
||||
})
|
||||
|
||||
s.traefikCmd(withConfigFile(file))
|
||||
|
||||
// wait for traefik
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8001/basic", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
contains := []map[string]string{
|
||||
{
|
||||
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.0.name": "ReverseProxy",
|
||||
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_CLIENT",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue": "1.1",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue": fmt.Sprintf("http://%s/basic", net.JoinHostPort(s.whoamiIP, "80")),
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.peer.address\").value.stringValue": s.whoamiIP,
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.peer.port\").value.intValue": "80",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"server.address\").value.stringValue": s.whoamiIP,
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"server.port\").value.intValue": "80",
|
||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.1.name": "EntryPoint",
|
||||
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_SERVER",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"entry_point\").value.stringValue": "web-minimal",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"url.path\").value.stringValue": "/basic",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"url.query\").value.stringValue": "",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"server.address\").value.stringValue": "127.0.0.1:8001",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"network.peer.address\").value.stringValue": "127.0.0.1",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||
},
|
||||
}
|
||||
|
||||
s.checkTraceContent(contains)
|
||||
}
|
||||
|
||||
func (s *TracingSuite) TestOpenTelemetryBasic_HTTP() {
|
||||
file := s.adaptFile("fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
|
||||
WhoamiIP: s.whoamiIP,
|
||||
@ -121,7 +219,7 @@ func (s *TracingSuite) TestOpenTelemetryBasic_HTTP() {
|
||||
"batches.0.scopeSpans.0.spans.3.name": "Router",
|
||||
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.router.name\").value.stringValue": "router0@file",
|
||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.router.name\").value.stringValue": "web-router0@file",
|
||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.route\").value.stringValue": "Path(`/basic`)",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.4.name": "Metrics",
|
||||
@ -189,7 +287,7 @@ func (s *TracingSuite) TestOpenTelemetryBasic_gRPC() {
|
||||
"batches.0.scopeSpans.0.spans.3.name": "Router",
|
||||
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.router.name\").value.stringValue": "router0@file",
|
||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.router.name\").value.stringValue": "web-router0@file",
|
||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.route\").value.stringValue": "Path(`/basic`)",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.4.name": "Metrics",
|
||||
@ -251,7 +349,7 @@ func (s *TracingSuite) TestOpenTelemetryRateLimit() {
|
||||
"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": "service1@file",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router1@file",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "web-router1@file",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"http.route\").value.stringValue": "Path(`/ratelimit`)",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.2.name": "Metrics",
|
||||
@ -299,7 +397,7 @@ func (s *TracingSuite) TestOpenTelemetryRateLimit() {
|
||||
"batches.0.scopeSpans.0.spans.4.name": "Router",
|
||||
"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.4.attributes.#(key=\"traefik.router.name\").value.stringValue": "router1@file",
|
||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.router.name\").value.stringValue": "web-router1@file",
|
||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.route\").value.stringValue": "Path(`/ratelimit`)",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.5.name": "Metrics",
|
||||
@ -423,7 +521,7 @@ func (s *TracingSuite) TestOpenTelemetryRetry() {
|
||||
"batches.0.scopeSpans.0.spans.12.name": "Router",
|
||||
"batches.0.scopeSpans.0.spans.12.kind": "SPAN_KIND_INTERNAL",
|
||||
"batches.0.scopeSpans.0.spans.12.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
|
||||
"batches.0.scopeSpans.0.spans.12.attributes.#(key=\"traefik.router.name\").value.stringValue": "router2@file",
|
||||
"batches.0.scopeSpans.0.spans.12.attributes.#(key=\"traefik.router.name\").value.stringValue": "web-router2@file",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.13.name": "Metrics",
|
||||
"batches.0.scopeSpans.0.spans.13.kind": "SPAN_KIND_INTERNAL",
|
||||
@ -475,7 +573,7 @@ func (s *TracingSuite) TestOpenTelemetryAuth() {
|
||||
"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": "service3@file",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router3@file",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "web-router3@file",
|
||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"http.route\").value.stringValue": "Path(`/auth`)",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.2.name": "Metrics",
|
||||
@ -532,7 +630,7 @@ func (s *TracingSuite) TestOpenTelemetryAuthWithRetry() {
|
||||
"batches.0.scopeSpans.0.spans.2.name": "Router",
|
||||
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service4@file",
|
||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.router.name\").value.stringValue": "router4@file",
|
||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.router.name\").value.stringValue": "web-router4@file",
|
||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"http.route\").value.stringValue": "Path(`/retry-auth`)",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.3.name": "Metrics",
|
||||
@ -601,7 +699,7 @@ func (s *TracingSuite) TestOpenTelemetrySafeURL() {
|
||||
"batches.0.scopeSpans.0.spans.4.name": "Router",
|
||||
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
|
||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.service.name\").value.stringValue": "service3@file",
|
||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.router.name\").value.stringValue": "router3@file",
|
||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.router.name\").value.stringValue": "web-router3@file",
|
||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.route\").value.stringValue": "Path(`/auth`)",
|
||||
|
||||
"batches.0.scopeSpans.0.spans.5.name": "Metrics",
|
||||
|
@ -88,9 +88,21 @@ type RouterTLSConfig struct {
|
||||
|
||||
// RouterObservabilityConfig holds the observability configuration for a router.
|
||||
type RouterObservabilityConfig struct {
|
||||
// AccessLogs enables access logs for this router.
|
||||
AccessLogs *bool `json:"accessLogs,omitempty" toml:"accessLogs,omitempty" yaml:"accessLogs,omitempty" export:"true"`
|
||||
Tracing *bool `json:"tracing,omitempty" toml:"tracing,omitempty" yaml:"tracing,omitempty" export:"true"`
|
||||
Metrics *bool `json:"metrics,omitempty" toml:"metrics,omitempty" yaml:"metrics,omitempty" export:"true"`
|
||||
// Metrics enables metrics for this router.
|
||||
Metrics *bool `json:"metrics,omitempty" toml:"metrics,omitempty" yaml:"metrics,omitempty" export:"true"`
|
||||
// Tracing enables tracing for this router.
|
||||
Tracing *bool `json:"tracing,omitempty" toml:"tracing,omitempty" yaml:"tracing,omitempty" export:"true"`
|
||||
// TraceVerbosity defines the verbosity level of the tracing for this router.
|
||||
// +kubebuilder:validation:Enum=minimal;detailed
|
||||
// +kubebuilder:default=minimal
|
||||
TraceVerbosity types.TracingVerbosity `json:"traceVerbosity,omitempty" toml:"traceVerbosity,omitempty" yaml:"traceVerbosity,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// SetDefaults Default values for a RouterObservabilityConfig.
|
||||
func (r *RouterObservabilityConfig) SetDefaults() {
|
||||
r.TraceVerbosity = types.MinimalVerbosity
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
@ -1335,13 +1335,13 @@ func (in *RouterObservabilityConfig) DeepCopyInto(out *RouterObservabilityConfig
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Tracing != nil {
|
||||
in, out := &in.Tracing, &out.Tracing
|
||||
if in.Metrics != nil {
|
||||
in, out := &in.Metrics, &out.Metrics
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Metrics != nil {
|
||||
in, out := &in.Metrics, &out.Metrics
|
||||
if in.Tracing != nil {
|
||||
in, out := &in.Tracing, &out.Tracing
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
|
@ -26,9 +26,10 @@ const (
|
||||
type Configuration struct {
|
||||
Routers map[string]*RouterInfo `json:"routers,omitempty"`
|
||||
Middlewares map[string]*MiddlewareInfo `json:"middlewares,omitempty"`
|
||||
TCPMiddlewares map[string]*TCPMiddlewareInfo `json:"tcpMiddlewares,omitempty"`
|
||||
Services map[string]*ServiceInfo `json:"services,omitempty"`
|
||||
Models map[string]*dynamic.Model `json:"-"`
|
||||
TCPRouters map[string]*TCPRouterInfo `json:"tcpRouters,omitempty"`
|
||||
TCPMiddlewares map[string]*TCPMiddlewareInfo `json:"tcpMiddlewares,omitempty"`
|
||||
TCPServices map[string]*TCPServiceInfo `json:"tcpServices,omitempty"`
|
||||
UDPRouters map[string]*UDPRouterInfo `json:"udpRouters,omitempty"`
|
||||
UDPServices map[string]*UDPServiceInfo `json:"udpServices,omitempty"`
|
||||
@ -66,6 +67,8 @@ func NewConfig(conf dynamic.Configuration) *Configuration {
|
||||
runtimeConfig.Middlewares[k] = &MiddlewareInfo{Middleware: v, Status: StatusEnabled}
|
||||
}
|
||||
}
|
||||
|
||||
runtimeConfig.Models = conf.HTTP.Models
|
||||
}
|
||||
|
||||
if conf.TCP != nil {
|
||||
|
@ -165,15 +165,17 @@ func (u *UDPConfig) SetDefaults() {
|
||||
|
||||
// ObservabilityConfig holds the observability configuration for an entry point.
|
||||
type ObservabilityConfig struct {
|
||||
AccessLogs *bool `json:"accessLogs,omitempty" toml:"accessLogs,omitempty" yaml:"accessLogs,omitempty" export:"true"`
|
||||
Tracing *bool `json:"tracing,omitempty" toml:"tracing,omitempty" yaml:"tracing,omitempty" export:"true"`
|
||||
Metrics *bool `json:"metrics,omitempty" toml:"metrics,omitempty" yaml:"metrics,omitempty" export:"true"`
|
||||
AccessLogs *bool `description:"Enables access-logs for this entryPoint." json:"accessLogs,omitempty" toml:"accessLogs,omitempty" yaml:"accessLogs,omitempty" export:"true"`
|
||||
Metrics *bool `description:"Enables metrics for this entryPoint." json:"metrics,omitempty" toml:"metrics,omitempty" yaml:"metrics,omitempty" export:"true"`
|
||||
Tracing *bool `description:"Enables tracing for this entryPoint." json:"tracing,omitempty" toml:"tracing,omitempty" yaml:"tracing,omitempty" export:"true"`
|
||||
TraceVerbosity types.TracingVerbosity `description:"Defines the tracing verbosity level for this entryPoint." json:"traceVerbosity,omitempty" toml:"traceVerbosity,omitempty" yaml:"traceVerbosity,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// SetDefaults sets the default values.
|
||||
func (o *ObservabilityConfig) SetDefaults() {
|
||||
defaultValue := true
|
||||
o.AccessLogs = &defaultValue
|
||||
o.Tracing = &defaultValue
|
||||
o.Metrics = &defaultValue
|
||||
o.Tracing = &defaultValue
|
||||
o.TraceVerbosity = types.MinimalVerbosity
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ func (a *LifeCycle) SetDefaults() {
|
||||
|
||||
// Tracing holds the tracing configuration.
|
||||
type Tracing struct {
|
||||
ServiceName string `description:"Sets the name for this service." json:"serviceName,omitempty" toml:"serviceName,omitempty" yaml:"serviceName,omitempty" export:"true"`
|
||||
ServiceName string `description:"Defines the service name resource attribute." json:"serviceName,omitempty" toml:"serviceName,omitempty" yaml:"serviceName,omitempty" export:"true"`
|
||||
ResourceAttributes map[string]string `description:"Defines additional resource attributes (key:value)." json:"resourceAttributes,omitempty" toml:"resourceAttributes,omitempty" yaml:"resourceAttributes,omitempty" export:"true"`
|
||||
CapturedRequestHeaders []string `description:"Request headers to add as attributes for server and client spans." json:"capturedRequestHeaders,omitempty" toml:"capturedRequestHeaders,omitempty" yaml:"capturedRequestHeaders,omitempty" export:"true"`
|
||||
CapturedResponseHeaders []string `description:"Response headers to add as attributes for server and client spans." json:"capturedResponseHeaders,omitempty" toml:"capturedResponseHeaders,omitempty" yaml:"capturedResponseHeaders,omitempty" export:"true"`
|
||||
|
@ -1,6 +1,7 @@
|
||||
package logs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@ -12,12 +13,12 @@ import (
|
||||
)
|
||||
|
||||
// SetupOTelLogger sets up the OpenTelemetry logger.
|
||||
func SetupOTelLogger(logger zerolog.Logger, config *types.OTelLog) (zerolog.Logger, error) {
|
||||
func SetupOTelLogger(ctx context.Context, logger zerolog.Logger, config *types.OTelLog) (zerolog.Logger, error) {
|
||||
if config == nil {
|
||||
return logger, nil
|
||||
}
|
||||
|
||||
provider, err := config.NewLoggerProvider()
|
||||
provider, err := config.NewLoggerProvider(ctx)
|
||||
if err != nil {
|
||||
return zerolog.Logger{}, fmt.Errorf("setting up OpenTelemetry logger provider: %w", err)
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ func TestLog(t *testing.T) {
|
||||
out := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339})
|
||||
logger := zerolog.New(out).With().Caller().Logger()
|
||||
|
||||
logger, err := SetupOTelLogger(logger, config)
|
||||
logger, err := SetupOTelLogger(t.Context(), logger, config)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := trace.ContextWithSpanContext(t.Context(), trace.NewSpanContext(trace.SpanContextConfig{
|
||||
|
@ -206,15 +206,27 @@ func newOpenTelemetryMeterProvider(ctx context.Context, config *types.OTLP) (*sd
|
||||
return nil, fmt.Errorf("creating exporter: %w", err)
|
||||
}
|
||||
|
||||
var resAttrs []attribute.KeyValue
|
||||
for k, v := range config.ResourceAttributes {
|
||||
resAttrs = append(resAttrs, attribute.String(k, v))
|
||||
}
|
||||
|
||||
res, err := resource.New(ctx,
|
||||
resource.WithAttributes(semconv.ServiceNameKey.String(config.ServiceName)),
|
||||
resource.WithAttributes(semconv.ServiceVersionKey.String(version.Version)),
|
||||
resource.WithContainer(),
|
||||
resource.WithFromEnv(),
|
||||
resource.WithHost(),
|
||||
resource.WithOS(),
|
||||
resource.WithProcess(),
|
||||
resource.WithTelemetrySDK(),
|
||||
resource.WithDetectors(types.K8sAttributesDetector{}),
|
||||
// The following order allows the user to override the service name and version,
|
||||
// as well as any other attributes set by the above detectors.
|
||||
resource.WithAttributes(
|
||||
semconv.ServiceName(config.ServiceName),
|
||||
semconv.ServiceVersion(version.Version),
|
||||
),
|
||||
resource.WithAttributes(resAttrs...),
|
||||
// Use the environment variables to allow overriding above resource attributes.
|
||||
resource.WithFromEnv(),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("building resource: %w", err)
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
ptypes "github.com/traefik/paerser/types"
|
||||
"github.com/traefik/traefik/v3/pkg/logs"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/capture"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
traefiktls "github.com/traefik/traefik/v3/pkg/tls"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
"go.opentelemetry.io/contrib/bridges/otellogrus"
|
||||
@ -69,17 +70,22 @@ type Handler struct {
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
// WrapHandler Wraps access log handler into an Alice Constructor.
|
||||
func WrapHandler(handler *Handler) alice.Constructor {
|
||||
// AliceConstructor returns an alice.Constructor that wraps the Handler (conditionally) in a middleware chain.
|
||||
func (h *Handler) AliceConstructor() alice.Constructor {
|
||||
return func(next http.Handler) (http.Handler, error) {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
handler.ServeHTTP(rw, req, next)
|
||||
if h == nil {
|
||||
next.ServeHTTP(rw, req)
|
||||
return
|
||||
}
|
||||
|
||||
h.ServeHTTP(rw, req, next)
|
||||
}), nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewHandler creates a new Handler.
|
||||
func NewHandler(config *types.AccessLog) (*Handler, error) {
|
||||
func NewHandler(ctx context.Context, config *types.AccessLog) (*Handler, error) {
|
||||
var file io.WriteCloser = noopCloser{os.Stdout}
|
||||
if len(config.FilePath) > 0 {
|
||||
f, err := openAccessLogFile(config.FilePath)
|
||||
@ -110,7 +116,7 @@ func NewHandler(config *types.AccessLog) (*Handler, error) {
|
||||
}
|
||||
|
||||
if config.OTLP != nil {
|
||||
otelLoggerProvider, err := config.OTLP.NewLoggerProvider()
|
||||
otelLoggerProvider, err := config.OTLP.NewLoggerProvider(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setting up OpenTelemetry logger provider: %w", err)
|
||||
}
|
||||
@ -196,6 +202,12 @@ func GetLogData(req *http.Request) *LogData {
|
||||
}
|
||||
|
||||
func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request, next http.Handler) {
|
||||
if !observability.AccessLogsEnabled(req.Context()) {
|
||||
next.ServeHTTP(rw, req)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now().UTC()
|
||||
|
||||
core := CoreLogData{
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCommonLogFormatter_Format(t *testing.T) {
|
||||
@ -82,8 +83,9 @@ func TestCommonLogFormatter_Format(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
// Set timezone to Etc/GMT+9 to have a constant behavior
|
||||
t.Setenv("TZ", "Etc/GMT+9")
|
||||
var err error
|
||||
time.Local, err = time.LoadLocation("Etc/GMT+9")
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
ptypes "github.com/traefik/paerser/types"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/capture"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
"go.opentelemetry.io/collector/pdata/plog/plogotlp"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
@ -84,7 +85,7 @@ func TestOTelAccessLog(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
logHandler, err := NewHandler(config)
|
||||
logHandler, err := NewHandler(t.Context(), config)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
err := logHandler.Close()
|
||||
@ -105,7 +106,15 @@ func TestOTelAccessLog(t *testing.T) {
|
||||
|
||||
chain := alice.New()
|
||||
chain = chain.Append(capture.Wrap)
|
||||
chain = chain.Append(WrapHandler(logHandler))
|
||||
|
||||
// Injection of the observability variables in the request context.
|
||||
chain = chain.Append(func(next http.Handler) (http.Handler, error) {
|
||||
return observability.WithObservabilityHandler(next, observability.Observability{
|
||||
AccessLogsEnabled: true,
|
||||
}), nil
|
||||
})
|
||||
|
||||
chain = chain.Append(logHandler.AliceConstructor())
|
||||
handler, err := chain.Then(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
@ -129,7 +138,7 @@ func TestLogRotation(t *testing.T) {
|
||||
rotatedFileName := fileName + ".rotated"
|
||||
|
||||
config := &types.AccessLog{FilePath: fileName, Format: CommonFormat}
|
||||
logHandler, err := NewHandler(config)
|
||||
logHandler, err := NewHandler(t.Context(), config)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
err := logHandler.Close()
|
||||
@ -138,7 +147,15 @@ func TestLogRotation(t *testing.T) {
|
||||
|
||||
chain := alice.New()
|
||||
chain = chain.Append(capture.Wrap)
|
||||
chain = chain.Append(WrapHandler(logHandler))
|
||||
|
||||
// Injection of the observability variables in the request context.
|
||||
chain = chain.Append(func(next http.Handler) (http.Handler, error) {
|
||||
return observability.WithObservabilityHandler(next, observability.Observability{
|
||||
AccessLogsEnabled: true,
|
||||
}), nil
|
||||
})
|
||||
|
||||
chain = chain.Append(logHandler.AliceConstructor())
|
||||
handler, err := chain.Then(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
@ -265,7 +282,7 @@ func TestLoggerHeaderFields(t *testing.T) {
|
||||
Fields: &test.accessLogFields,
|
||||
}
|
||||
|
||||
logger, err := NewHandler(config)
|
||||
logger, err := NewHandler(t.Context(), config)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
err := logger.Close()
|
||||
@ -290,7 +307,15 @@ func TestLoggerHeaderFields(t *testing.T) {
|
||||
|
||||
chain := alice.New()
|
||||
chain = chain.Append(capture.Wrap)
|
||||
chain = chain.Append(WrapHandler(logger))
|
||||
|
||||
// Injection of the observability variables in the request context.
|
||||
chain = chain.Append(func(next http.Handler) (http.Handler, error) {
|
||||
return observability.WithObservabilityHandler(next, observability.Observability{
|
||||
AccessLogsEnabled: true,
|
||||
}), nil
|
||||
})
|
||||
|
||||
chain = chain.Append(logger.AliceConstructor())
|
||||
handler, err := chain.Then(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
@ -954,7 +979,7 @@ func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) {
|
||||
|
||||
func doLoggingTLSOpt(t *testing.T, config *types.AccessLog, enableTLS, tracing bool) {
|
||||
t.Helper()
|
||||
logger, err := NewHandler(config)
|
||||
logger, err := NewHandler(t.Context(), config)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
err := logger.Close()
|
||||
@ -998,7 +1023,15 @@ func doLoggingTLSOpt(t *testing.T, config *types.AccessLog, enableTLS, tracing b
|
||||
|
||||
chain := alice.New()
|
||||
chain = chain.Append(capture.Wrap)
|
||||
chain = chain.Append(WrapHandler(logger))
|
||||
|
||||
// Injection of the observability variables in the request context.
|
||||
chain = chain.Append(func(next http.Handler) (http.Handler, error) {
|
||||
return observability.WithObservabilityHandler(next, observability.Observability{
|
||||
AccessLogsEnabled: true,
|
||||
}), nil
|
||||
})
|
||||
|
||||
chain = chain.Append(logger.AliceConstructor())
|
||||
handler, err := chain.Then(http.HandlerFunc(logWriterTestHandlerFunc))
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -1043,7 +1076,7 @@ func logWriterTestHandlerFunc(rw http.ResponseWriter, r *http.Request) {
|
||||
func doLoggingWithAbortedStream(t *testing.T, config *types.AccessLog) {
|
||||
t.Helper()
|
||||
|
||||
logger, err := NewHandler(config)
|
||||
logger, err := NewHandler(t.Context(), config)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
err := logger.Close()
|
||||
@ -1085,7 +1118,15 @@ func doLoggingWithAbortedStream(t *testing.T, config *types.AccessLog) {
|
||||
}), nil
|
||||
})
|
||||
chain = chain.Append(capture.Wrap)
|
||||
chain = chain.Append(WrapHandler(logger))
|
||||
|
||||
// Injection of the observability variables in the request context.
|
||||
chain = chain.Append(func(next http.Handler) (http.Handler, error) {
|
||||
return observability.WithObservabilityHandler(next, observability.Observability{
|
||||
AccessLogsEnabled: true,
|
||||
}), nil
|
||||
})
|
||||
|
||||
chain = chain.Append(logger.AliceConstructor())
|
||||
|
||||
service := NewFieldHandler(http.HandlerFunc(streamBackend), ServiceURL, "http://stream", nil)
|
||||
service = NewFieldHandler(service, ServiceAddr, "127.0.0.1", nil)
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -39,8 +38,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.AddPrefix, name
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (a *addPrefix) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return a.name, typeName, trace.SpanKindInternal
|
||||
func (a *addPrefix) GetTracingInformation() (string, string) {
|
||||
return a.name, typeName
|
||||
}
|
||||
|
||||
func (a *addPrefix) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"golang.org/x/sync/singleflight"
|
||||
)
|
||||
|
||||
@ -61,8 +60,8 @@ func NewBasic(ctx context.Context, next http.Handler, authConfig dynamic.BasicAu
|
||||
return ba, nil
|
||||
}
|
||||
|
||||
func (b *basicAuth) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return b.name, typeNameBasic, trace.SpanKindInternal
|
||||
func (b *basicAuth) GetTracingInformation() (string, string) {
|
||||
return b.name, typeNameBasic
|
||||
}
|
||||
|
||||
func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -54,8 +53,8 @@ func NewDigest(ctx context.Context, next http.Handler, authConfig dynamic.Digest
|
||||
return da, nil
|
||||
}
|
||||
|
||||
func (d *digestAuth) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return d.name, typeNameDigest, trace.SpanKindInternal
|
||||
func (d *digestAuth) GetTracingInformation() (string, string) {
|
||||
return d.name, typeNameDigest
|
||||
}
|
||||
|
||||
func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -131,8 +131,8 @@ func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAu
|
||||
return fa, nil
|
||||
}
|
||||
|
||||
func (fa *forwardAuth) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return fa.name, typeNameForward, trace.SpanKindInternal
|
||||
func (fa *forwardAuth) GetTracingInformation() (string, string) {
|
||||
return fa.name, typeNameForward
|
||||
}
|
||||
|
||||
func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
@ -180,7 +180,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
||||
var forwardSpan trace.Span
|
||||
var tracer *tracing.Tracer
|
||||
if tracer = tracing.TracerFromContext(req.Context()); tracer != nil {
|
||||
if tracer = tracing.TracerFromContext(req.Context()); tracer != nil && observability.TracingEnabled(req.Context()) {
|
||||
var tracingCtx context.Context
|
||||
tracingCtx, forwardSpan = tracer.Start(req.Context(), "AuthRequest", trace.WithSpanKind(trace.SpanKindClient))
|
||||
defer forwardSpan.End()
|
||||
|
@ -16,6 +16,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/middlewares/observability"
|
||||
"github.com/traefik/traefik/v3/pkg/proxy/httputil"
|
||||
"github.com/traefik/traefik/v3/pkg/testhelpers"
|
||||
"github.com/traefik/traefik/v3/pkg/tracing"
|
||||
@ -756,6 +757,10 @@ func TestForwardAuthTracing(t *testing.T) {
|
||||
next, err := NewForward(t.Context(), next, auth, "authTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
next = observability.WithObservabilityHandler(next, observability.Observability{
|
||||
TracingEnabled: true,
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "http://www.test.com/search?q=Opentelemetry", nil)
|
||||
req.RemoteAddr = "10.0.0.1:1234"
|
||||
req.Header.Set("User-Agent", "forward-test")
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/logs"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
oxybuffer "github.com/vulcand/oxy/v2/buffer"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -48,8 +47,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.Buffering, name
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *buffer) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return b.name, typeName, trace.SpanKindInternal
|
||||
func (b *buffer) GetTracingInformation() (string, string) {
|
||||
return b.name, typeName
|
||||
}
|
||||
|
||||
func (b *buffer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"github.com/vulcand/oxy/v2/cbreaker"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const typeName = "CircuitBreaker"
|
||||
@ -68,8 +67,8 @@ func New(ctx context.Context, next http.Handler, confCircuitBreaker dynamic.Circ
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *circuitBreaker) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return c.name, typeName, trace.SpanKindInternal
|
||||
func (c *circuitBreaker) GetTracingInformation() (string, string) {
|
||||
return c.name, typeName
|
||||
}
|
||||
|
||||
func (c *circuitBreaker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
"github.com/klauspost/compress/zstd"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const typeName = "Compress"
|
||||
@ -181,8 +180,8 @@ func (c *compress) chooseHandler(typ string, rw http.ResponseWriter, req *http.R
|
||||
}
|
||||
}
|
||||
|
||||
func (c *compress) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return c.name, typeName, trace.SpanKindInternal
|
||||
func (c *compress) GetTracingInformation() (string, string) {
|
||||
return c.name, typeName
|
||||
}
|
||||
|
||||
func (c *compress) newGzipHandler() (http.Handler, error) {
|
||||
|
@ -15,7 +15,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"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.
|
||||
@ -83,8 +82,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.ErrorPage, servi
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *customErrors) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return c.name, typeName, trace.SpanKindInternal
|
||||
func (c *customErrors) GetTracingInformation() (string, string) {
|
||||
return c.name, typeName
|
||||
}
|
||||
|
||||
func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const requestHeaderModifierTypeName = "RequestHeaderModifier"
|
||||
@ -35,8 +34,8 @@ func NewRequestHeaderModifier(ctx context.Context, next http.Handler, config dyn
|
||||
}
|
||||
}
|
||||
|
||||
func (r *requestHeaderModifier) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return r.name, requestHeaderModifierTypeName, trace.SpanKindUnspecified
|
||||
func (r *requestHeaderModifier) GetTracingInformation() (string, string) {
|
||||
return r.name, requestHeaderModifierTypeName
|
||||
}
|
||||
|
||||
func (r *requestHeaderModifier) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const responseHeaderModifierTypeName = "ResponseHeaderModifier"
|
||||
@ -35,8 +34,8 @@ func NewResponseHeaderModifier(ctx context.Context, next http.Handler, config dy
|
||||
}
|
||||
}
|
||||
|
||||
func (r *responseHeaderModifier) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return r.name, responseHeaderModifierTypeName, trace.SpanKindUnspecified
|
||||
func (r *responseHeaderModifier) GetTracingInformation() (string, string) {
|
||||
return r.name, responseHeaderModifierTypeName
|
||||
}
|
||||
|
||||
func (r *responseHeaderModifier) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const typeName = "RequestRedirect"
|
||||
@ -52,8 +51,8 @@ func NewRequestRedirect(ctx context.Context, next http.Handler, conf dynamic.Req
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r redirect) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return r.name, typeName, trace.SpanKindInternal
|
||||
func (r redirect) GetTracingInformation() (string, string) {
|
||||
return r.name, typeName
|
||||
}
|
||||
|
||||
func (r redirect) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -38,8 +37,8 @@ func NewURLRewrite(ctx context.Context, next http.Handler, conf dynamic.URLRewri
|
||||
}
|
||||
}
|
||||
|
||||
func (u urlRewrite) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return u.name, typeName, trace.SpanKindInternal
|
||||
func (u urlRewrite) GetTracingInformation() (string, string) {
|
||||
return u.name, typeName
|
||||
}
|
||||
|
||||
func (u urlRewrite) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -58,8 +57,8 @@ func New(ctx context.Context, next http.Handler, cfg dynamic.Headers, name strin
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *headers) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return h.name, typeName, trace.SpanKindInternal
|
||||
func (h *headers) GetTracingInformation() (string, string) {
|
||||
return h.name, typeName
|
||||
}
|
||||
|
||||
func (h *headers) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
func TestNew_withoutOptions(t *testing.T) {
|
||||
@ -107,11 +106,10 @@ func Test_headers_getTracingInformation(t *testing.T) {
|
||||
name: "testing",
|
||||
}
|
||||
|
||||
name, typeName, spanKind := mid.GetTracingInformation()
|
||||
name, typeName := mid.GetTracingInformation()
|
||||
|
||||
assert.Equal(t, "testing", name)
|
||||
assert.Equal(t, "Headers", typeName)
|
||||
assert.Equal(t, trace.SpanKindInternal, spanKind)
|
||||
}
|
||||
|
||||
// This test is an adapted version of net/http/httputil.Test1xxResponses test.
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/logs"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"github.com/vulcand/oxy/v2/connlimit"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -53,8 +52,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, string, trace.SpanKind) {
|
||||
return i.name, typeName, trace.SpanKindInternal
|
||||
func (i *inFlightReq) GetTracingInformation() (string, string) {
|
||||
return i.name, typeName
|
||||
}
|
||||
|
||||
func (i *inFlightReq) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/ip"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -65,8 +64,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.IPAllowList, nam
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (al *ipAllowLister) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return al.name, typeName, trace.SpanKindInternal
|
||||
func (al *ipAllowLister) GetTracingInformation() (string, string) {
|
||||
return al.name, typeName
|
||||
}
|
||||
|
||||
func (al *ipAllowLister) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/ip"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -55,8 +54,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.IPWhiteList, nam
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (wl *ipWhiteLister) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return wl.name, typeName, trace.SpanKindInternal
|
||||
func (wl *ipWhiteLister) GetTracingInformation() (string, string) {
|
||||
return wl.name, typeName
|
||||
}
|
||||
|
||||
func (wl *ipWhiteLister) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/retry"
|
||||
traefiktls "github.com/traefik/traefik/v3/pkg/tls"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"google.golang.org/grpc/codes"
|
||||
)
|
||||
|
||||
@ -93,33 +92,45 @@ func NewServiceMiddleware(ctx context.Context, next http.Handler, registry metri
|
||||
}
|
||||
}
|
||||
|
||||
// WrapEntryPointHandler Wraps metrics entrypoint to alice.Constructor.
|
||||
func WrapEntryPointHandler(ctx context.Context, registry metrics.Registry, entryPointName string) alice.Constructor {
|
||||
// EntryPointMetricsHandler returns the metrics entrypoint handler.
|
||||
func EntryPointMetricsHandler(ctx context.Context, registry metrics.Registry, entryPointName string) alice.Constructor {
|
||||
return func(next http.Handler) (http.Handler, error) {
|
||||
if registry == nil || !registry.IsEpEnabled() {
|
||||
return next, nil
|
||||
}
|
||||
|
||||
return NewEntryPointMiddleware(ctx, next, registry, entryPointName), nil
|
||||
}
|
||||
}
|
||||
|
||||
// WrapRouterHandler Wraps metrics router to alice.Constructor.
|
||||
func WrapRouterHandler(ctx context.Context, registry metrics.Registry, routerName string, serviceName string) alice.Constructor {
|
||||
// RouterMetricsHandler returns the metrics router handler.
|
||||
func RouterMetricsHandler(ctx context.Context, registry metrics.Registry, routerName string, serviceName string) alice.Constructor {
|
||||
return func(next http.Handler) (http.Handler, error) {
|
||||
if registry == nil || !registry.IsRouterEnabled() {
|
||||
return next, nil
|
||||
}
|
||||
|
||||
return NewRouterMiddleware(ctx, next, registry, routerName, serviceName), nil
|
||||
}
|
||||
}
|
||||
|
||||
// WrapServiceHandler Wraps metrics service to alice.Constructor.
|
||||
func WrapServiceHandler(ctx context.Context, registry metrics.Registry, serviceName string) alice.Constructor {
|
||||
// ServiceMetricsHandler returns the metrics service handler.
|
||||
func ServiceMetricsHandler(ctx context.Context, registry metrics.Registry, serviceName string) alice.Constructor {
|
||||
return func(next http.Handler) (http.Handler, error) {
|
||||
if registry == nil || !registry.IsSvcEnabled() {
|
||||
return next, nil
|
||||
}
|
||||
|
||||
return NewServiceMiddleware(ctx, next, registry, serviceName), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m *metricsMiddleware) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return m.name, typeName, trace.SpanKindInternal
|
||||
func (m *metricsMiddleware) GetTracingInformation() (string, string) {
|
||||
return m.name, typeName
|
||||
}
|
||||
|
||||
func (m *metricsMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if val := req.Context().Value(observability.DisableMetricsKey); val != nil {
|
||||
if !observability.MetricsEnabled(req.Context()) {
|
||||
m.next.ServeHTTP(rw, req)
|
||||
return
|
||||
}
|
||||
|
@ -48,11 +48,17 @@ func newEntryPoint(ctx context.Context, tracer *tracing.Tracer, entryPointName s
|
||||
}
|
||||
|
||||
func (e *entryPointTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if e.tracer == nil || !TracingEnabled(req.Context()) {
|
||||
e.next.ServeHTTP(rw, req)
|
||||
return
|
||||
}
|
||||
|
||||
tracingCtx := tracing.ExtractCarrierIntoContext(req.Context(), req.Header)
|
||||
start := time.Now()
|
||||
tracingCtx, span := e.tracer.Start(tracingCtx, "EntryPoint", trace.WithSpanKind(trace.SpanKindServer), trace.WithTimestamp(start))
|
||||
|
||||
// Associate the request context with the logger.
|
||||
// This allows the logger to be aware of the tracing context and log accordingly (TraceID, SpanID, etc.).
|
||||
logger := log.Ctx(tracingCtx).With().Ctx(tracingCtx).Logger()
|
||||
loggerCtx := logger.WithContext(tracingCtx)
|
||||
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
|
||||
// Traceable embeds tracing information.
|
||||
type Traceable interface {
|
||||
GetTracingInformation() (name string, typeName string, spanKind trace.SpanKind)
|
||||
GetTracingInformation() (name string, typeName string)
|
||||
}
|
||||
|
||||
// WrapMiddleware adds traceability to an alice.Constructor.
|
||||
@ -29,21 +29,20 @@ func WrapMiddleware(ctx context.Context, constructor alice.Constructor) alice.Co
|
||||
}
|
||||
|
||||
if traceableHandler, ok := handler.(Traceable); ok {
|
||||
name, typeName, spanKind := traceableHandler.GetTracingInformation()
|
||||
name, typeName := traceableHandler.GetTracingInformation()
|
||||
log.Ctx(ctx).Debug().Str(logs.MiddlewareName, name).Msg("Adding tracing to middleware")
|
||||
return NewMiddleware(handler, name, typeName, spanKind), nil
|
||||
return NewMiddleware(handler, name, typeName), nil
|
||||
}
|
||||
return handler, nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewMiddleware returns a http.Handler struct.
|
||||
func NewMiddleware(next http.Handler, name string, typeName string, spanKind trace.SpanKind) http.Handler {
|
||||
func NewMiddleware(next http.Handler, name string, typeName string) http.Handler {
|
||||
return &middlewareTracing{
|
||||
next: next,
|
||||
name: name,
|
||||
typeName: typeName,
|
||||
spanKind: spanKind,
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,12 +51,11 @@ 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))
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil && DetailedTracingEnabled(req.Context()) {
|
||||
tracingCtx, span := tracer.Start(req.Context(), w.typeName, trace.WithSpanKind(trace.SpanKindInternal))
|
||||
defer span.End()
|
||||
|
||||
req = req.WithContext(tracingCtx)
|
||||
|
@ -3,6 +3,7 @@ package observability
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
@ -10,8 +11,58 @@ import (
|
||||
|
||||
type contextKey int
|
||||
|
||||
// DisableMetricsKey is a context key used to disable the metrics.
|
||||
const DisableMetricsKey contextKey = iota
|
||||
const observabilityKey contextKey = iota
|
||||
|
||||
type Observability struct {
|
||||
AccessLogsEnabled bool
|
||||
MetricsEnabled bool
|
||||
SemConvMetricsEnabled bool
|
||||
TracingEnabled bool
|
||||
DetailedTracingEnabled bool
|
||||
}
|
||||
|
||||
// WithObservabilityHandler sets the observability state in the context for the next handler.
|
||||
// This is also used for testing purposes to control whether access logs are enabled or not.
|
||||
func WithObservabilityHandler(next http.Handler, obs Observability) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
next.ServeHTTP(rw, req.WithContext(WithObservability(req.Context(), obs)))
|
||||
})
|
||||
}
|
||||
|
||||
// WithObservability injects the observability state into the context.
|
||||
func WithObservability(ctx context.Context, obs Observability) context.Context {
|
||||
return context.WithValue(ctx, observabilityKey, obs)
|
||||
}
|
||||
|
||||
// AccessLogsEnabled returns whether access-logs are enabled.
|
||||
func AccessLogsEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.AccessLogsEnabled
|
||||
}
|
||||
|
||||
// MetricsEnabled returns whether metrics are enabled.
|
||||
func MetricsEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.MetricsEnabled
|
||||
}
|
||||
|
||||
// SemConvMetricsEnabled returns whether metrics are enabled.
|
||||
func SemConvMetricsEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.SemConvMetricsEnabled
|
||||
}
|
||||
|
||||
// TracingEnabled returns whether tracing is enabled.
|
||||
func TracingEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.TracingEnabled
|
||||
}
|
||||
|
||||
// DetailedTracingEnabled returns whether detailed tracing is enabled.
|
||||
func DetailedTracingEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.DetailedTracingEnabled
|
||||
}
|
||||
|
||||
// SetStatusErrorf flags the span as in error and log an event.
|
||||
func SetStatusErrorf(ctx context.Context, format string, args ...interface{}) {
|
||||
|
@ -45,7 +45,7 @@ func newRouter(ctx context.Context, router, routerRule, service string, next htt
|
||||
}
|
||||
|
||||
func (f *routerTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil && DetailedTracingEnabled(req.Context()) {
|
||||
tracingCtx, span := tracer.Start(req.Context(), "Router", trace.WithSpanKind(trace.SpanKindInternal))
|
||||
defer span.End()
|
||||
|
||||
|
@ -46,7 +46,7 @@ func newServerMetricsSemConv(ctx context.Context, semConvMetricRegistry *metrics
|
||||
}
|
||||
|
||||
func (e *semConvServerMetrics) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if e.semConvMetricRegistry == nil || e.semConvMetricRegistry.HTTPServerRequestDuration() == nil {
|
||||
if e.semConvMetricRegistry == nil || e.semConvMetricRegistry.HTTPServerRequestDuration() == nil || !SemConvMetricsEnabled(req.Context()) {
|
||||
e.next.ServeHTTP(rw, req)
|
||||
return
|
||||
}
|
||||
|
@ -83,6 +83,11 @@ func TestSemConvServerMetrics(t *testing.T) {
|
||||
handler, err = capture.Wrap(handler)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Injection of the observability variables in the request context.
|
||||
handler = WithObservabilityHandler(handler, Observability{
|
||||
SemConvMetricsEnabled: true,
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rw, req)
|
||||
|
||||
got := metricdata.ResourceMetrics{}
|
||||
|
@ -32,7 +32,7 @@ func NewService(ctx context.Context, service string, next http.Handler) http.Han
|
||||
}
|
||||
|
||||
func (t *serviceTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil && DetailedTracingEnabled(req.Context()) {
|
||||
tracingCtx, span := tracer.Start(req.Context(), "Service", trace.WithSpanKind(trace.SpanKindInternal))
|
||||
defer span.End()
|
||||
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const typeName = "PassClientTLSCert"
|
||||
@ -139,8 +138,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.PassTLSClientCer
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *passTLSClientCert) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return p.name, typeName, trace.SpanKindInternal
|
||||
func (p *passTLSClientCert) GetTracingInformation() (string, string) {
|
||||
return p.name, typeName
|
||||
}
|
||||
|
||||
func (p *passTLSClientCert) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares/observability"
|
||||
"github.com/vulcand/oxy/v2/utils"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
@ -127,8 +126,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.RateLimit, name
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (rl *rateLimiter) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return rl.name, typeName, trace.SpanKindInternal
|
||||
func (rl *rateLimiter) GetTracingInformation() (string, string) {
|
||||
return rl.name, typeName
|
||||
}
|
||||
|
||||
func (rl *rateLimiter) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user