package logger import ( "context" "io" "log/slog" "os" "strings" "go.opentelemetry.io/otel/trace" ) type otlpHandler struct { slog.Handler } func Init() { levelStr := strings.ToLower(os.Getenv("LOG_LEVEL")) var level slog.Level switch levelStr { case "debug": level = slog.LevelDebug case "warn": level = slog.LevelWarn case "error": level = slog.LevelError default: level = slog.LevelInfo } var writer io.Writer = os.Stdout if level == slog.LevelDebug { file, _ := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) writer = io.MultiWriter(os.Stdout, file) } opts := &slog.HandlerOptions{ Level: level, AddSource: true, ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr { if a.Key == slog.TimeKey { return slog.String(a.Key, a.Value.Time().Format("2006-01-02 15:04:05")) } return a }, } baseHandler := slog.NewJSONHandler(writer, opts) handler := &otlpHandler{baseHandler} logger := slog.New(handler) slog.SetDefault(logger) } func (h *otlpHandler) Handle(ctx context.Context, r slog.Record) error { span := trace.SpanFromContext(ctx) if span.SpanContext().HasTraceID() { r.AddAttrs( slog.String("trace_id", span.SpanContext().TraceID().String()), slog.String("span_id", span.SpanContext().SpanID().String()), ) } return h.Handler.Handle(ctx, r) }