Skip to content

Commit

Permalink
Merge pull request #1838 from openmeterio/fix/http-logger
Browse files Browse the repository at this point in the history
fix(logger): http context on logs
  • Loading branch information
tothandras authored Nov 13, 2024
2 parents 0c9cab5 + fa8e531 commit a8e062e
Show file tree
Hide file tree
Showing 15 changed files with 141 additions and 242 deletions.
45 changes: 26 additions & 19 deletions app/common/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (

"github.com/openmeterio/openmeter/app/config"
"github.com/openmeterio/openmeter/pkg/contextx"
"github.com/openmeterio/openmeter/pkg/framework/operation"
"github.com/openmeterio/openmeter/pkg/gosundheit"
)

Expand Down Expand Up @@ -89,25 +88,33 @@ func NewLoggerProvider(ctx context.Context, conf config.LogTelemetryConfig, res
}

func NewLogger(conf config.LogTelemetryConfig, res *resource.Resource, loggerProvider log.LoggerProvider, metadata Metadata) *slog.Logger {
return slog.New(
slogmulti.Pipe(
// Common handlers
contextx.NewLogHandler,
operation.NewLogHandler,
).Handler(slogmulti.Fanout(
// Original logger (with otel context middleware)
slogmulti.Pipe(
otelslog.ResourceMiddleware(res),
otelslog.NewHandler,
).Handler(conf.NewHandler(os.Stdout)),

// Otel logger
NewLevelHandler(
realotelslog.NewHandler(metadata.OpenTelemetryName, realotelslog.WithLoggerProvider(loggerProvider)),
conf.Level,
),
)),
// Stdout logger
stdoutLogger := slogmulti.
Pipe(
otelslog.ResourceMiddleware(res),
otelslog.NewHandler,
).
Handler(conf.NewHandler(os.Stdout))

// OTel logger
// It already has the resource middleware applied by the loggerProvider
otelLogger := NewLevelHandler(
realotelslog.NewHandler(metadata.OpenTelemetryName, realotelslog.WithLoggerProvider(loggerProvider)),
conf.Level,
)

// Fanout logger to stdout and OTel logger
out := slogmulti.Fanout(
stdoutLogger,
otelLogger,
)

// Enrich log records
middlewares := slogmulti.Pipe(
contextx.NewLogHandler,
)

return slog.New(middlewares.Handler(out))
}

func NewMeterProvider(ctx context.Context, conf config.MetricsTelemetryConfig, res *resource.Resource, logger *slog.Logger) (*sdkmetric.MeterProvider, func(), error) {
Expand Down
2 changes: 0 additions & 2 deletions cmd/jobs/service/otel.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (

"github.com/openmeterio/openmeter/app/config"
"github.com/openmeterio/openmeter/pkg/contextx"
"github.com/openmeterio/openmeter/pkg/framework/operation"
)

const (
Expand Down Expand Up @@ -49,7 +48,6 @@ func NewTelemetry(ctx context.Context, conf config.TelemetryConfig, env string,
otelslog.ResourceMiddleware(res),
otelslog.NewHandler,
contextx.NewLogHandler,
operation.NewLogHandler,
).Handler(conf.Log.NewHandler(os.Stdout)))

slog.SetDefault(logger)
Expand Down
1 change: 0 additions & 1 deletion cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ func main() {
app.SetGlobals()

logger := app.Logger
slog.SetDefault(logger)

logger.Info("starting OpenMeter server", "config", map[string]string{
"address": conf.Address,
Expand Down
1 change: 0 additions & 1 deletion cmd/sink-worker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ func main() {
app.SetGlobals()

logger := app.Logger
slog.SetDefault(logger)

logger.Info("starting OpenMeter sink worker", "config", map[string]string{
"telemetry.address": conf.Telemetry.Address,
Expand Down
92 changes: 0 additions & 92 deletions openmeter/server/logger.go

This file was deleted.

12 changes: 11 additions & 1 deletion openmeter/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (
"github.com/openmeterio/openmeter/api"
"github.com/openmeterio/openmeter/openmeter/server/authenticator"
"github.com/openmeterio/openmeter/openmeter/server/router"
"github.com/openmeterio/openmeter/pkg/contextx"
"github.com/openmeterio/openmeter/pkg/models"
"github.com/openmeterio/openmeter/pkg/server"
)

type Server struct {
Expand Down Expand Up @@ -57,7 +59,15 @@ func NewServer(config *Config) (*Server, error) {

r.Use(middleware.RealIP)
r.Use(middleware.RequestID)
r.Use(NewStructuredLogger(slog.Default().Handler(), nil))
r.Use(func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx = contextx.WithAttrs(ctx, server.GetRequestAttributes(r))

h.ServeHTTP(w, r.WithContext(ctx))
})
})
r.Use(server.NewRequestLoggerMiddleware(slog.Default().Handler()))
r.Use(middleware.Recoverer)
if config.RouterConfig.PortalCORSEnabled && config.RouterConfig.PortalTokenStrategy != nil {
// Enable CORS for portal requests
Expand Down
14 changes: 14 additions & 0 deletions pkg/contextx/attr.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,17 @@ func WithAttr(ctx context.Context, key string, value any) context.Context {

return ctx
}

// ctxdata adds amultiple key-value pairs to the context.
func WithAttrs(ctx context.Context, data map[string]string) context.Context {
d := ctxdata.From(ctx)
if d == nil {
ctx, d = ctxdata.New(ctx)
}

for key, value := range data {
_ = d.Set(key, value)
}

return ctx
}
19 changes: 0 additions & 19 deletions pkg/framework/internal/operation/name.go

This file was deleted.

39 changes: 0 additions & 39 deletions pkg/framework/operation/log.go

This file was deleted.

30 changes: 0 additions & 30 deletions pkg/framework/operation/name.go

This file was deleted.

29 changes: 0 additions & 29 deletions pkg/framework/operation/name_test.go

This file was deleted.

7 changes: 0 additions & 7 deletions pkg/framework/operation/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,12 @@ package operation

import (
"context"

"github.com/openmeterio/openmeter/pkg/framework/internal/operation"
)

// Operation is the fundamental building block of RPC-style APIs.
// It represents a single operation that can be performed by a caller.
type Operation[Request any, Response any] func(ctx context.Context, request Request) (Response, error)

// Name returns the name of the operation from the context (if any).
func Name(ctx context.Context) (string, bool) {
return operation.Name(ctx)
}

// AsNoResponseOperation wraps a func (context.Context, request Request) error typed function as an operation
// useful for Delete like methods
func AsNoResponseOperation[Request any](f func(ctx context.Context, request Request) error) Operation[Request, any] {
Expand Down
6 changes: 4 additions & 2 deletions pkg/framework/transport/httptransport/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"errors"
"net/http"

intoperation "github.com/openmeterio/openmeter/pkg/framework/internal/operation"
semconv "go.opentelemetry.io/otel/semconv/v1.27.0"

"github.com/openmeterio/openmeter/pkg/contextx"
"github.com/openmeterio/openmeter/pkg/framework/operation"
"github.com/openmeterio/openmeter/pkg/models"
)
Expand Down Expand Up @@ -77,7 +79,7 @@ func (h handler[Request, Response]) ServeHTTP(w http.ResponseWriter, r *http.Req

// TODO: rewrite this as a generic hook
if h.operationNameFunc != nil {
ctx = intoperation.ContextWithName(ctx, h.operationNameFunc(ctx))
ctx = contextx.WithAttr(ctx, string(semconv.HTTPRouteKey), h.operationNameFunc(ctx))
}

request, err := h.decodeRequest(ctx, r)
Expand Down
Loading

0 comments on commit a8e062e

Please sign in to comment.