2018-01-25 14:00:05 +03:00
package integration
import (
2024-01-08 11:10:06 +03:00
"encoding/json"
2024-06-27 15:14:03 +03:00
"fmt"
2024-01-08 11:10:06 +03:00
"io"
2024-06-27 15:14:03 +03:00
"net"
2018-01-25 14:00:05 +03:00
"net/http"
2024-01-08 11:10:06 +03:00
"net/url"
2018-01-25 14:00:05 +03:00
"os"
2024-01-08 11:10:06 +03:00
"strings"
2024-01-09 19:00:07 +03:00
"testing"
2018-01-25 14:00:05 +03:00
"time"
2024-01-10 12:47:44 +03:00
"github.com/rs/zerolog/log"
2024-01-09 19:00:07 +03:00
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
2024-01-08 11:10:06 +03:00
"github.com/tidwall/gjson"
2023-02-03 17:24:05 +03:00
"github.com/traefik/traefik/v3/integration/try"
2018-01-25 14:00:05 +03:00
)
type TracingSuite struct {
BaseSuite
2024-01-08 11:10:06 +03:00
whoamiIP string
whoamiPort int
tempoIP string
otelCollectorIP string
2018-01-25 14:00:05 +03:00
}
2024-01-09 19:00:07 +03:00
func TestTracingSuite ( t * testing . T ) {
suite . Run ( t , new ( TracingSuite ) )
2018-01-25 14:00:05 +03:00
}
type TracingTemplate struct {
2021-11-25 13:10:06 +03:00
WhoamiIP string
WhoamiPort int
2019-10-15 17:30:06 +03:00
IP string
TraceContextHeaderName string
2024-01-08 11:10:06 +03:00
IsHTTP bool
2018-01-25 14:00:05 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * TracingSuite ) SetupSuite ( ) {
s . BaseSuite . SetupSuite ( )
2024-01-08 11:10:06 +03:00
2024-01-09 19:00:07 +03:00
s . createComposeProject ( "tracing" )
s . composeUp ( )
2018-01-25 14:00:05 +03:00
2024-01-09 19:00:07 +03:00
s . whoamiIP = s . getComposeServiceIP ( "whoami" )
2021-11-25 13:10:06 +03:00
s . whoamiPort = 80
2018-01-25 14:00:05 +03:00
2024-01-08 11:10:06 +03:00
// Wait for whoami to turn ready.
err := try . GetRequest ( "http://" + s . whoamiIP + ":80" , 30 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
2024-01-10 12:47:44 +03:00
require . NoError ( s . T ( ) , err )
2024-01-08 11:10:06 +03:00
2024-01-10 12:47:44 +03:00
s . otelCollectorIP = s . getComposeServiceIP ( "otel-collector" )
2018-01-25 14:00:05 +03:00
2024-01-08 11:10:06 +03:00
// Wait for otel collector to turn ready.
err = try . GetRequest ( "http://" + s . otelCollectorIP + ":13133/" , 30 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
2024-01-10 12:47:44 +03:00
require . NoError ( s . T ( ) , err )
2018-01-25 14:00:05 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * TracingSuite ) TearDownSuite ( ) {
s . BaseSuite . TearDownSuite ( )
2018-01-25 14:00:05 +03:00
}
2024-01-10 12:47:44 +03:00
func ( s * TracingSuite ) SetupTest ( ) {
s . composeUp ( "tempo" )
s . tempoIP = s . getComposeServiceIP ( "tempo" )
2018-01-25 14:00:05 +03:00
2024-01-10 12:47:44 +03:00
// Wait for tempo to turn ready.
err := try . GetRequest ( "http://" + s . tempoIP + ":3200/ready" , 30 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2018-01-25 14:00:05 +03:00
}
2024-01-10 12:47:44 +03:00
func ( s * TracingSuite ) TearDownTest ( ) {
s . composeStop ( "tempo" )
2024-01-08 11:10:06 +03:00
}
2021-11-25 13:10:06 +03:00
2024-01-10 12:47:44 +03:00
func ( s * TracingSuite ) TestOpentelemetryBasic_HTTP ( ) {
file := s . adaptFile ( "fixtures/tracing/simple-opentelemetry.toml" , TracingTemplate {
2021-11-25 13:10:06 +03:00
WhoamiIP : s . whoamiIP ,
WhoamiPort : s . whoamiPort ,
2024-01-08 11:10:06 +03:00
IP : s . otelCollectorIP ,
IsHTTP : true ,
2018-01-25 14:00:05 +03:00
} )
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2018-01-25 14:00:05 +03:00
2019-05-16 11:58:06 +03:00
// wait for traefik
2024-01-09 19:00:07 +03:00
err := try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , time . Second , try . BodyContains ( "basic-auth" ) )
require . NoError ( s . T ( ) , err )
2019-05-16 11:58:06 +03:00
2024-01-08 11:10:06 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/basic" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2018-01-25 14:00:05 +03:00
2024-01-08 11:10:06 +03:00
contains := [ ] map [ string ] string {
{
"batches.0.scopeSpans.0.scope.name" : "github.com/traefik/traefik" ,
2018-01-25 14:00:05 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.0.name" : "ReverseProxy" ,
"batches.0.scopeSpans.0.spans.0.kind" : "SPAN_KIND_CLIENT" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue" : "GET" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue" : "1.1" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue" : fmt . Sprintf ( "http://%s/basic" , net . JoinHostPort ( s . whoamiIP , "80" ) ) ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"user_agent.original\").value.stringValue" : "Go-http-client/1.1" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.peer.address\").value.stringValue" : s . whoamiIP ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.peer.port\").value.intValue" : "80" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"server.address\").value.stringValue" : s . whoamiIP ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"server.port\").value.intValue" : "80" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue" : "200" ,
"batches.0.scopeSpans.0.spans.1.name" : "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" ,
2018-01-25 14:00:05 +03:00
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.2.name" : "Service" ,
"batches.0.scopeSpans.0.spans.2.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service0@file" ,
2018-01-25 14:00:05 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.3.name" : "Router" ,
"batches.0.scopeSpans.0.spans.3.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service0@file" ,
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.router.name\").value.stringValue" : "router0@file" ,
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"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" ,
2024-01-08 11:10:06 +03:00
} ,
}
2018-01-25 14:00:05 +03:00
2024-01-10 12:47:44 +03:00
s . checkTraceContent ( contains )
2024-01-08 11:10:06 +03:00
}
2021-11-25 13:10:06 +03:00
2024-01-10 12:47:44 +03:00
func ( s * TracingSuite ) TestOpentelemetryBasic_gRPC ( ) {
file := s . adaptFile ( "fixtures/tracing/simple-opentelemetry.toml" , TracingTemplate {
2021-11-25 13:10:06 +03:00
WhoamiIP : s . whoamiIP ,
2024-01-08 11:10:06 +03:00
WhoamiPort : s . whoamiPort ,
IP : s . otelCollectorIP ,
IsHTTP : false ,
2018-01-25 14:00:05 +03:00
} )
defer os . Remove ( file )
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2018-01-25 14:00:05 +03:00
2019-05-16 11:58:06 +03:00
// wait for traefik
2024-01-09 19:00:07 +03:00
err := try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , time . Second , try . BodyContains ( "basic-auth" ) )
require . NoError ( s . T ( ) , err )
2019-05-16 11:58:06 +03:00
2024-01-08 11:10:06 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/basic" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2018-01-25 14:00:05 +03:00
2024-01-08 11:10:06 +03:00
contains := [ ] map [ string ] string {
{
"batches.0.scopeSpans.0.scope.name" : "github.com/traefik/traefik" ,
2018-01-25 14:00:05 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.0.name" : "ReverseProxy" ,
"batches.0.scopeSpans.0.spans.0.kind" : "SPAN_KIND_CLIENT" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue" : "GET" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue" : "1.1" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue" : fmt . Sprintf ( "http://%s/basic" , net . JoinHostPort ( s . whoamiIP , "80" ) ) ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"user_agent.original\").value.stringValue" : "Go-http-client/1.1" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.peer.address\").value.stringValue" : s . whoamiIP ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.peer.port\").value.intValue" : "80" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"server.address\").value.stringValue" : s . whoamiIP ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"server.port\").value.intValue" : "80" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue" : "200" ,
"batches.0.scopeSpans.0.spans.1.name" : "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" ,
2018-01-25 14:00:05 +03:00
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.2.name" : "Service" ,
"batches.0.scopeSpans.0.spans.2.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service0@file" ,
2019-06-28 01:16:04 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.3.name" : "Router" ,
"batches.0.scopeSpans.0.spans.3.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service0@file" ,
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.router.name\").value.stringValue" : "router0@file" ,
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"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" ,
2024-01-08 11:10:06 +03:00
} ,
}
2019-06-28 01:16:04 +03:00
2024-01-10 12:47:44 +03:00
s . checkTraceContent ( contains )
2019-06-28 01:16:04 +03:00
}
2024-01-10 12:47:44 +03:00
func ( s * TracingSuite ) TestOpentelemetryRateLimit ( ) {
file := s . adaptFile ( "fixtures/tracing/simple-opentelemetry.toml" , TracingTemplate {
2024-01-08 11:10:06 +03:00
WhoamiIP : s . whoamiIP ,
WhoamiPort : s . whoamiPort ,
IP : s . otelCollectorIP ,
2019-06-28 01:16:04 +03:00
} )
defer os . Remove ( file )
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-06-28 01:16:04 +03:00
// wait for traefik
2024-01-09 19:00:07 +03:00
err := try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , time . Second , try . BodyContains ( "basic-auth" ) )
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/ratelimit" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/ratelimit" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/ratelimit" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusTooManyRequests ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
// sleep for 4 seconds to be certain the configured time period has elapsed
// then test another request and verify a 200 status code
time . Sleep ( 4 * time . Second )
err = try . GetRequest ( "http://127.0.0.1:8000/ratelimit" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
// continue requests at 3 second intervals to test the other rate limit time period
time . Sleep ( 3 * time . Second )
err = try . GetRequest ( "http://127.0.0.1:8000/ratelimit" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
time . Sleep ( 3 * time . Second )
err = try . GetRequest ( "http://127.0.0.1:8000/ratelimit" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/ratelimit" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusTooManyRequests ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
2024-01-08 11:10:06 +03:00
contains := [ ] map [ string ] string {
{
"batches.0.scopeSpans.0.scope.name" : "github.com/traefik/traefik" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.0.name" : "RateLimiter" ,
"batches.0.scopeSpans.0.spans.0.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "ratelimit-1@file" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.1.name" : "Retry" ,
"batches.0.scopeSpans.0.spans.1.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "retry@file" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.2.name" : "RateLimiter" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.2.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "ratelimit-1@file" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.3.name" : "Retry" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.3.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"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" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.4.name" : "RateLimiter" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.4.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "ratelimit-1@file" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"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" : "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" ,
2024-01-08 11:10:06 +03:00
} ,
{
"batches.0.scopeSpans.0.scope.name" : "github.com/traefik/traefik" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.0.name" : "ReverseProxy" ,
"batches.0.scopeSpans.0.spans.0.kind" : "SPAN_KIND_CLIENT" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue" : "GET" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue" : "1.1" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue" : fmt . Sprintf ( "http://%s/ratelimit" , 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" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.2.name" : "Service" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.2.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service1@file" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.3.name" : "RateLimiter" ,
"batches.0.scopeSpans.0.spans.3.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "ratelimit-1@file" ,
"batches.0.scopeSpans.0.spans.4.name" : "Retry" ,
"batches.0.scopeSpans.0.spans.4.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "retry@file" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.5.name" : "Router" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.5.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"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`)" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.6.name" : "Metrics" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.6.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"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" : "/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" ,
2024-01-08 11:10:06 +03:00
} ,
}
2024-01-10 12:47:44 +03:00
s . checkTraceContent ( contains )
2019-06-28 01:16:04 +03:00
}
2024-01-10 12:47:44 +03:00
func ( s * TracingSuite ) TestOpentelemetryRetry ( ) {
file := s . adaptFile ( "fixtures/tracing/simple-opentelemetry.toml" , TracingTemplate {
2024-01-08 11:10:06 +03:00
WhoamiIP : s . whoamiIP ,
WhoamiPort : 81 ,
IP : s . otelCollectorIP ,
2019-06-28 01:16:04 +03:00
} )
defer os . Remove ( file )
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-06-28 01:16:04 +03:00
// wait for traefik
2024-03-12 11:48:04 +03:00
err := try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 2 * time . Second , try . BodyContains ( "basic-auth" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/retry" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusBadGateway ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
2024-01-08 11:10:06 +03:00
contains := [ ] map [ string ] string {
{
"batches.0.scopeSpans.0.scope.name" : "github.com/traefik/traefik" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.0.name" : "ReverseProxy" ,
"batches.0.scopeSpans.0.spans.0.kind" : "SPAN_KIND_CLIENT" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue" : "GET" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"network.protocol.version\").value.stringValue" : "1.1" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.full\").value.stringValue" : fmt . Sprintf ( "http://%s/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.status.code" : "STATUS_CODE_ERROR" ,
"batches.0.scopeSpans.0.spans.1.name" : "Metrics" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.1.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "metrics-service" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.2.name" : "Service" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.2.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service2@file" ,
2024-01-08 11:10:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.3.name" : "Retry" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.3.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"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.kind" : "SPAN_KIND_CLIENT" ,
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.request.method\").value.stringValue" : "GET" ,
"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=\"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" : "Metrics" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.5.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "metrics-service" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.6.name" : "Service" ,
"batches.0.scopeSpans.0.spans.6.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service2@file" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.7.name" : "Retry" ,
"batches.0.scopeSpans.0.spans.7.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "retry@file" ,
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.request.resend_count\").value.intValue" : "1" ,
"batches.0.scopeSpans.0.spans.8.name" : "ReverseProxy" ,
"batches.0.scopeSpans.0.spans.8.kind" : "SPAN_KIND_CLIENT" ,
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.request.method\").value.stringValue" : "GET" ,
"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" : "Metrics" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.9.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.9.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "metrics-service" ,
"batches.0.scopeSpans.0.spans.10.name" : "Service" ,
"batches.0.scopeSpans.0.spans.10.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service2@file" ,
"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" ,
2024-01-08 11:10:06 +03:00
} ,
}
2024-01-10 12:47:44 +03:00
s . checkTraceContent ( contains )
2019-06-28 01:16:04 +03:00
}
2024-01-10 12:47:44 +03:00
func ( s * TracingSuite ) TestOpentelemetryAuth ( ) {
file := s . adaptFile ( "fixtures/tracing/simple-opentelemetry.toml" , TracingTemplate {
2024-01-08 11:10:06 +03:00
WhoamiIP : s . whoamiIP ,
WhoamiPort : s . whoamiPort ,
IP : s . otelCollectorIP ,
2019-10-15 17:30:06 +03:00
} )
defer os . Remove ( file )
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-10-15 17:30:06 +03:00
// wait for traefik
2024-01-09 19:00:07 +03:00
err := try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , time . Second , try . BodyContains ( "basic-auth" ) )
require . NoError ( s . T ( ) , err )
2019-10-15 17:30:06 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/auth" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusUnauthorized ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 17:30:06 +03:00
2024-01-08 11:10:06 +03:00
contains := [ ] map [ string ] string {
{
"batches.0.scopeSpans.0.scope.name" : "github.com/traefik/traefik" ,
2019-10-15 17:30:06 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.0.name" : "BasicAuth" ,
"batches.0.scopeSpans.0.spans.0.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "basic-auth@file" ,
"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" : "Retry" ,
"batches.0.scopeSpans.0.spans.1.kind" : "SPAN_KIND_INTERNAL" ,
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.middleware.name\").value.stringValue" : "retry@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.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" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue" : "GET" ,
2024-06-27 15:14:03 +03:00
"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" ,
2021-11-25 13:10:06 +03:00
2024-06-27 15:14:03 +03:00
"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" ,
2019-06-28 01:16:04 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.2.name" : "Service" ,
2024-01-08 11:10:06 +03:00
"batches.0.scopeSpans.0.spans.2.kind" : "SPAN_KIND_INTERNAL" ,
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue" : "service3@file" ,
2019-06-28 01:16:04 +03:00
2024-06-27 15:14:03 +03:00
"batches.0.scopeSpans.0.spans.3.name" : "BasicAuth" ,
2024-01-08 11:10:06 +03:00
"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" ,
2024-06-27 15:14:03 +03:00
"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" ,
2024-01-08 11:10:06 +03:00
} ,
}
2024-01-10 12:47:44 +03:00
s . checkTraceContent ( contains )
2024-01-08 11:10:06 +03:00
}
2024-01-30 18:28:05 +03:00
func ( s * TracingSuite ) TestNoInternals ( ) {
file := s . adaptFile ( "fixtures/tracing/simple-opentelemetry.toml" , TracingTemplate {
WhoamiIP : s . whoamiIP ,
WhoamiPort : s . whoamiPort ,
IP : s . otelCollectorIP ,
IsHTTP : true ,
} )
s . traefikCmd ( withConfigFile ( file ) )
// wait for traefik
2024-03-12 11:48:04 +03:00
err := try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 2 * time . Second , try . BodyContains ( "basic-auth" ) )
2024-01-30 18:28:05 +03:00
require . NoError ( s . T ( ) , err )
err = try . GetRequest ( "http://127.0.0.1:8000/ratelimit" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
require . NoError ( s . T ( ) , err )
err = try . GetRequest ( "http://127.0.0.1:8000/ping" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
require . NoError ( s . T ( ) , err )
err = try . GetRequest ( "http://127.0.0.1:8080/ping" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) )
require . NoError ( s . T ( ) , err )
baseURL , err := url . Parse ( "http://" + s . tempoIP + ":3200/api/search" )
require . NoError ( s . T ( ) , err )
req := & http . Request {
Method : http . MethodGet ,
URL : baseURL ,
}
// Wait for traces to be available.
time . Sleep ( 10 * time . Second )
resp , err := try . Response ( req , 5 * time . Second )
require . NoError ( s . T ( ) , err )
out := & TraceResponse { }
content , err := io . ReadAll ( resp . Body )
require . NoError ( s . T ( ) , err )
err = json . Unmarshal ( content , & out )
require . NoError ( s . T ( ) , err )
s . NotEmptyf ( len ( out . Traces ) , "expected at least one trace" )
for _ , t := range out . Traces {
baseURL , err := url . Parse ( "http://" + s . tempoIP + ":3200/api/traces/" + t . TraceID )
require . NoError ( s . T ( ) , err )
req := & http . Request {
Method : http . MethodGet ,
URL : baseURL ,
}
resp , err := try . Response ( req , 5 * time . Second )
require . NoError ( s . T ( ) , err )
content , err := io . ReadAll ( resp . Body )
require . NoError ( s . T ( ) , err )
require . NotContains ( s . T ( ) , content , "@internal" )
}
}
2024-01-10 12:47:44 +03:00
func ( s * TracingSuite ) checkTraceContent ( expectedJSON [ ] map [ string ] string ) {
s . T ( ) . Helper ( )
baseURL , err := url . Parse ( "http://" + s . tempoIP + ":3200/api/search" )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
2024-01-08 11:10:06 +03:00
req := & http . Request {
Method : http . MethodGet ,
URL : baseURL ,
}
// Wait for traces to be available.
time . Sleep ( 10 * time . Second )
resp , err := try . Response ( req , 5 * time . Second )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-06-28 01:16:04 +03:00
2024-01-08 11:10:06 +03:00
out := & TraceResponse { }
content , err := io . ReadAll ( resp . Body )
2024-01-10 12:47:44 +03:00
require . NoError ( s . T ( ) , err )
2024-01-08 11:10:06 +03:00
err = json . Unmarshal ( content , & out )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-07-15 15:52:04 +03:00
2024-01-10 12:47:44 +03:00
s . NotEmptyf ( len ( out . Traces ) , "expected at least one trace" )
2021-11-25 13:10:06 +03:00
2024-01-08 11:10:06 +03:00
var contents [ ] string
for _ , t := range out . Traces {
2024-01-10 12:47:44 +03:00
baseURL , err := url . Parse ( "http://" + s . tempoIP + ":3200/api/traces/" + t . TraceID )
require . NoError ( s . T ( ) , err )
2019-07-15 15:52:04 +03:00
2024-01-08 11:10:06 +03:00
req := & http . Request {
Method : http . MethodGet ,
URL : baseURL ,
}
2019-07-15 15:52:04 +03:00
2024-01-08 11:10:06 +03:00
resp , err := try . Response ( req , 5 * time . Second )
2024-01-10 12:47:44 +03:00
require . NoError ( s . T ( ) , err )
2019-07-15 15:52:04 +03:00
2024-01-08 11:10:06 +03:00
content , err := io . ReadAll ( resp . Body )
2024-01-10 12:47:44 +03:00
require . NoError ( s . T ( ) , err )
2019-07-15 15:52:04 +03:00
2024-01-08 11:10:06 +03:00
contents = append ( contents , string ( content ) )
}
2024-06-27 15:14:03 +03:00
var missingElements [ ] string
2024-01-08 11:10:06 +03:00
for _ , expected := range expectedJSON {
2024-06-27 15:14:03 +03:00
missingElements = append ( missingElements , contains ( expected , contents ) ... )
2024-01-08 11:10:06 +03:00
}
2024-06-27 15:14:03 +03:00
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 )
2024-01-08 11:10:06 +03:00
}
2024-06-27 15:14:03 +03:00
func contains ( expectedJSON map [ string ] string , contents [ ] string ) [ ] string {
var missingElements [ ] string
2024-01-08 11:10:06 +03:00
for k , v := range expectedJSON {
found := false
for _ , content := range contents {
if gjson . Get ( content , k ) . String ( ) == v {
found = true
break
}
}
if ! found {
2024-06-27 15:14:03 +03:00
missingElements = append ( missingElements , "Key: " + k + ", Value: " + v )
2024-01-08 11:10:06 +03:00
}
}
2024-06-27 15:14:03 +03:00
return missingElements
2024-01-08 11:10:06 +03:00
}
// TraceResponse contains a list of traces.
type TraceResponse struct {
Traces [ ] Trace ` json:"traces" `
}
// Trace represents a simplified grafana tempo trace.
type Trace struct {
TraceID string ` json:"traceID" `
2019-07-15 15:52:04 +03:00
}