封裝zap log打印日志
封裝 go.uber.org/zap log打印日志:
支持輸出到標準輸出、文件;
輸出到文件支持按時間或者大小切分文件;
支持多個日志輸出級別;
package main import ( "context" "github.com/opentracing/opentracing-go" "github.com/uber/jaeger-client-go" "go.uber.org/zap/zapcore" "go.uber.org/zap" rotatelogs "github.com/lestrrat-go/file-rotatelogs" "io" "os" "time" ) type LogIface interface { // 包含鏈路跟蹤信息的日志方法 InfoWithCtx(ctx context.Context, format string, v ...interface{}) ErrorWithCtx(ctx context.Context, format string, v ...interface{}) // DebugWithCtx、WarnWithCtx、Info... } var sugarLogger *zap.SugaredLogger /** * 日志配置 */ type Config struct { Path string //日志打印路徑 Level string //需要打印日志的最低級別日志級別有debug,info,warn,error,panic,fatal OutputMode int // 0:file 1:stdout 2:file+stdout ArchiveTime int //存檔時間(單位天,默認20天) AddCaller bool //是否打印文件名行號,默認不打印debug會打印 } var ( OutputFile int = 0 //file OutputStdout int = 1 //stdout OutputFileAndStdout int = 2 //file+stdout ) /** * 日志級別 */ var ( DebugLevel = "debug" //日志級別 InfoLevel = "info" WarnLevel = "warn" ErrorLevel = "error" PanicLevel = "panic" FatalLevel = "fatal" ) var levelMap = map[string]zapcore.Level{ DebugLevel: zapcore.DebugLevel, InfoLevel: zapcore.InfoLevel, WarnLevel: zapcore.WarnLevel, ErrorLevel: zapcore.ErrorLevel, PanicLevel: zapcore.PanicLevel, FatalLevel: zapcore.FatalLevel, } func getLoggerLevel(lvl string) zapcore.Level { if level, ok := levelMap[lvl]; ok { return level } return zapcore.InfoLevel } /** * 打印日志方法 */ func InfoWithCtx(ctx context.Context, format string, v ...interface{}) { traceID := TraceID(ctx) if traceID == "" { sugarLogger.Infof(format, v...) return } sugarLogger.With("trace_id", traceID).Infof(format, v...) } func ErrorWithCtx(ctx context.Context, format string, v ...interface{}) { traceID := TraceID(ctx) if traceID == "" { sugarLogger.Errorf(format, v...) return } sugarLogger.With("trace_id", traceID).Errorf(format, v...) } func TraceID(ctx context.Context) string { sp := opentracing.SpanFromContext(ctx) if sp == nil { return "" } sctx, ok := sp.Context().(jaeger.SpanContext) if !ok { return "" } return sctx.TraceID().String() } func getWriter(filename string, archiveTime int) io.Writer { if archiveTime < 5 { //日志存檔時間小于5天時,默認更新為30天 archiveTime = 30 } var withMaxAge = time.Duration(archiveTime) * 24 * time.Hour hook, err := rotatelogs.New( filename+".%Y-%m-%d", //info.log.2021-10-22 //rotatelogs.WithLinkName(filename), //為最新的日志建立軟連接 rotatelogs.WithMaxAge(withMaxAge), //默認保存30天 rotatelogs.WithRotationTime(time.Hour*24), //切割頻率 24小時 ) if err != nil { panic(err) } return hook } /** * conf.Path: 日志目錄 * conf.Level: 日志級別 * serviceName: 服務名 * addCaller: 是否開啟打印文件名以及行號信息 * outputModel: 日志打印方式 0:file 1:stdout 2:file+stdout * archiveTime: 存檔時間(單位天,默認20天) */ func LoadConfig(conf *Config, serviceName string) *zap.Logger { // 1.設置級別 logLevel := getLoggerLevel(conf.Level) infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { return lvl >= logLevel }) // 2.設置文件存儲路徑 logPath := conf.Path if logPath == "" { logPath = "./log/info.log" } infoWriter := getWriter(logPath, conf.ArchiveTime) // 3.設置config config := zapcore.EncoderConfig{ MessageKey: "message", LevelKey: "level", TimeKey: "time", CallerKey: "caller", StacktraceKey: "stack", EncodeLevel: zapcore.CapitalLevelEncoder, EncodeCaller: zapcore.ShortCallerEncoder, EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02T15:04:05-07:00")) }, EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) { enc.AppendInt64(int64(d) / 1000000) }, } encoder := zapcore.NewJSONEncoder(config) // 4.初始化日志操作句柄 var core zapcore.Core if conf.OutputMode == OutputFileAndStdout { core = zapcore.NewTee( zapcore.NewCore(encoder, zapcore.AddSync(infoWriter), infoLevel), zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), logLevel), ) } else if conf.OutputMode == OutputStdout { core = zapcore.NewTee( zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), logLevel), ) } else { core = zapcore.NewTee( zapcore.NewCore(encoder, zapcore.AddSync(infoWriter), infoLevel), ) } var option []zap.Option option = []zap.Option{zap.AddStacktrace(zap.ErrorLevel), zap.Fields(zap.String("service", serviceName))} //error級別會打印棧 if conf.AddCaller { option = append(option, zap.AddCaller(), zap.AddCallerSkip(1)) } return zap.New(core, option...) } //釋放資源 func DeferLog() { _ = sugarLogger.Sync() } func main() { conf := &Config{ Path: "", Level: InfoLevel, OutputMode: 2, ArchiveTime: 30, AddCaller: false, } sugarLogger = LoadConfig(conf, "test-srv").Sugar() InfoWithCtx(context.Background(), "current time: %v", time.Now().Unix()) }

浙公網安備 33010602011771號