Trace back everything (tested)

Signed-off-by: Asai Neko <sugar@sne.moe>
This commit is contained in:
2026-01-21 19:19:17 +08:00
parent 3f44d2d9c2
commit 5f6eb9f2a2
16 changed files with 229 additions and 84 deletions

View File

@@ -7,15 +7,57 @@ import (
"os"
"strings"
"github.com/spf13/viper"
"go.opentelemetry.io/contrib/bridges/otelslog"
"go.opentelemetry.io/otel/trace"
)
type otlpHandler struct {
slog.Handler
type multiHandler struct {
handlers []slog.Handler
}
func (m *multiHandler) Enabled(ctx context.Context, l slog.Level) bool {
for _, h := range m.handlers {
if h.Enabled(ctx, l) {
return true
}
}
return false
}
func (m *multiHandler) 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()),
)
}
for _, h := range m.handlers {
_ = h.Handle(ctx, r)
}
return nil
}
func (m *multiHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
newHandlers := make([]slog.Handler, len(m.handlers))
for i, h := range m.handlers {
newHandlers[i] = h.WithAttrs(attrs)
}
return &multiHandler{handlers: newHandlers}
}
func (m *multiHandler) WithGroup(name string) slog.Handler {
newHandlers := make([]slog.Handler, len(m.handlers))
for i, h := range m.handlers {
newHandlers[i] = h.WithGroup(name)
}
return &multiHandler{handlers: newHandlers}
}
func Init() {
levelStr := strings.ToLower(os.Getenv("LOG_LEVEL"))
levelStr := strings.ToLower(viper.GetString("server.log_level"))
var level slog.Level
switch levelStr {
case "debug":
@@ -34,7 +76,7 @@ func Init() {
writer = io.MultiWriter(os.Stdout, file)
}
opts := &slog.HandlerOptions{
localHandler := slog.NewJSONHandler(writer, &slog.HandlerOptions{
Level: level,
AddSource: true,
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
@@ -43,21 +85,13 @@ func Init() {
}
return a
},
})
otelHandler := otelslog.NewHandler(viper.GetString("server.service_name"))
combinedHandler := &multiHandler{
handlers: []slog.Handler{localHandler, otelHandler},
}
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)
slog.SetDefault(slog.New(combinedHandler))
}