feat(internal/otelTrace): 添加上下文信息并优化日志格式- 在日志中添加 ctx (上下文) 信息,使用 zap.Reflect 进行序列化- 调整 trace_id 和 span_id 的顺序,提高日志可读性

This commit is contained in:
danial
2025-06-20 18:40:21 +08:00
parent 63d940c91a
commit 53af0ae990
3 changed files with 61 additions and 85 deletions

3
go.mod
View File

@@ -24,8 +24,8 @@ require (
github.com/rs/xid v1.6.0
github.com/shopspring/decimal v1.4.0
github.com/stretchr/testify v1.10.0
github.com/uptrace/opentelemetry-go-extra/otelzap v0.3.2
github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b
go.opentelemetry.io/contrib/bridges/otelzap v0.11.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0
go.opentelemetry.io/otel v1.36.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2
@@ -68,6 +68,7 @@ require (
github.com/prometheus/procfs v0.16.1 // indirect
github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect

8
go.sum
View File

@@ -128,6 +128,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 h1:3/aHKUq7qaFMWxyQV0W2ryNgg8x8rVeKVA20KJUkfS0=
github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2/go.mod h1:Zit4b8AQXaXvA68+nzmbyDzqiyFRISyw1JiD5JqUBjw=
github.com/uptrace/opentelemetry-go-extra/otelzap v0.3.2 h1:cj/Z6FKTTYBnstI0Lni9PA+k2foounKIPUmj1LBwNiQ=
github.com/uptrace/opentelemetry-go-extra/otelzap v0.3.2/go.mod h1:LDaXk90gKEC2nC7JH3Lpnhfu+2V7o/TsqomJJmqA39o=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b h1:ieRJ8K7QAPWWltEOv7rzMruuPd7gbeAqTaBFhUECIy0=
@@ -136,8 +140,6 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/bridges/otelzap v0.11.0 h1:u2E32P7j1a/gRgZDWhIXC+Shd4rLg70mnE7QLI/Ssnw=
go.opentelemetry.io/contrib/bridges/otelzap v0.11.0/go.mod h1:pJPCLM8gzX4ASqLlyAXjHBEYxgbOQJ/9bidWxD6PEPQ=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
@@ -152,8 +154,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXX
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ=
go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc=
go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E=
go.opentelemetry.io/otel/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:TU7eU/nib68C+4ZMQ5t4em5Jhf50kRorSCV4w+v65vo=
go.opentelemetry.io/otel/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:4AsFc5k1BDLWm5jt0yagrodTEA9xS9McwcnYm+Jf73A=
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=

View File

@@ -2,6 +2,7 @@ package otelTrace
import (
"context"
"github.com/uptrace/opentelemetry-go-extra/otelzap"
"log/slog"
"net/http"
"os"
@@ -11,7 +12,6 @@ import (
"github.com/beego/beego/v2/server/web"
beecontext "github.com/beego/beego/v2/server/web/context"
"go.opentelemetry.io/contrib/bridges/otelzap"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
@@ -37,35 +37,18 @@ var (
InitCtx = context.Background()
)
type LoggerStruct struct {
logger *zap.Logger
type CustomLogger struct {
*otelzap.Logger
}
// WithContext 为日志记录器添加上下文信息。
// 如果上下文中包含跟踪 id则将其添加到日志中以增强可追踪性。
func (l *LoggerStruct) WithContext(ctx context.Context) *zap.Logger {
// 如果上下文为空,直接返回日志记录器,不进行任何修改。
if ctx == nil {
return l.logger
}
span := trace.SpanFromContext(ctx)
if !span.SpanContext().IsValid() {
if l.logger == nil {
return zap.NewNop()
}
return l.logger
}
return l.logger.With(zap.Reflect("ctx", ctx)).
With(
zap.String("trace_id", span.SpanContext().TraceID().String()),
zap.String("span_id", span.SpanContext().SpanID().String()),
)
func (l *CustomLogger) WithContext(ctx context.Context) otelzap.LoggerWithCtx {
return l.Ctx(ctx)
}
var (
serviceName = "网关服务——" + env.Get("serverName", "")
collectorURL = "otel-collector.kkknametrans.buzz"
Logger *LoggerStruct // 添加全局 logger
Logger CustomLogger // 添加全局 logger
)
func InitTracer() (func(context.Context) error, func(context.Context) error, func(context.Context) error) {
@@ -168,11 +151,12 @@ func InitTracer() (func(context.Context) error, func(context.Context) error, fun
MaxAge: 30, //days
Compress: true, // disabled by default
}
defer lumberjacklogger.Close()
defer func(lumberjacklogger *lumberjack.Logger) {
_ = lumberjacklogger.Close()
}(lumberjacklogger)
// 日志需要保存在本地,并且每日更新
core := zapcore.NewTee(
otelzap.NewCore(serviceName, otelzap.WithLoggerProvider(loggerProvider)),
zapcore.NewCore(
zapcore.NewConsoleEncoder(encoderConfig),
zapcore.NewMultiWriteSyncer(
@@ -182,15 +166,15 @@ func InitTracer() (func(context.Context) error, func(context.Context) error, fun
zap.InfoLevel,
),
)
logger := zap.New(core,
zap.AddCaller(),
zap.AddStacktrace(zap.ErrorLevel),
)
// zap设置标准输出流
// 设置全局 logger
Logger = &LoggerStruct{
logger: logger,
Logger = CustomLogger{
Logger: otelzap.New(zap.New(core,
zap.AddCaller(),
zap.AddStacktrace(zap.ErrorLevel),
), otelzap.WithLoggerProvider(loggerProvider)),
}
// 确保设置 TextMapPropagator
otel.SetTextMapPropagator(
propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}),
@@ -233,7 +217,7 @@ func Middleware(ctx *beecontext.Context, next web.FilterFunc) {
if err := recover(); err != nil {
span.RecordError(err.(error))
span.SetAttributes(attribute.String("error", "true"))
Logger.WithContext(ctx.Request.Context()).Error("全局错误", zap.Any("error", err))
Logger.Ctx(ctx.Request.Context()).Error("全局错误", zap.Any("error", err))
// 结束 span
span.End()
// 重新抛出异常
@@ -273,51 +257,42 @@ func NewSchedulerTrace(opts ...trace.TracerOption) trace.Tracer {
return otel.Tracer("scheduler", opts...)
}
func init() {
// 初始化日志
// 自定义日志格式配置
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
FunctionKey: zapcore.OmitKey,
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalLevelEncoder, // 使用大写字母记录日志级别
EncodeTime: zapcore.TimeEncoderOfLayout(time.DateTime), // ISO8601 时间格式
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder, // 短路径编码器
}
lumberjacklogger := &lumberjack.Logger{
Filename: "./logs/log-rotate-test.log",
MaxSize: 10, //MB
MaxBackups: 20,
MaxAge: 15, //days
Compress: true, // disabled by default
}
defer lumberjacklogger.Close()
// 创建核心
core := zapcore.NewTee(
zapcore.NewCore(
zapcore.NewConsoleEncoder(encoderConfig),
zapcore.NewMultiWriteSyncer(
zapcore.AddSync(os.Stdout),
zapcore.AddSync(lumberjacklogger),
),
zap.InfoLevel,
),
)
logger := zap.New(core,
zap.AddCaller(),
// zap.AddCallerSkip(1),
zap.AddStacktrace(zap.ErrorLevel),
)
// zap设置标准输出流
// 设置全局 logger
Logger = &LoggerStruct{
logger: logger,
}
}
//func init() {
// // 初始化日志
// // 自定义日志格式配置
// encoderConfig := zapcore.EncoderConfig{
// TimeKey: "time",
// LevelKey: "level",
// NameKey: "logger",
// CallerKey: "caller",
// FunctionKey: zapcore.OmitKey,
// MessageKey: "msg",
// StacktraceKey: "stacktrace",
// LineEnding: zapcore.DefaultLineEnding,
// EncodeLevel: zapcore.CapitalLevelEncoder, // 使用大写字母记录日志级别
// EncodeTime: zapcore.TimeEncoderOfLayout(time.DateTime), // ISO8601 时间格式
// EncodeDuration: zapcore.SecondsDurationEncoder,
// EncodeCaller: zapcore.ShortCallerEncoder, // 短路径编码器
// }
//
// lumberjacklogger := &lumberjack.Logger{
// Filename: "./logs/log-rotate-test.log",
// MaxSize: 10, //MB
// MaxBackups: 20,
// MaxAge: 15, //days
// Compress: true, // disabled by default
// }
// defer lumberjacklogger.Close()
// // 创建核心
// core := zapcore.NewTee(
// zapcore.NewCore(
// zapcore.NewConsoleEncoder(encoderConfig),
// zapcore.NewMultiWriteSyncer(
// zapcore.AddSync(os.Stdout),
// zapcore.AddSync(lumberjacklogger),
// ),
// zap.InfoLevel,
// ),
// )
// Logger = otelzap.New(zap.New(core))
//}