68 lines
1.4 KiB
Go
68 lines
1.4 KiB
Go
package log
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"io"
|
||
|
|
"log/slog"
|
||
|
|
"path/filepath"
|
||
|
|
"runtime"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
sdktrace "go.opentelemetry.io/otel/trace"
|
||
|
|
)
|
||
|
|
|
||
|
|
var projectRoot = getCompileTimeModuleRoot()
|
||
|
|
|
||
|
|
func getCompileTimeModuleRoot() string {
|
||
|
|
// 获取当前函数的调用信息
|
||
|
|
_, file, _, ok := runtime.Caller(0)
|
||
|
|
if !ok {
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
// file 就是编译时的绝对路径
|
||
|
|
return filepath.Dir(filepath.Dir(file))
|
||
|
|
}
|
||
|
|
|
||
|
|
func isProjectFile(file string) bool {
|
||
|
|
// 检查文件是否在编译时的模块根目录下
|
||
|
|
if projectRoot != "" {
|
||
|
|
if rel, err := filepath.Rel(projectRoot, file); err == nil {
|
||
|
|
if !strings.HasPrefix(rel, "..") {
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 其他回退逻辑...
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewContextHandler(w io.Writer, encoding string, opts *slog.HandlerOptions) slog.Handler {
|
||
|
|
if strings.EqualFold(encoding, "json") {
|
||
|
|
return &ContextHandler{
|
||
|
|
Handler: slog.NewJSONHandler(w, opts),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return &ContextHandler{
|
||
|
|
Handler: slog.NewTextHandler(w, opts),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
type ContextHandler struct {
|
||
|
|
slog.Handler
|
||
|
|
encoding string
|
||
|
|
}
|
||
|
|
|
||
|
|
func (h *ContextHandler) Handle(ctx context.Context, r slog.Record) error {
|
||
|
|
var attrs []slog.Attr
|
||
|
|
spanCtx := sdktrace.SpanContextFromContext(ctx)
|
||
|
|
if spanCtx.HasTraceID() {
|
||
|
|
attrs = append(attrs, slog.String("trace", spanCtx.TraceID().String()))
|
||
|
|
}
|
||
|
|
if spanCtx.HasSpanID() {
|
||
|
|
attrs = append(attrs, slog.String("span", spanCtx.SpanID().String()))
|
||
|
|
}
|
||
|
|
r.AddAttrs(attrs...)
|
||
|
|
return h.Handler.Handle(ctx, r)
|
||
|
|
}
|