first commit
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
// FanoutHandler 是一个将日志记录扇出到多个 slog.Handler 的组合处理器,
|
||||
// 用于同时输出本地 JSON 日志与 OTel 日志桥接。
|
||||
type FanoutHandler struct {
|
||||
handlers []slog.Handler
|
||||
}
|
||||
|
||||
// NewFanoutHandler 创建扇出处理器(忽略 nil handler)。
|
||||
func NewFanoutHandler(handlers ...slog.Handler) *FanoutHandler {
|
||||
filtered := make([]slog.Handler, 0, len(handlers))
|
||||
for _, h := range handlers {
|
||||
if h != nil {
|
||||
filtered = append(filtered, h)
|
||||
}
|
||||
}
|
||||
return &FanoutHandler{handlers: filtered}
|
||||
}
|
||||
|
||||
// Enabled 任一子处理器启用即返回 true。
|
||||
func (f *FanoutHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
||||
for _, h := range f.handlers {
|
||||
if h.Enabled(ctx, level) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Handle 将记录分发给每个启用的子处理器(各自使用副本,避免相互污染)。
|
||||
func (f *FanoutHandler) Handle(ctx context.Context, r slog.Record) error {
|
||||
var errs []error
|
||||
for _, h := range f.handlers {
|
||||
if h.Enabled(ctx, r.Level) {
|
||||
if err := h.Handle(ctx, r.Clone()); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// WithAttrs 为每个子处理器附加属性。
|
||||
func (f *FanoutHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
next := make([]slog.Handler, len(f.handlers))
|
||||
for i, h := range f.handlers {
|
||||
next[i] = h.WithAttrs(attrs)
|
||||
}
|
||||
return &FanoutHandler{handlers: next}
|
||||
}
|
||||
|
||||
// WithGroup 为每个子处理器开启分组。
|
||||
func (f *FanoutHandler) WithGroup(name string) slog.Handler {
|
||||
if name == "" {
|
||||
return f
|
||||
}
|
||||
next := make([]slog.Handler, len(f.handlers))
|
||||
for i, h := range f.handlers {
|
||||
next[i] = h.WithGroup(name)
|
||||
}
|
||||
return &FanoutHandler{handlers: next}
|
||||
}
|
||||
Reference in New Issue
Block a user