2025-04-12 10:43:40 +02:00
|
|
|
package logging
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"log/slog"
|
|
|
|
|
"os"
|
2025-06-13 11:00:52 +02:00
|
|
|
|
|
|
|
|
"go.opentelemetry.io/contrib/bridges/otelslog"
|
2025-04-12 10:43:40 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Logger interface {
|
|
|
|
|
Info(msg string, args ...any)
|
|
|
|
|
Warn(msg string, args ...any)
|
|
|
|
|
Error(msg string, args ...any)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var defaultLogger *slog.Logger
|
|
|
|
|
|
|
|
|
|
type contextKey string
|
|
|
|
|
|
|
|
|
|
const loggerKey = contextKey("logger")
|
|
|
|
|
|
2025-06-13 11:00:52 +02:00
|
|
|
func SetupLogger(logLevel, logFormat, serviceName, buildVersion string) *slog.Logger {
|
2025-04-12 10:43:40 +02:00
|
|
|
var leveler slog.LevelVar
|
|
|
|
|
|
|
|
|
|
err := leveler.UnmarshalText([]byte(logLevel))
|
|
|
|
|
|
2025-06-13 11:00:52 +02:00
|
|
|
handlerOpts := &slog.HandlerOptions{
|
2025-04-12 10:43:40 +02:00
|
|
|
AddSource: false,
|
|
|
|
|
Level: leveler.Level(),
|
|
|
|
|
ReplaceAttr: nil,
|
2025-06-13 11:00:52 +02:00
|
|
|
}
|
2025-04-12 10:43:40 +02:00
|
|
|
|
2025-06-13 11:00:52 +02:00
|
|
|
var handler slog.Handler
|
|
|
|
|
switch logFormat {
|
|
|
|
|
case "json":
|
|
|
|
|
handler = slog.NewJSONHandler(os.Stdout, handlerOpts)
|
|
|
|
|
case "text":
|
|
|
|
|
handler = slog.NewTextHandler(os.Stdout, handlerOpts)
|
|
|
|
|
case "otel":
|
|
|
|
|
handler = otelslog.NewHandler(serviceName,
|
|
|
|
|
otelslog.WithVersion(buildVersion))
|
|
|
|
|
}
|
|
|
|
|
defaultLogger = slog.New(handler).With("service", serviceName).With("version", buildVersion)
|
2025-04-12 10:43:40 +02:00
|
|
|
if err != nil {
|
|
|
|
|
defaultLogger.With("err", err).Error("Failed to parse log level")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
slog.SetDefault(defaultLogger)
|
|
|
|
|
return defaultLogger
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ContextWithLogger returns a new Context with the logger attached
|
|
|
|
|
func ContextWithLogger(ctx context.Context, logger *slog.Logger) context.Context {
|
|
|
|
|
return context.WithValue(ctx, loggerKey, logger)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// LoggerFromContext returns a logger from the passed context or the default logger
|
|
|
|
|
func LoggerFromContext(ctx context.Context) *slog.Logger {
|
|
|
|
|
logger := ctx.Value(loggerKey)
|
|
|
|
|
if l, ok := logger.(*slog.Logger); ok {
|
|
|
|
|
return l
|
|
|
|
|
}
|
|
|
|
|
return defaultLogger
|
|
|
|
|
}
|