Add internal/tracing: env-gated OTel setup, span/log helpers, decorators
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
82
internal/tracing/http_test.go
Normal file
82
internal/tracing/http_test.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/sdk/trace/tracetest"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
const sampleTraceparent = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
|
||||
|
||||
func TestHTTPMiddleware(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
newServer := func(lines *[]string, tp *sdktrace.TracerProvider) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
logf.FromContext(r.Context()).Info("handling")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
mux.HandleFunc("GET /healthz", handler)
|
||||
mux.HandleFunc("GET /v1/things/{id}", handler)
|
||||
return HTTPMiddleware("discovery", captureLogger(lines), WithTracerProvider(tp))(mux)
|
||||
}
|
||||
|
||||
t.Run("route span, enriched handler logs, traceparent continuation", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
sr := tracetest.NewSpanRecorder()
|
||||
tp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr))
|
||||
t.Cleanup(func() { _ = tp.Shutdown(context.Background()) })
|
||||
|
||||
var lines []string
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/v1/things/42", nil)
|
||||
req.Header.Set("traceparent", sampleTraceparent)
|
||||
newServer(&lines, tp).ServeHTTP(rec, req)
|
||||
|
||||
ended := sr.Ended()
|
||||
if len(ended) != 1 {
|
||||
t.Fatalf("got %d spans, want 1", len(ended))
|
||||
}
|
||||
if got := ended[0].Name(); got != "GET /v1/things/{id}" {
|
||||
t.Errorf("span name = %q, want route pattern", got)
|
||||
}
|
||||
wantTrace := "4bf92f3577b34da6a3ce929d0e0e4736"
|
||||
if got := ended[0].SpanContext().TraceID().String(); got != wantTrace {
|
||||
t.Errorf("span traceID = %s, want continuation of client trace %s", got, wantTrace)
|
||||
}
|
||||
if len(lines) != 1 {
|
||||
t.Fatalf("got %d log lines, want 1: %v", len(lines), lines)
|
||||
}
|
||||
if n := strings.Count(lines[0], `"traceID"`); n != 1 {
|
||||
t.Errorf("traceID appears %d times, want 1: %s", n, lines[0])
|
||||
}
|
||||
if !strings.Contains(lines[0], wantTrace) {
|
||||
t.Errorf("handler log missing traceID %s: %s", wantTrace, lines[0])
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("healthz is not traced but still gets a logger", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
sr := tracetest.NewSpanRecorder()
|
||||
tp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr))
|
||||
t.Cleanup(func() { _ = tp.Shutdown(context.Background()) })
|
||||
|
||||
var lines []string
|
||||
rec := httptest.NewRecorder()
|
||||
newServer(&lines, tp).ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/healthz", nil))
|
||||
|
||||
if len(sr.Ended()) != 0 {
|
||||
t.Fatalf("healthz produced %d spans, want 0", len(sr.Ended()))
|
||||
}
|
||||
if len(lines) != 1 || strings.Contains(lines[0], "traceID") {
|
||||
t.Fatalf("want one unenriched log line, got %v", lines)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user