Upgrade to OpenTelemetry Semantic Conventions v1.26.0
This commit is contained in:
parent
2f9905061e
commit
8cb1829698
21 changed files with 558 additions and 217 deletions
|
@ -5,6 +5,8 @@ description: "Traefik supports several tracing backends, including OpenTelemetry
|
||||||
|
|
||||||
# OpenTelemetry
|
# OpenTelemetry
|
||||||
|
|
||||||
|
Traefik Proxy follows [official OpenTelemetry semantic conventions v1.26.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/http/http-spans.md).
|
||||||
|
|
||||||
To enable the OpenTelemetry tracer:
|
To enable the OpenTelemetry tracer:
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
|
|
|
@ -160,3 +160,28 @@ tracing:
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.capturedResponseHeaders[0]=X-CustomHeader
|
--tracing.capturedResponseHeaders[0]=X-CustomHeader
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `safeQueryParams`
|
||||||
|
|
||||||
|
_Optional, Default={}_
|
||||||
|
|
||||||
|
By default, all query parameters are redacted.
|
||||||
|
Defines the list of query parameters to not redact.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
tracing:
|
||||||
|
otlp:
|
||||||
|
safeQueryParams:
|
||||||
|
- bar
|
||||||
|
- buz
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[tracing]
|
||||||
|
[tracing.otlp]
|
||||||
|
safeQueryParams = ["bar", "buz"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--tracing.otlp.safeQueryParams=bar,buz
|
||||||
|
```
|
||||||
|
|
|
@ -1125,6 +1125,9 @@ TLS insecure skip verify (Default: ```false```)
|
||||||
`--tracing.otlp.http.tls.key`:
|
`--tracing.otlp.http.tls.key`:
|
||||||
TLS key
|
TLS key
|
||||||
|
|
||||||
|
`--tracing.safequeryparams`:
|
||||||
|
Query params to not redact.
|
||||||
|
|
||||||
`--tracing.samplerate`:
|
`--tracing.samplerate`:
|
||||||
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
|
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
|
||||||
|
|
||||||
|
|
|
@ -1125,6 +1125,9 @@ TLS insecure skip verify (Default: ```false```)
|
||||||
`TRAEFIK_TRACING_OTLP_HTTP_TLS_KEY`:
|
`TRAEFIK_TRACING_OTLP_HTTP_TLS_KEY`:
|
||||||
TLS key
|
TLS key
|
||||||
|
|
||||||
|
`TRAEFIK_TRACING_SAFEQUERYPARAMS`:
|
||||||
|
Query params to not redact.
|
||||||
|
|
||||||
`TRAEFIK_TRACING_SAMPLERATE`:
|
`TRAEFIK_TRACING_SAMPLERATE`:
|
||||||
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
|
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
|
||||||
|
|
||||||
|
|
|
@ -392,6 +392,7 @@
|
||||||
serviceName = "foobar"
|
serviceName = "foobar"
|
||||||
capturedRequestHeaders = ["foobar", "foobar"]
|
capturedRequestHeaders = ["foobar", "foobar"]
|
||||||
capturedResponseHeaders = ["foobar", "foobar"]
|
capturedResponseHeaders = ["foobar", "foobar"]
|
||||||
|
safeQueryParams = ["foobar", "foobar"]
|
||||||
sampleRate = 42.0
|
sampleRate = 42.0
|
||||||
addInternals = true
|
addInternals = true
|
||||||
[tracing.globalAttributes]
|
[tracing.globalAttributes]
|
||||||
|
|
|
@ -434,6 +434,9 @@ tracing:
|
||||||
capturedResponseHeaders:
|
capturedResponseHeaders:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
safeQueryParams:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
sampleRate: 42
|
sampleRate: 42
|
||||||
addInternals: true
|
addInternals: true
|
||||||
otlp:
|
otlp:
|
||||||
|
|
32
go.mod
32
go.mod
|
@ -70,18 +70,18 @@ require (
|
||||||
github.com/unrolled/secure v1.0.9
|
github.com/unrolled/secure v1.0.9
|
||||||
github.com/vulcand/oxy/v2 v2.0.0-20230427132221-be5cf38f3c1c
|
github.com/vulcand/oxy/v2 v2.0.0-20230427132221-be5cf38f3c1c
|
||||||
github.com/vulcand/predicate v1.2.0
|
github.com/vulcand/predicate v1.2.0
|
||||||
go.opentelemetry.io/collector/pdata v1.2.0
|
go.opentelemetry.io/collector/pdata v1.10.0
|
||||||
go.opentelemetry.io/contrib/propagators/autoprop v0.52.0
|
go.opentelemetry.io/contrib/propagators/autoprop v0.52.0
|
||||||
go.opentelemetry.io/otel v1.27.0
|
go.opentelemetry.io/otel v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/metric v1.27.0
|
go.opentelemetry.io/otel/metric v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/sdk v1.27.0
|
go.opentelemetry.io/otel/sdk v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.27.0
|
go.opentelemetry.io/otel/sdk/metric v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
go.opentelemetry.io/otel/trace v1.27.0
|
go.opentelemetry.io/otel/trace v1.27.1-0.20240624175855-921eb701b175 // For security reason we need to follow semconv v1.26.0 and we can't wait for opentelemetry-go-sdk v1.28.0.
|
||||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f
|
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f
|
||||||
golang.org/x/mod v0.18.0
|
golang.org/x/mod v0.18.0
|
||||||
golang.org/x/net v0.26.0
|
golang.org/x/net v0.26.0
|
||||||
|
@ -180,7 +180,7 @@ require (
|
||||||
github.com/go-errors/errors v1.0.1 // indirect
|
github.com/go-errors/errors v1.0.1 // indirect
|
||||||
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
||||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||||
github.com/go-logr/logr v1.4.1 // indirect
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-logr/zapr v1.3.0 // indirect
|
github.com/go-logr/zapr v1.3.0 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
|
@ -329,7 +329,7 @@ require (
|
||||||
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 // indirect
|
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 // indirect
|
||||||
go.opentelemetry.io/contrib/propagators/jaeger v1.27.0 // indirect
|
go.opentelemetry.io/contrib/propagators/jaeger v1.27.0 // indirect
|
||||||
go.opentelemetry.io/contrib/propagators/ot v1.27.0 // indirect
|
go.opentelemetry.io/contrib/propagators/ot v1.27.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||||
go.uber.org/atomic v1.11.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
go.uber.org/mock v0.4.0 // indirect
|
go.uber.org/mock v0.4.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
|
@ -342,9 +342,9 @@ require (
|
||||||
golang.org/x/term v0.21.0 // indirect
|
golang.org/x/term v0.21.0 // indirect
|
||||||
google.golang.org/api v0.172.0 // indirect
|
google.golang.org/api v0.172.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect
|
||||||
google.golang.org/protobuf v1.34.1 // indirect
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
gopkg.in/h2non/gock.v1 v1.0.16 // indirect
|
gopkg.in/h2non/gock.v1 v1.0.16 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
|
64
go.sum
64
go.sum
|
@ -348,8 +348,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
|
||||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||||
|
@ -1182,8 +1182,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
go.opentelemetry.io/collector/pdata v1.2.0 h1:N6VdyEFYJyoHIKqHd0F372eNVD5b+AbH0ZQf7Z2jJ9I=
|
go.opentelemetry.io/collector/pdata v1.10.0 h1:oLyPLGvPTQrcRT64ZVruwvmH/u3SHTfNo01pteS4WOE=
|
||||||
go.opentelemetry.io/collector/pdata v1.2.0/go.mod h1:mKXb6527Syb8PT4P9CZOJNbkuHOHjjGTZNNwSKESJhc=
|
go.opentelemetry.io/collector/pdata v1.10.0/go.mod h1:IHxHsp+Jq/xfjORQMDJjSH6jvedOSTOyu3nbxqhWSYE=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||||
go.opentelemetry.io/contrib/propagators/autoprop v0.52.0 h1:xyRih6jMB0vroMSRdBE+uyKx20BclB/bybJt/LaCxmY=
|
go.opentelemetry.io/contrib/propagators/autoprop v0.52.0 h1:xyRih6jMB0vroMSRdBE+uyKx20BclB/bybJt/LaCxmY=
|
||||||
|
@ -1196,29 +1196,29 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.27.0 h1:tJPpZAEsihJgRTnXrPjY3r
|
||||||
go.opentelemetry.io/contrib/propagators/jaeger v1.27.0/go.mod h1:5uPAMHJnlTktQbCCdWSX5PfK8CocD25mycIsZV/iFiU=
|
go.opentelemetry.io/contrib/propagators/jaeger v1.27.0/go.mod h1:5uPAMHJnlTktQbCCdWSX5PfK8CocD25mycIsZV/iFiU=
|
||||||
go.opentelemetry.io/contrib/propagators/ot v1.27.0 h1:xFPqk7ntRR87dqvl6RfeHiq9UlE8mPSuL6Dtr/zysL8=
|
go.opentelemetry.io/contrib/propagators/ot v1.27.0 h1:xFPqk7ntRR87dqvl6RfeHiq9UlE8mPSuL6Dtr/zysL8=
|
||||||
go.opentelemetry.io/contrib/propagators/ot v1.27.0/go.mod h1:nVLTPrDlSZPoVdeWRmpWBwxA73TYL6XLkC4bj72jvmg=
|
go.opentelemetry.io/contrib/propagators/ot v1.27.0/go.mod h1:nVLTPrDlSZPoVdeWRmpWBwxA73TYL6XLkC4bj72jvmg=
|
||||||
go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
|
go.opentelemetry.io/otel v1.27.1-0.20240624175855-921eb701b175 h1:2aQYN3ZllvztGtSIFNT2xGMrwsbPkGXj0O+KgPVsq5A=
|
||||||
go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
|
go.opentelemetry.io/otel v1.27.1-0.20240624175855-921eb701b175/go.mod h1:sAYY1kDqq6Qgmu9OdUrtIhBJAVKevM27kmSzEkEyyBg=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.1-0.20240624175855-921eb701b175 h1:awu+mcY8Zh17gkaxch+AY59ZEeZHsct61kce/JUa/Ho=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.1-0.20240624175855-921eb701b175/go.mod h1:wwHMT54YgLNroOkp4+XK7PRqCez5DtQayTBR9Wf1CEA=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.1-0.20240624175855-921eb701b175 h1:nNu+y3xs12BTRqNVciOBdq1bwUpqHJFs26lhXXnO8/0=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.1-0.20240624175855-921eb701b175/go.mod h1:/TESptXGTu8vZX8i19t1TSU4PGo9+gT9pGK/UNAea9I=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.1-0.20240624175855-921eb701b175 h1:ihrS8VlMvzPDy1QJ9yIsrKpcso6XnADVrj33wWxRG6k=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.1-0.20240624175855-921eb701b175/go.mod h1:O6p37S657iklDAWQZrzkHeyOooL0TRG7ADP6jZ1RpF8=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.1-0.20240624175855-921eb701b175 h1:qk6WZWPTf1MDvgLRCECyzbUzugNp2Ybc11fnrj6L/t4=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.1-0.20240624175855-921eb701b175/go.mod h1:A5CvQA6TBgKbMXLU3YrV9WB2m5xQYB50/PLkW1nJA8k=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.1-0.20240624175855-921eb701b175 h1:l47wCNFvbEdVi0U3Ojf5yD6QhrNjuK2N46N9tiCzpNE=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.1-0.20240624175855-921eb701b175/go.mod h1:vS4rxlVsjAdnvN34PmMKVPKZdQrKVxRw6Tz6qQ+NsY8=
|
||||||
go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik=
|
go.opentelemetry.io/otel/metric v1.27.1-0.20240624175855-921eb701b175 h1:YGLAewt2Wr/DFRQI6OjqqZ31B+CO3W1bcDWhsIL7r98=
|
||||||
go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak=
|
go.opentelemetry.io/otel/metric v1.27.1-0.20240624175855-921eb701b175/go.mod h1:YHVa4iPQFl9x0kF/Pxk1MYAbroRbl7zK+vT34w7VsCA=
|
||||||
go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI=
|
go.opentelemetry.io/otel/sdk v1.27.1-0.20240624175855-921eb701b175 h1:QdXgh+39hJwRYYQ3OgcI4SMawt/rPBgmQdtZYGxzdq8=
|
||||||
go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A=
|
go.opentelemetry.io/otel/sdk v1.27.1-0.20240624175855-921eb701b175/go.mod h1:Ru3JMbgJMftQARx7nhi0IJotnL2n8bv61IOrAgFpd+s=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI=
|
go.opentelemetry.io/otel/sdk/metric v1.27.1-0.20240624175855-921eb701b175 h1:GYxFdqdupCe5BEORUuWvNMRKeZliRLK8INKCgGzYLRA=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw=
|
go.opentelemetry.io/otel/sdk/metric v1.27.1-0.20240624175855-921eb701b175/go.mod h1:SRwqsyIihvNIPKOVe1CqC4owsJX2vv63U5op9Axd4fI=
|
||||||
go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
|
go.opentelemetry.io/otel/trace v1.27.1-0.20240624175855-921eb701b175 h1:1y2KlY7+gTBn4GZa2yMKqgcb4H2KIOrBSSrG4esCC3g=
|
||||||
go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
|
go.opentelemetry.io/otel/trace v1.27.1-0.20240624175855-921eb701b175/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||||
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
|
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
@ -1547,10 +1547,10 @@ google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6D
|
||||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
|
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
|
||||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d h1:Aqf0fiIdUQEj0Gn9mKFFXoQfTTEaNopWpfVyYADxiSg=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Od4k8V1LQSizPRUK4OzZ7TBE/20k+jPczUDAEyvn69Y=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||||
|
@ -1588,8 +1588,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
|
@ -7,7 +7,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./fixtures/tracing/tempo.yaml:/etc/tempo.yaml
|
- ./fixtures/tracing/tempo.yaml:/etc/tempo.yaml
|
||||||
otel-collector:
|
otel-collector:
|
||||||
image: otel/opentelemetry-collector-contrib:0.89.0
|
image: otel/opentelemetry-collector-contrib:0.103.0
|
||||||
volumes:
|
volumes:
|
||||||
- ./fixtures/tracing/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
|
- ./fixtures/tracing/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
|
||||||
whoami:
|
whoami:
|
||||||
|
|
|
@ -2,7 +2,9 @@ package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -96,27 +98,46 @@ func (s *TracingSuite) TestOpentelemetryBasic_HTTP() {
|
||||||
{
|
{
|
||||||
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
|
"batches.0.scopeSpans.0.spans.0.name": "ReverseProxy",
|
||||||
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_SERVER",
|
"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=\"http.request.method\").value.stringValue": "GET",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue": "1.1",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/basic",
|
"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.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.1.name": "Router",
|
"batches.0.scopeSpans.0.spans.1.name": "Metrics",
|
||||||
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router0@file",
|
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-service",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.2.name": "Service",
|
"batches.0.scopeSpans.0.spans.2.name": "Service",
|
||||||
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.3.name": "ReverseProxy",
|
"batches.0.scopeSpans.0.spans.3.name": "Router",
|
||||||
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_CLIENT",
|
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"url.scheme\").value.stringValue": "http",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.router.name\").value.stringValue": "router0@file",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.route\").value.stringValue": "Path(`/basic`)",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.4.name": "Metrics",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-entrypoint",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.5.name": "EntryPoint",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_SERVER",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"url.path\").value.stringValue": "/basic",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"url.query\").value.stringValue": "",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"server.address\").value.stringValue": "127.0.0.1:8000",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"network.peer.address\").value.stringValue": "127.0.0.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,27 +166,35 @@ func (s *TracingSuite) TestOpentelemetryBasic_gRPC() {
|
||||||
{
|
{
|
||||||
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
|
"batches.0.scopeSpans.0.spans.0.name": "ReverseProxy",
|
||||||
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_SERVER",
|
"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=\"http.request.method\").value.stringValue": "GET",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue": "1.1",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/basic",
|
"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.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.1.name": "Router",
|
"batches.0.scopeSpans.0.spans.1.name": "Metrics",
|
||||||
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router0@file",
|
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-service",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.2.name": "Service",
|
"batches.0.scopeSpans.0.spans.2.name": "Service",
|
||||||
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.3.name": "ReverseProxy",
|
"batches.0.scopeSpans.0.spans.3.name": "Router",
|
||||||
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_CLIENT",
|
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"url.scheme\").value.stringValue": "http",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.router.name\").value.stringValue": "router0@file",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.route\").value.stringValue": "Path(`/basic`)",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.4.name": "Metrics",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-entrypoint",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,54 +244,75 @@ func (s *TracingSuite) TestOpentelemetryRateLimit() {
|
||||||
{
|
{
|
||||||
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
|
"batches.0.scopeSpans.0.spans.0.name": "RateLimiter",
|
||||||
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_SERVER",
|
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/ratelimit",
|
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.1.name": "Router",
|
"batches.0.scopeSpans.0.spans.1.name": "Retry",
|
||||||
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router1@file",
|
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.2.name": "Retry",
|
"batches.0.scopeSpans.0.spans.2.name": "RateLimiter",
|
||||||
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.3.name": "RateLimiter",
|
"batches.0.scopeSpans.0.spans.3.name": "Retry",
|
||||||
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.request.resend_count\").value.intValue": "1",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.4.name": "Service",
|
"batches.0.scopeSpans.0.spans.4.name": "RateLimiter",
|
||||||
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
|
"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.middleware.name\").value.stringValue": "ratelimit-1@file",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.5.name": "ReverseProxy",
|
"batches.0.scopeSpans.0.spans.5.name": "Retry",
|
||||||
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_CLIENT",
|
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"url.scheme\").value.stringValue": "http",
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.request.resend_count\").value.intValue": "2",
|
||||||
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
|
||||||
|
"batches.0.scopeSpans.0.spans.6.name": "Router",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.router.name\").value.stringValue": "router1@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"http.route\").value.stringValue": "Path(`/ratelimit`)",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.7.name": "Metrics",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-entrypoint",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.8.name": "EntryPoint",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.kind": "SPAN_KIND_SERVER",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"url.path\").value.stringValue": "/ratelimit",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"url.query\").value.stringValue": "",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"server.address\").value.stringValue": "127.0.0.1:8000",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"network.peer.address\").value.stringValue": "127.0.0.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.response.status_code\").value.intValue": "429",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
|
"batches.0.scopeSpans.0.spans.0.name": "ReverseProxy",
|
||||||
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_SERVER",
|
"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=\"http.request.method\").value.stringValue": "GET",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue": "1.1",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/ratelimit",
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue": fmt.Sprintf("http://%s/ratelimit", net.JoinHostPort(s.whoamiIP, "80")),
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "429",
|
"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": "Router",
|
"batches.0.scopeSpans.0.spans.1.name": "Metrics",
|
||||||
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router1@file",
|
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-service",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.2.name": "Retry",
|
"batches.0.scopeSpans.0.spans.2.name": "Service",
|
||||||
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.3.name": "RateLimiter",
|
"batches.0.scopeSpans.0.spans.3.name": "RateLimiter",
|
||||||
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
@ -271,20 +321,27 @@ func (s *TracingSuite) TestOpentelemetryRateLimit() {
|
||||||
"batches.0.scopeSpans.0.spans.4.name": "Retry",
|
"batches.0.scopeSpans.0.spans.4.name": "Retry",
|
||||||
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.resend_count\").value.intValue": "1",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.5.name": "RateLimiter",
|
"batches.0.scopeSpans.0.spans.5.name": "Router",
|
||||||
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.router.name\").value.stringValue": "router1@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.route\").value.stringValue": "Path(`/ratelimit`)",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.6.name": "Retry",
|
"batches.0.scopeSpans.0.spans.6.name": "Metrics",
|
||||||
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-entrypoint",
|
||||||
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"http.resend_count\").value.intValue": "2",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.7.name": "RateLimiter",
|
"batches.0.scopeSpans.0.spans.7.name": "EntryPoint",
|
||||||
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_SERVER",
|
||||||
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"url.path\").value.stringValue": "/ratelimit",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"url.query\").value.stringValue": "",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"server.address\").value.stringValue": "127.0.0.1:8000",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"network.peer.address\").value.stringValue": "127.0.0.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,60 +369,102 @@ func (s *TracingSuite) TestOpentelemetryRetry() {
|
||||||
{
|
{
|
||||||
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
|
"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=\"http.request.method\").value.stringValue": "GET",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/retry",
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue": "1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue": fmt.Sprintf("http://%s/retry", net.JoinHostPort(s.whoamiIP, "81")),
|
||||||
|
"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": "81",
|
||||||
|
"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": "81",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
|
||||||
"batches.0.scopeSpans.0.spans.0.status.code": "STATUS_CODE_ERROR",
|
"batches.0.scopeSpans.0.spans.0.status.code": "STATUS_CODE_ERROR",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.1.name": "Router",
|
"batches.0.scopeSpans.0.spans.1.name": "Metrics",
|
||||||
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
|
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-service",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router2@file",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.2.name": "Retry",
|
"batches.0.scopeSpans.0.spans.2.name": "Service",
|
||||||
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.3.name": "Service",
|
"batches.0.scopeSpans.0.spans.3.name": "Retry",
|
||||||
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.4.name": "ReverseProxy",
|
"batches.0.scopeSpans.0.spans.4.name": "ReverseProxy",
|
||||||
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_CLIENT",
|
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_CLIENT",
|
||||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"url.scheme\").value.stringValue": "http",
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"network.protocol.version\").value.stringValue": "1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"url.full\").value.stringValue": fmt.Sprintf("http://%s/retry", net.JoinHostPort(s.whoamiIP, "81")),
|
||||||
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"network.peer.address\").value.stringValue": s.whoamiIP,
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"network.peer.port\").value.intValue": "81",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"server.address\").value.stringValue": s.whoamiIP,
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"server.port\").value.intValue": "81",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.status.code": "STATUS_CODE_ERROR",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.5.name": "Retry",
|
"batches.0.scopeSpans.0.spans.5.name": "Metrics",
|
||||||
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-service",
|
||||||
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.resend_count\").value.intValue": "1",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.6.name": "Service",
|
"batches.0.scopeSpans.0.spans.6.name": "Service",
|
||||||
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.7.name": "ReverseProxy",
|
"batches.0.scopeSpans.0.spans.7.name": "Retry",
|
||||||
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_CLIENT",
|
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"url.scheme\").value.stringValue": "http",
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.request.resend_count\").value.intValue": "1",
|
||||||
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.8.name": "Retry",
|
"batches.0.scopeSpans.0.spans.8.name": "ReverseProxy",
|
||||||
"batches.0.scopeSpans.0.spans.8.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.8.kind": "SPAN_KIND_CLIENT",
|
||||||
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.resend_count\").value.intValue": "2",
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"network.protocol.version\").value.stringValue": "1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"url.full\").value.stringValue": fmt.Sprintf("http://%s/retry", net.JoinHostPort(s.whoamiIP, "81")),
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"network.peer.address\").value.stringValue": s.whoamiIP,
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"network.peer.port\").value.intValue": "81",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"server.address\").value.stringValue": s.whoamiIP,
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"server.port\").value.intValue": "81",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.status.code": "STATUS_CODE_ERROR",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.9.name": "Service",
|
"batches.0.scopeSpans.0.spans.9.name": "Metrics",
|
||||||
"batches.0.scopeSpans.0.spans.9.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.9.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.9.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
|
"batches.0.scopeSpans.0.spans.9.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-service",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.10.name": "ReverseProxy",
|
"batches.0.scopeSpans.0.spans.10.name": "Service",
|
||||||
"batches.0.scopeSpans.0.spans.10.kind": "SPAN_KIND_CLIENT",
|
"batches.0.scopeSpans.0.spans.10.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"url.scheme\").value.stringValue": "http",
|
"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
|
||||||
"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
|
|
||||||
"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
"batches.0.scopeSpans.0.spans.11.name": "Retry",
|
||||||
|
"batches.0.scopeSpans.0.spans.11.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.11.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.11.attributes.#(key=\"http.request.resend_count\").value.intValue": "2",
|
||||||
|
|
||||||
|
"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.13.name": "Metrics",
|
||||||
|
"batches.0.scopeSpans.0.spans.13.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.13.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-entrypoint",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.14.name": "EntryPoint",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.kind": "SPAN_KIND_SERVER",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.attributes.#(key=\"url.path\").value.stringValue": "/retry",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.attributes.#(key=\"url.query\").value.stringValue": "",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.attributes.#(key=\"server.address\").value.stringValue": "127.0.0.1:8000",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.attributes.#(key=\"network.peer.address\").value.stringValue": "127.0.0.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.14.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,21 +492,131 @@ func (s *TracingSuite) TestOpentelemetryAuth() {
|
||||||
{
|
{
|
||||||
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
|
"batches.0.scopeSpans.0.spans.0.name": "BasicAuth",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/auth",
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "basic-auth@file",
|
||||||
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "401",
|
"batches.0.scopeSpans.0.spans.0.status.message": "Authentication failed",
|
||||||
|
"batches.0.scopeSpans.0.spans.0.status.code": "STATUS_CODE_ERROR",
|
||||||
|
|
||||||
"batches.0.scopeSpans.0.spans.1.name": "Router",
|
"batches.0.scopeSpans.0.spans.1.name": "Retry",
|
||||||
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router3@file",
|
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service3@file",
|
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.2.name": "BasicAuth",
|
||||||
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "basic-auth@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.2.status.message": "Authentication failed",
|
||||||
|
"batches.0.scopeSpans.0.spans.2.status.code": "STATUS_CODE_ERROR",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.3.name": "Retry",
|
||||||
|
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.request.resend_count\").value.intValue": "1",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.4.name": "BasicAuth",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "basic-auth@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.status.message": "Authentication failed",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.status.code": "STATUS_CODE_ERROR",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.5.name": "Retry",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.request.resend_count\").value.intValue": "2",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.6.name": "Router",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.service.name\").value.stringValue": "service3@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.router.name\").value.stringValue": "router3@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"http.route\").value.stringValue": "Path(`/auth`)",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.7.name": "Metrics",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-entrypoint",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.8.name": "EntryPoint",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.kind": "SPAN_KIND_SERVER",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"url.path\").value.stringValue": "/auth",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"url.query\").value.stringValue": "",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"server.address\").value.stringValue": "127.0.0.1:8000",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"network.peer.address\").value.stringValue": "127.0.0.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.response.status_code\").value.intValue": "401",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
s.checkTraceContent(contains)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TracingSuite) TestOpentelemetrySafeURL() {
|
||||||
|
file := s.adaptFile("fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
|
||||||
|
WhoamiIP: s.whoamiIP,
|
||||||
|
WhoamiPort: s.whoamiPort,
|
||||||
|
IP: s.otelCollectorIP,
|
||||||
|
})
|
||||||
|
defer os.Remove(file)
|
||||||
|
|
||||||
|
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://test:test@127.0.0.1:8000/auth?api_key=powpow", 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.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
|
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue": fmt.Sprintf("http://REDACTED:REDACTED@%s/auth?api_key=REDACTED", 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": "Metrics",
|
||||||
|
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-service",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.2.name": "Service",
|
||||||
|
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service3@file",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.3.name": "BasicAuth",
|
||||||
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
|
||||||
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "basic-auth@file",
|
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "basic-auth@file",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.4.name": "Retry",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.5.name": "Router",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.service.name\").value.stringValue": "service3@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.router.name\").value.stringValue": "router3@file",
|
||||||
|
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.route\").value.stringValue": "Path(`/auth`)",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.6.name": "Metrics",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
|
||||||
|
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "metrics-entrypoint",
|
||||||
|
|
||||||
|
"batches.0.scopeSpans.0.spans.7.name": "EntryPoint",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_SERVER",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"entry_point\").value.stringValue": "web",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"url.path\").value.stringValue": "/auth",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"url.query\").value.stringValue": "api_key=REDACTED",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"server.address\").value.stringValue": "127.0.0.1:8000",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"network.peer.address\").value.stringValue": "127.0.0.1",
|
||||||
|
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,12 +726,22 @@ func (s *TracingSuite) checkTraceContent(expectedJSON []map[string]string) {
|
||||||
contents = append(contents, string(content))
|
contents = append(contents, string(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var missingElements []string
|
||||||
for _, expected := range expectedJSON {
|
for _, expected := range expectedJSON {
|
||||||
containsAll(expected, contents)
|
missingElements = append(missingElements, contains(expected, contents)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("Contents: [%s]\n", strings.Join(contents, ","))
|
||||||
|
for _, element := range missingElements {
|
||||||
|
log.Printf("Missing elements:\n%s\n", element)
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Empty(s.T(), missingElements)
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsAll(expectedJSON map[string]string, contents []string) {
|
func contains(expectedJSON map[string]string, contents []string) []string {
|
||||||
|
var missingElements []string
|
||||||
|
|
||||||
for k, v := range expectedJSON {
|
for k, v := range expectedJSON {
|
||||||
found := false
|
found := false
|
||||||
for _, content := range contents {
|
for _, content := range contents {
|
||||||
|
@ -531,12 +750,12 @@ func containsAll(expectedJSON map[string]string, contents []string) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
log.Info().Msgf("[" + strings.Join(contents, ",") + "]")
|
missingElements = append(missingElements, "Key: "+k+", Value: "+v)
|
||||||
log.Error().Msgf("missing element: \nKey: %q\nValue: %q ", k, v)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return missingElements
|
||||||
}
|
}
|
||||||
|
|
||||||
// TraceResponse contains a list of traces.
|
// TraceResponse contains a list of traces.
|
||||||
|
|
|
@ -201,6 +201,7 @@ type Tracing struct {
|
||||||
GlobalAttributes map[string]string `description:"Defines additional attributes (key:value) on all spans." json:"globalAttributes,omitempty" toml:"globalAttributes,omitempty" yaml:"globalAttributes,omitempty" export:"true"`
|
GlobalAttributes map[string]string `description:"Defines additional attributes (key:value) on all spans." json:"globalAttributes,omitempty" toml:"globalAttributes,omitempty" yaml:"globalAttributes,omitempty" export:"true"`
|
||||||
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"`
|
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"`
|
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"`
|
||||||
|
SafeQueryParams []string `description:"Query params to not redact." json:"safeQueryParams,omitempty" toml:"safeQueryParams,omitempty" yaml:"safeQueryParams,omitempty" export:"true"`
|
||||||
SampleRate float64 `description:"Sets the rate between 0.0 and 1.0 of requests to trace." json:"sampleRate,omitempty" toml:"sampleRate,omitempty" yaml:"sampleRate,omitempty" export:"true"`
|
SampleRate float64 `description:"Sets the rate between 0.0 and 1.0 of requests to trace." json:"sampleRate,omitempty" toml:"sampleRate,omitempty" yaml:"sampleRate,omitempty" export:"true"`
|
||||||
AddInternals bool `description:"Enables tracing for internal services (ping, dashboard, etc...)." json:"addInternals,omitempty" toml:"addInternals,omitempty" yaml:"addInternals,omitempty" export:"true"`
|
AddInternals bool `description:"Enables tracing for internal services (ping, dashboard, etc...)." json:"addInternals,omitempty" toml:"addInternals,omitempty" yaml:"addInternals,omitempty" export:"true"`
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"go.opentelemetry.io/otel/metric"
|
"go.opentelemetry.io/otel/metric"
|
||||||
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
|
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
|
||||||
"go.opentelemetry.io/otel/sdk/resource"
|
"go.opentelemetry.io/otel/sdk/resource"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/encoding/gzip"
|
"google.golang.org/grpc/encoding/gzip"
|
||||||
)
|
)
|
||||||
|
@ -58,16 +58,16 @@ func NewSemConvMetricRegistry(ctx context.Context, config *types.OTLP) (*SemConv
|
||||||
meter := otel.Meter("github.com/traefik/traefik",
|
meter := otel.Meter("github.com/traefik/traefik",
|
||||||
metric.WithInstrumentationVersion(version.Version))
|
metric.WithInstrumentationVersion(version.Version))
|
||||||
|
|
||||||
httpServerRequestDuration, err := meter.Float64Histogram("http.server.request.duration",
|
httpServerRequestDuration, err := meter.Float64Histogram(semconv.HTTPServerRequestDurationName,
|
||||||
metric.WithDescription("Duration of HTTP server requests."),
|
metric.WithDescription(semconv.HTTPServerRequestDurationDescription),
|
||||||
metric.WithUnit("s"),
|
metric.WithUnit("s"),
|
||||||
metric.WithExplicitBucketBoundaries(config.ExplicitBoundaries...))
|
metric.WithExplicitBucketBoundaries(config.ExplicitBoundaries...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't build httpServerRequestDuration histogram: %w", err)
|
return nil, fmt.Errorf("can't build httpServerRequestDuration histogram: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClientRequestDuration, err := meter.Float64Histogram("http.client.request.duration",
|
httpClientRequestDuration, err := meter.Float64Histogram(semconv.HTTPClientRequestDurationName,
|
||||||
metric.WithDescription("Duration of HTTP client requests."),
|
metric.WithDescription(semconv.HTTPClientRequestDurationDescription),
|
||||||
metric.WithUnit("s"),
|
metric.WithUnit("s"),
|
||||||
metric.WithExplicitBucketBoundaries(config.ExplicitBoundaries...))
|
metric.WithExplicitBucketBoundaries(config.ExplicitBoundaries...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -513,7 +513,7 @@ func TestForwardAuthTracing(t *testing.T) {
|
||||||
attribute.String("url.scheme", "http"),
|
attribute.String("url.scheme", "http"),
|
||||||
attribute.String("user_agent.original", ""),
|
attribute.String("user_agent.original", ""),
|
||||||
attribute.String("network.peer.address", "127.0.0.1"),
|
attribute.String("network.peer.address", "127.0.0.1"),
|
||||||
attribute.String("network.peer.port", serverPort),
|
attribute.Int64("network.peer.port", int64(serverPortInt)),
|
||||||
attribute.String("server.address", "127.0.0.1"),
|
attribute.String("server.address", "127.0.0.1"),
|
||||||
attribute.Int64("server.port", int64(serverPortInt)),
|
attribute.Int64("server.port", int64(serverPortInt)),
|
||||||
attribute.StringSlice("http.request.header.x-foo", []string{"foo", "bar"}),
|
attribute.StringSlice("http.request.header.x-foo", []string{"foo", "bar"}),
|
||||||
|
@ -546,7 +546,7 @@ func TestForwardAuthTracing(t *testing.T) {
|
||||||
otel.SetTextMapPropagator(autoprop.NewTextMapPropagator())
|
otel.SetTextMapPropagator(autoprop.NewTextMapPropagator())
|
||||||
|
|
||||||
mockTracer := &mockTracer{}
|
mockTracer := &mockTracer{}
|
||||||
tracer := tracing.NewTracer(mockTracer, []string{"X-Foo"}, []string{"X-Bar"})
|
tracer := tracing.NewTracer(mockTracer, []string{"X-Foo"}, []string{"X-Bar"}, []string{"q"})
|
||||||
initialCtx, initialSpan := tracer.Start(req.Context(), "initial")
|
initialCtx, initialSpan := tracer.Start(req.Context(), "initial")
|
||||||
defer initialSpan.End()
|
defer initialSpan.End()
|
||||||
req = req.WithContext(initialCtx)
|
req = req.WithContext(initialCtx)
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/traefik/traefik/v3/pkg/tracing"
|
"github.com/traefik/traefik/v3/pkg/tracing"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/metric"
|
"go.opentelemetry.io/otel/metric"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
"go.opentelemetry.io/otel/trace/noop"
|
"go.opentelemetry.io/otel/trace/noop"
|
||||||
)
|
)
|
||||||
|
@ -35,7 +35,7 @@ type entryPointTracing struct {
|
||||||
func WrapEntryPointHandler(ctx context.Context, tracer *tracing.Tracer, semConvMetricRegistry *metrics.SemConvMetricsRegistry, entryPointName string) alice.Constructor {
|
func WrapEntryPointHandler(ctx context.Context, tracer *tracing.Tracer, semConvMetricRegistry *metrics.SemConvMetricsRegistry, entryPointName string) alice.Constructor {
|
||||||
return func(next http.Handler) (http.Handler, error) {
|
return func(next http.Handler) (http.Handler, error) {
|
||||||
if tracer == nil {
|
if tracer == nil {
|
||||||
tracer = tracing.NewTracer(noop.Tracer{}, nil, nil)
|
tracer = tracing.NewTracer(noop.Tracer{}, nil, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newEntryPoint(ctx, tracer, semConvMetricRegistry, entryPointName, next), nil
|
return newEntryPoint(ctx, tracer, semConvMetricRegistry, entryPointName, next), nil
|
||||||
|
@ -47,7 +47,7 @@ func newEntryPoint(ctx context.Context, tracer *tracing.Tracer, semConvMetricReg
|
||||||
middlewares.GetLogger(ctx, "tracing", entryPointTypeName).Debug().Msg("Creating middleware")
|
middlewares.GetLogger(ctx, "tracing", entryPointTypeName).Debug().Msg("Creating middleware")
|
||||||
|
|
||||||
if tracer == nil {
|
if tracer == nil {
|
||||||
tracer = tracing.NewTracer(noop.Tracer{}, nil, nil)
|
tracer = tracing.NewTracer(noop.Tracer{}, nil, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &entryPointTracing{
|
return &entryPointTracing{
|
||||||
|
|
|
@ -42,15 +42,14 @@ func TestEntryPointMiddleware_tracing(t *testing.T) {
|
||||||
attribute.String("network.protocol.version", "1.1"),
|
attribute.String("network.protocol.version", "1.1"),
|
||||||
attribute.Int64("http.request.body.size", int64(0)),
|
attribute.Int64("http.request.body.size", int64(0)),
|
||||||
attribute.String("url.path", "/search"),
|
attribute.String("url.path", "/search"),
|
||||||
attribute.String("url.query", "q=Opentelemetry"),
|
attribute.String("url.query", "q=Opentelemetry&token=REDACTED"),
|
||||||
attribute.String("url.scheme", "http"),
|
attribute.String("url.scheme", "http"),
|
||||||
attribute.String("user_agent.original", "entrypoint-test"),
|
attribute.String("user_agent.original", "entrypoint-test"),
|
||||||
attribute.String("server.address", "www.test.com"),
|
attribute.String("server.address", "www.test.com"),
|
||||||
attribute.String("network.peer.address", "10.0.0.1"),
|
attribute.String("network.peer.address", "10.0.0.1"),
|
||||||
attribute.String("network.peer.port", "1234"),
|
|
||||||
attribute.String("client.address", "10.0.0.1"),
|
attribute.String("client.address", "10.0.0.1"),
|
||||||
attribute.Int64("client.port", int64(1234)),
|
attribute.Int64("client.port", int64(1234)),
|
||||||
attribute.String("client.socket.address", ""),
|
attribute.Int64("network.peer.port", int64(1234)),
|
||||||
attribute.StringSlice("http.request.header.x-foo", []string{"foo", "bar"}),
|
attribute.StringSlice("http.request.header.x-foo", []string{"foo", "bar"}),
|
||||||
attribute.Int64("http.response.status_code", int64(404)),
|
attribute.Int64("http.response.status_code", int64(404)),
|
||||||
attribute.StringSlice("http.response.header.x-bar", []string{"foo", "bar"}),
|
attribute.StringSlice("http.response.header.x-bar", []string{"foo", "bar"}),
|
||||||
|
@ -61,7 +60,7 @@ func TestEntryPointMiddleware_tracing(t *testing.T) {
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodGet, "http://www.test.com/search?q=Opentelemetry", nil)
|
req := httptest.NewRequest(http.MethodGet, "http://www.test.com/search?q=Opentelemetry&token=123", nil)
|
||||||
rw := httptest.NewRecorder()
|
rw := httptest.NewRecorder()
|
||||||
req.RemoteAddr = "10.0.0.1:1234"
|
req.RemoteAddr = "10.0.0.1:1234"
|
||||||
req.Header.Set("User-Agent", "entrypoint-test")
|
req.Header.Set("User-Agent", "entrypoint-test")
|
||||||
|
@ -77,7 +76,7 @@ func TestEntryPointMiddleware_tracing(t *testing.T) {
|
||||||
|
|
||||||
tracer := &mockTracer{}
|
tracer := &mockTracer{}
|
||||||
|
|
||||||
handler := newEntryPoint(context.Background(), tracing.NewTracer(tracer, []string{"X-Foo"}, []string{"X-Bar"}), nil, test.entryPoint, next)
|
handler := newEntryPoint(context.Background(), tracing.NewTracer(tracer, []string{"X-Foo"}, []string{"X-Bar"}, []string{"q"}), nil, test.entryPoint, next)
|
||||||
handler.ServeHTTP(rw, req)
|
handler.ServeHTTP(rw, req)
|
||||||
|
|
||||||
for _, span := range tracer.spans {
|
for _, span := range tracer.spans {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||||
"github.com/traefik/traefik/v3/pkg/tracing"
|
"github.com/traefik/traefik/v3/pkg/tracing"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||||
"github.com/traefik/traefik/v3/pkg/tracing"
|
"github.com/traefik/traefik/v3/pkg/tracing"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ func (r *retry) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
currentSpan.SetAttributes(attribute.String("traefik.middleware.name", r.name))
|
currentSpan.SetAttributes(attribute.String("traefik.middleware.name", r.name))
|
||||||
// Only add the attribute "http.resend_count" defined by semantic conventions starting from second attempt.
|
// Only add the attribute "http.resend_count" defined by semantic conventions starting from second attempt.
|
||||||
if attempts > 1 {
|
if attempts > 1 {
|
||||||
currentSpan.SetAttributes(semconv.HTTPResendCount(attempts - 1))
|
currentSpan.SetAttributes(semconv.HTTPRequestResendCount(attempts - 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
req = req.WithContext(tracingCtx)
|
req = req.WithContext(tracingCtx)
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/traefik/traefik/v3/pkg/tracing"
|
"github.com/traefik/traefik/v3/pkg/tracing"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/metric"
|
"go.opentelemetry.io/otel/metric"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||||||
"go.opentelemetry.io/otel/sdk/resource"
|
"go.opentelemetry.io/otel/sdk/resource"
|
||||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/encoding/gzip"
|
"google.golang.org/grpc/encoding/gzip"
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -17,7 +19,7 @@ import (
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/codes"
|
"go.opentelemetry.io/otel/codes"
|
||||||
"go.opentelemetry.io/otel/propagation"
|
"go.opentelemetry.io/otel/propagation"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,7 +49,7 @@ func NewTracing(conf *static.Tracing) (*Tracer, io.Closer, error) {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewTracer(tr, conf.CapturedRequestHeaders, conf.CapturedResponseHeaders), closer, nil
|
return NewTracer(tr, conf.CapturedRequestHeaders, conf.CapturedResponseHeaders, conf.SafeQueryParams), closer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TracerFromContext extracts the trace.Tracer from the given context.
|
// TracerFromContext extracts the trace.Tracer from the given context.
|
||||||
|
@ -122,14 +124,16 @@ func (t TracerProvider) Tracer(name string, options ...trace.TracerOption) trace
|
||||||
type Tracer struct {
|
type Tracer struct {
|
||||||
trace.Tracer
|
trace.Tracer
|
||||||
|
|
||||||
|
safeQueryParams []string
|
||||||
capturedRequestHeaders []string
|
capturedRequestHeaders []string
|
||||||
capturedResponseHeaders []string
|
capturedResponseHeaders []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTracer builds and configures a new Tracer.
|
// NewTracer builds and configures a new Tracer.
|
||||||
func NewTracer(tracer trace.Tracer, capturedRequestHeaders, capturedResponseHeaders []string) *Tracer {
|
func NewTracer(tracer trace.Tracer, capturedRequestHeaders, capturedResponseHeaders, safeQueryParams []string) *Tracer {
|
||||||
return &Tracer{
|
return &Tracer{
|
||||||
Tracer: tracer,
|
Tracer: tracer,
|
||||||
|
safeQueryParams: safeQueryParams,
|
||||||
capturedRequestHeaders: capturedRequestHeaders,
|
capturedRequestHeaders: capturedRequestHeaders,
|
||||||
capturedResponseHeaders: capturedResponseHeaders,
|
capturedResponseHeaders: capturedResponseHeaders,
|
||||||
}
|
}
|
||||||
|
@ -153,37 +157,37 @@ func (t *Tracer) Start(ctx context.Context, spanName string, opts ...trace.SpanS
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaptureClientRequest used to add span attributes from the request as a Client.
|
// CaptureClientRequest used to add span attributes from the request as a Client.
|
||||||
// TODO: need to update the semconv package as it does not implement fully Semantic Convention v1.23.0.
|
|
||||||
func (t *Tracer) CaptureClientRequest(span trace.Span, r *http.Request) {
|
func (t *Tracer) CaptureClientRequest(span trace.Span, r *http.Request) {
|
||||||
if t == nil || span == nil || r == nil {
|
if t == nil || span == nil || r == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes
|
// Common attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/http/http-spans.md#common-attributes
|
||||||
span.SetAttributes(semconv.HTTPRequestMethodKey.String(r.Method))
|
span.SetAttributes(semconv.HTTPRequestMethodKey.String(r.Method))
|
||||||
span.SetAttributes(semconv.NetworkProtocolVersion(proto(r.Proto)))
|
span.SetAttributes(semconv.NetworkProtocolVersion(proto(r.Proto)))
|
||||||
|
|
||||||
// Client attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#http-client
|
// Client attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/http/http-spans.md#http-client
|
||||||
span.SetAttributes(semconv.URLFull(r.URL.String()))
|
sURL := t.safeURL(r.URL)
|
||||||
span.SetAttributes(semconv.URLScheme(r.URL.Scheme))
|
span.SetAttributes(semconv.URLFull(sURL.String()))
|
||||||
|
span.SetAttributes(semconv.URLScheme(sURL.Scheme))
|
||||||
span.SetAttributes(semconv.UserAgentOriginal(r.UserAgent()))
|
span.SetAttributes(semconv.UserAgentOriginal(r.UserAgent()))
|
||||||
|
|
||||||
host, port, err := net.SplitHostPort(r.URL.Host)
|
host, port, err := net.SplitHostPort(sURL.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.SetAttributes(attribute.String("network.peer.address", host))
|
span.SetAttributes(semconv.NetworkPeerAddress(host))
|
||||||
span.SetAttributes(semconv.ServerAddress(r.URL.Host))
|
span.SetAttributes(semconv.ServerAddress(sURL.Host))
|
||||||
switch r.URL.Scheme {
|
switch sURL.Scheme {
|
||||||
case "http":
|
case "http":
|
||||||
span.SetAttributes(attribute.String("network.peer.port", "80"))
|
span.SetAttributes(semconv.NetworkPeerPort(80))
|
||||||
span.SetAttributes(semconv.ServerPort(80))
|
span.SetAttributes(semconv.ServerPort(80))
|
||||||
case "https":
|
case "https":
|
||||||
span.SetAttributes(attribute.String("network.peer.port", "443"))
|
span.SetAttributes(semconv.NetworkPeerPort(443))
|
||||||
span.SetAttributes(semconv.ServerPort(443))
|
span.SetAttributes(semconv.ServerPort(443))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
span.SetAttributes(attribute.String("network.peer.address", host))
|
span.SetAttributes(semconv.NetworkPeerAddress(host))
|
||||||
span.SetAttributes(attribute.String("network.peer.port", port))
|
|
||||||
intPort, _ := strconv.Atoi(port)
|
intPort, _ := strconv.Atoi(port)
|
||||||
|
span.SetAttributes(semconv.NetworkPeerPort(intPort))
|
||||||
span.SetAttributes(semconv.ServerAddress(host))
|
span.SetAttributes(semconv.ServerAddress(host))
|
||||||
span.SetAttributes(semconv.ServerPort(intPort))
|
span.SetAttributes(semconv.ServerPort(intPort))
|
||||||
}
|
}
|
||||||
|
@ -201,20 +205,20 @@ func (t *Tracer) CaptureClientRequest(span trace.Span, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaptureServerRequest used to add span attributes from the request as a Server.
|
// CaptureServerRequest used to add span attributes from the request as a Server.
|
||||||
// TODO: need to update the semconv package as it does not implement fully Semantic Convention v1.23.0.
|
|
||||||
func (t *Tracer) CaptureServerRequest(span trace.Span, r *http.Request) {
|
func (t *Tracer) CaptureServerRequest(span trace.Span, r *http.Request) {
|
||||||
if t == nil || span == nil || r == nil {
|
if t == nil || span == nil || r == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes
|
// Common attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/http/http-spans.md#common-attributes
|
||||||
span.SetAttributes(semconv.HTTPRequestMethodKey.String(r.Method))
|
span.SetAttributes(semconv.HTTPRequestMethodKey.String(r.Method))
|
||||||
span.SetAttributes(semconv.NetworkProtocolVersion(proto(r.Proto)))
|
span.SetAttributes(semconv.NetworkProtocolVersion(proto(r.Proto)))
|
||||||
|
|
||||||
// Server attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#http-server-semantic-conventions
|
sURL := t.safeURL(r.URL)
|
||||||
|
// Server attributes https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/http/http-spans.md#http-server-semantic-conventions
|
||||||
span.SetAttributes(semconv.HTTPRequestBodySize(int(r.ContentLength)))
|
span.SetAttributes(semconv.HTTPRequestBodySize(int(r.ContentLength)))
|
||||||
span.SetAttributes(semconv.URLPath(r.URL.Path))
|
span.SetAttributes(semconv.URLPath(sURL.Path))
|
||||||
span.SetAttributes(semconv.URLQuery(r.URL.RawQuery))
|
span.SetAttributes(semconv.URLQuery(sURL.RawQuery))
|
||||||
span.SetAttributes(semconv.URLScheme(r.Header.Get("X-Forwarded-Proto")))
|
span.SetAttributes(semconv.URLScheme(r.Header.Get("X-Forwarded-Proto")))
|
||||||
span.SetAttributes(semconv.UserAgentOriginal(r.UserAgent()))
|
span.SetAttributes(semconv.UserAgentOriginal(r.UserAgent()))
|
||||||
span.SetAttributes(semconv.ServerAddress(r.Host))
|
span.SetAttributes(semconv.ServerAddress(r.Host))
|
||||||
|
@ -222,17 +226,15 @@ func (t *Tracer) CaptureServerRequest(span trace.Span, r *http.Request) {
|
||||||
host, port, err := net.SplitHostPort(r.RemoteAddr)
|
host, port, err := net.SplitHostPort(r.RemoteAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.SetAttributes(semconv.ClientAddress(r.RemoteAddr))
|
span.SetAttributes(semconv.ClientAddress(r.RemoteAddr))
|
||||||
span.SetAttributes(attribute.String("network.peer.address", r.RemoteAddr))
|
span.SetAttributes(semconv.NetworkPeerAddress(r.Host))
|
||||||
} else {
|
} else {
|
||||||
span.SetAttributes(attribute.String("network.peer.address", host))
|
span.SetAttributes(semconv.NetworkPeerAddress(host))
|
||||||
span.SetAttributes(attribute.String("network.peer.port", port))
|
|
||||||
span.SetAttributes(semconv.ClientAddress(host))
|
span.SetAttributes(semconv.ClientAddress(host))
|
||||||
intPort, _ := strconv.Atoi(port)
|
intPort, _ := strconv.Atoi(port)
|
||||||
span.SetAttributes(semconv.ClientPort(intPort))
|
span.SetAttributes(semconv.ClientPort(intPort))
|
||||||
|
span.SetAttributes(semconv.NetworkPeerPort(intPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
span.SetAttributes(semconv.ClientSocketAddress(r.Header.Get("X-Forwarded-For")))
|
|
||||||
|
|
||||||
for _, header := range t.capturedRequestHeaders {
|
for _, header := range t.capturedRequestHeaders {
|
||||||
// User-agent is already part of the semantic convention as a recommended attribute.
|
// User-agent is already part of the semantic convention as a recommended attribute.
|
||||||
if strings.EqualFold(header, "User-Agent") {
|
if strings.EqualFold(header, "User-Agent") {
|
||||||
|
@ -273,6 +275,32 @@ func (t *Tracer) CaptureResponse(span trace.Span, responseHeaders http.Header, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tracer) safeURL(originalURL *url.URL) *url.URL {
|
||||||
|
if originalURL == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
redactedURL := *originalURL
|
||||||
|
|
||||||
|
// Redact password if exists.
|
||||||
|
if redactedURL.User != nil {
|
||||||
|
redactedURL.User = url.UserPassword("REDACTED", "REDACTED")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redact query parameters.
|
||||||
|
query := redactedURL.Query()
|
||||||
|
for k := range query {
|
||||||
|
if slices.Contains(t.safeQueryParams, k) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
query.Set(k, "REDACTED")
|
||||||
|
}
|
||||||
|
redactedURL.RawQuery = query.Encode()
|
||||||
|
|
||||||
|
return &redactedURL
|
||||||
|
}
|
||||||
|
|
||||||
func proto(proto string) string {
|
func proto(proto string) string {
|
||||||
switch proto {
|
switch proto {
|
||||||
case "HTTP/1.0":
|
case "HTTP/1.0":
|
||||||
|
|
57
pkg/tracing/tracing_test.go
Normal file
57
pkg/tracing/tracing_test.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package tracing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_safeFullURL(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
safeQueryParams []string
|
||||||
|
originalURL *url.URL
|
||||||
|
expectedURL *url.URL
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "Nil URL",
|
||||||
|
originalURL: nil,
|
||||||
|
expectedURL: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "No query parameters",
|
||||||
|
originalURL: &url.URL{Scheme: "https", Host: "example.com"},
|
||||||
|
expectedURL: &url.URL{Scheme: "https", Host: "example.com"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "All query parameters redacted",
|
||||||
|
originalURL: &url.URL{Scheme: "https", Host: "example.com", RawQuery: "foo=bar&baz=qux"},
|
||||||
|
expectedURL: &url.URL{Scheme: "https", Host: "example.com", RawQuery: "baz=REDACTED&foo=REDACTED"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Some query parameters unredacted",
|
||||||
|
safeQueryParams: []string{"foo"},
|
||||||
|
originalURL: &url.URL{Scheme: "https", Host: "example.com", RawQuery: "foo=bar&baz=qux"},
|
||||||
|
expectedURL: &url.URL{Scheme: "https", Host: "example.com", RawQuery: "baz=REDACTED&foo=bar"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "User info and some query parameters redacted",
|
||||||
|
safeQueryParams: []string{"foo"},
|
||||||
|
originalURL: &url.URL{Scheme: "https", Host: "example.com", User: url.UserPassword("username", "password"), RawQuery: "foo=bar&baz=qux"},
|
||||||
|
expectedURL: &url.URL{Scheme: "https", Host: "example.com", User: url.UserPassword("REDACTED", "REDACTED"), RawQuery: "baz=REDACTED&foo=bar"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tr := NewTracer(nil, nil, nil, test.safeQueryParams)
|
||||||
|
|
||||||
|
gotURL := tr.safeURL(test.originalURL)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expectedURL, gotURL)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue