diff --git a/go.mod b/go.mod index c619558..f4b5f2e 100644 --- a/go.mod +++ b/go.mod @@ -22,9 +22,11 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.10.0 + github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 go.opentelemetry.io/otel v1.34.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 go.opentelemetry.io/otel/sdk v1.34.0 + go.opentelemetry.io/otel/trace v1.34.0 go.uber.org/automaxprocs v1.6.0 golang.org/x/crypto v0.32.0 golang.org/x/oauth2 v0.25.0 @@ -72,11 +74,12 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 // indirect github.com/yuin/gopher-lua v1.1.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/log v0.6.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect diff --git a/go.sum b/go.sum index 0cae49d..6c9c343 100644 --- a/go.sum +++ b/go.sum @@ -150,6 +150,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 h1:H8wwQwTe5sL6x30z71lUgNiwBdeCHQjrphCfLwqIHGo= +github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2/go.mod h1:/kR4beFhlz2g+V5ik8jW+3PMiMQAPt29y6K64NNY53c= +github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 h1:3/aHKUq7qaFMWxyQV0W2ryNgg8x8rVeKVA20KJUkfS0= +github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2/go.mod h1:Zit4b8AQXaXvA68+nzmbyDzqiyFRISyw1JiD5JqUBjw= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= @@ -160,6 +164,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glB go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3LeK8= +go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= diff --git a/internal/observability/otel.go b/internal/observability/otel.go index ed8d70b..5f57a83 100644 --- a/internal/observability/otel.go +++ b/internal/observability/otel.go @@ -6,6 +6,7 @@ import ( "github.com/nais/wonderwall/pkg/config" log "github.com/sirupsen/logrus" + "go.opentelemetry.io/otel/trace/noop" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" @@ -13,6 +14,7 @@ import ( "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/semconv/v1.26.0" + oteltrace "go.opentelemetry.io/otel/trace" ) const ( @@ -20,6 +22,12 @@ const ( batchTimeout = 5 * time.Second ) +var tracer = noop.NewTracerProvider().Tracer("noop") + +func Tracer() oteltrace.Tracer { + return tracer +} + func OpenTelemetry(ctx context.Context, cfg *config.Config) (func(context.Context) error, error) { prop := newPropagator() otel.SetTextMapPropagator(prop) @@ -34,6 +42,7 @@ func OpenTelemetry(ctx context.Context, cfg *config.Config) (func(context.Contex return nil, err } otel.SetTracerProvider(tracerProvider) + tracer = tracerProvider.Tracer("wonderwall") log.Infof("opentelemetry: initialized configuration") shutdown := func(ctx context.Context) error { diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go index 665e8ee..79b0996 100644 --- a/pkg/logging/logging.go +++ b/pkg/logging/logging.go @@ -5,6 +5,7 @@ import ( "time" log "github.com/sirupsen/logrus" + "github.com/uptrace/opentelemetry-go-extra/otellogrus" ) func TextFormatter() log.Formatter { @@ -39,5 +40,14 @@ func Setup(level, format string) error { log.SetLevel(logLevel) log.Tracef("Trace logging enabled") + // Add OpenTelemetry logging hook. + // This attaches logs to the associated span in the given log context as events. + log.AddHook(otellogrus.NewHook(otellogrus.WithLevels( + log.PanicLevel, + log.FatalLevel, + log.ErrorLevel, + log.WarnLevel, + ))) + return nil } diff --git a/pkg/middleware/logentry.go b/pkg/middleware/logentry.go index b5676cf..4a6eb90 100644 --- a/pkg/middleware/logentry.go +++ b/pkg/middleware/logentry.go @@ -78,7 +78,9 @@ func (l *requestLogger) NewLogEntry(r *http.Request) *requestLoggerEntry { "request_user_agent": r.UserAgent(), } - entry.Logger = l.Logger.WithFields(fields) + entry.Logger = l.Logger. + WithContext(r.Context()). + WithFields(fields) return entry } diff --git a/pkg/router/router.go b/pkg/router/router.go index e75fd85..3c5158f 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -3,10 +3,9 @@ package router import ( "net/http" - "github.com/riandyrn/otelchi" - "github.com/go-chi/chi/v5" chi_middleware "github.com/go-chi/chi/v5/middleware" + "github.com/riandyrn/otelchi" "github.com/nais/wonderwall/pkg/config" "github.com/nais/wonderwall/pkg/ingress" @@ -56,15 +55,15 @@ func New(src Source, cfg *config.Config) chi.Router { logentry := middleware.LogEntry(providerName) r := chi.NewRouter() - r.Use(middleware.CorrelationIDHandler) - r.Use(chi_middleware.Recoverer) - r.Use(ingressMw.Handler) - if cfg.OpenTelemetry.Enabled { r.Use(otelchi.Middleware(cfg.OpenTelemetry.ServiceName, otelchi.WithChiRoutes(r), - otelchi.WithRequestMethodInSpanName(true))) + otelchi.WithRequestMethodInSpanName(true), + )) } + r.Use(middleware.CorrelationIDHandler) + r.Use(chi_middleware.Recoverer) + r.Use(ingressMw.Handler) prefixes := src.GetIngresses().Paths()