Files
servicebase/pkg/log/zap.go
2025-11-19 14:24:13 +08:00

196 lines
5.2 KiB
Go
Raw Permalink 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 log
import (
"context"
"fmt"
"os"
"strings"
"time"
"github.com/natefinch/lumberjack"
"github.com/spf13/viper"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gorm.io/gorm/logger"
)
var Log *zap.Logger
type ZapStarter struct {
}
func (s *ZapStarter) Init() error {
Init()
return nil
}
func Init() {
// 编码器
encoderConfig := zap.NewProductionEncoderConfig() // NewJSONEncoder()输出json格式NewConsoleEncoder()输出普通文本格式
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // 指定时间格式
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder // 按级别显示不同颜色,不需要的话取值 CapitalLevelEncoder 就可以了
encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder // 是否显示完整文件路径
encoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000")
env := viper.GetString("env")
//encoder := zapcore.NewJSONEncoder(encoderConfig)
encoder := zapcore.NewConsoleEncoder(encoderConfig) // todo
if env != "dev" {
fmt.Printf("zap log with %s env\n", env)
encoder = zapcore.NewConsoleEncoder(encoderConfig)
}
normalPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { // info 级别
return lev < zap.ErrorLevel && lev >= zap.InfoLevel
})
errorPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { // info 级别
return lev > zap.InfoLevel
})
normalWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
Filename: viper.GetString("log.normal.file"), // 日志文件存放目录
MaxSize: viper.GetInt("log.normal.size"), // 文件大小限制,单位MB
MaxBackups: viper.GetInt("log.normal.backups"), // 最大保留日志文件数量
MaxAge: viper.GetInt("log.normal.age"), // 日志文件保留天数
Compress: viper.GetBool("log.normal.compress"), // 是否压缩处理
LocalTime: true,
})
errorWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
Filename: viper.GetString("log.error.file"),
MaxSize: viper.GetInt("log.error.size"),
MaxBackups: viper.GetInt("log.error.backups"),
MaxAge: viper.GetInt("log.error.age"),
Compress: viper.GetBool("log.error.compress"),
LocalTime: true,
})
Log = zap.New(zapcore.NewTee(
[]zapcore.Core{
zapcore.NewCore(
encoder,
zapcore.NewMultiWriteSyncer(normalWriteSyncer, zapcore.AddSync(os.Stdout)),
normalPriority,
),
zapcore.NewCore(
encoder,
zapcore.NewMultiWriteSyncer(errorWriteSyncer, zapcore.AddSync(os.Stdout)),
errorPriority,
),
}...,
), zap.AddCaller(), zap.AddCallerSkip(1))
}
func traceID(ctx context.Context, fields ...zap.Field) []zap.Field {
sp := trace.SpanContextFromContext(ctx)
traceID := zap.String("trace_id", sp.TraceID().String())
fields = append(fields, traceID)
return fields
}
func InfoWithCtx(ctx context.Context, msg string, fields ...zap.Field) {
Info(msg, traceID(ctx, fields...)...)
}
func Info(msg string, fields ...zap.Field) {
if strings.Contains(msg, "SHOW STATUS") {
return
}
if strings.Contains(msg, "GET _health") {
return
}
if strings.Contains(msg, "GET url: /health") {
return
}
Log.Info(msg, fields...)
}
func WarnWithCtx(ctx context.Context, msg string, fields ...zap.Field) {
Warn(msg, traceID(ctx, fields...)...)
}
func Warn(msg string, fields ...zap.Field) {
Log.Warn(msg, fields...)
}
func ErrorWithCtx(ctx context.Context, msg string, fields ...zap.Field) {
Log.Error(msg, traceID(ctx, fields...)...)
}
func Error(msg string, fields ...zap.Field) {
Log.Error(msg, fields...)
}
func InfoFWithCtx(ctx context.Context, msg string, args ...any) {
Log.Info(fmt.Sprintf(msg, args...), traceID(ctx)...)
}
func InfoF(msg string, args ...any) {
msg = fmt.Sprintf(msg, args...)
Info(msg)
}
func WarnFWithCtx(ctx context.Context, msg string, args ...any) {
Log.Warn(fmt.Sprintf(msg, args...), traceID(ctx)...)
}
func WarnF(msg string, args ...any) {
Log.Warn(fmt.Sprintf(msg, args...))
}
func ErrorFWithCtx(ctx context.Context, msg string, args ...any) {
Log.Warn(fmt.Sprintf(msg, args...), traceID(ctx)...)
}
func ErrorF(msg string, args ...any) {
Log.Error(fmt.Sprintf(msg, args...))
}
type GLog struct {
}
func (g GLog) LogMode(_ logger.LogLevel) logger.Interface {
return &g
}
func (g GLog) Info(_ context.Context, msg string, args ...any) {
Info(fmt.Sprintf(msg, args...))
}
func (g GLog) Warn(_ context.Context, msg string, args ...any) {
Warn(fmt.Sprintf(msg, args...))
}
func (g GLog) Error(_ context.Context, msg string, args ...any) {
Error(fmt.Sprintf(msg, args...))
}
func (g GLog) Trace(_ context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
sql, ra := fc()
if sql == "SHOW STATUS" {
return
}
Info("gorm callback trace", zap.String("sql", sql), zap.Int64("rows", ra), zap.Error(err))
}
func (g GLog) Printf(msg string, args ...any) {
Info(fmt.Sprintf(msg, args...))
}
// CLog cron logger
type CLog struct {
}
func (c CLog) Info(msg string, keysAndValues ...any) {
InfoF(msg, keysAndValues...)
}
// Error logs an error condition.
func (c CLog) Error(err error, msg string, keysAndValues ...any) {
ErrorF(msg, keysAndValues...)
}
func (c CLog) Printf(msg string, args ...any) {
InfoF(msg, args...)
}