starter/pkg/logx/log.go
2026-03-28 19:29:40 +08:00

112 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package logx
import (
"context"
"fmt"
"sync"
"gitea.micah.wiki/pandora/starter/app/config"
"gitea.micah.wiki/pandora/starter/pkg/env"
"gitea.micah.wiki/pandora/starter/pkg/requestid"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var (
logger *zap.Logger
once sync.Once
)
func Init() {
_ = _getLogger()
}
func _getLogger() *zap.Logger {
if logger == nil {
once.Do(func() {
logFile := config.GetConfig().LogFile
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
// 自定义控制台输出的字段顺序仅对ConsoleEncoder生效
ConsoleSeparator: " ", // 字段之间的分隔符
}
var writer zapcore.WriteSyncer
var encoder zapcore.Encoder
writer = zapcore.AddSync(&lumberjack.Logger{
Filename: logFile,
MaxSize: 10, // megabytes
MaxBackups: 30,
MaxAge: 7, // days
Compress: true,
})
if env.IsLocal() {
encoder = zapcore.NewConsoleEncoder(encoderConfig)
} else {
// 其他系统保持 JSON 编码器
encoder = zapcore.NewJSONEncoder(encoderConfig)
}
core := zapcore.NewCore(
encoder,
writer,
zap.DebugLevel,
)
logger = zap.New(core)
})
}
return logger
}
func Close() {
if logger != nil {
_ = logger.Sync()
}
}
// 统一封装日志方法根据编码器类型处理logid
func logWithCtx(ctx context.Context, level zapcore.Level, template string, args ...interface{}) {
logid := requestid.GetLogID(ctx)
msg := fmt.Sprintf(template, args...)
// 根据编码器类型决定 logid 的展示方式
if env.IsMacOS() {
// macOS控制台模式将logid嵌入到消息中保证文本可读性
msg = fmt.Sprintf("%s %s", logid, msg)
_getLogger().Log(level, msg)
} else {
// 其他系统JSON模式使用zap字段保证JSON结构清晰
_getLogger().With(zap.String("logid", logid)).Log(level, msg)
}
}
// CtxInfo 带上下文的Info级别日志
func CtxInfo(ctx context.Context, template string, args ...interface{}) {
logWithCtx(ctx, zapcore.InfoLevel, template, args...)
}
// CtxError 带上下文的Error级别日志
func CtxError(ctx context.Context, template string, args ...interface{}) {
logWithCtx(ctx, zapcore.ErrorLevel, template, args...)
}
// CtxWarn 带上下文的Warn级别日志
func CtxWarn(ctx context.Context, template string, args ...interface{}) {
logWithCtx(ctx, zapcore.WarnLevel, template, args...)
}
// CtxDebug 带上下文的Debug级别日志
func CtxDebug(ctx context.Context, template string, args ...interface{}) {
logWithCtx(ctx, zapcore.DebugLevel, template, args...)
}