From 76b8a3840effecfdb2e8fe8c3b9f6c78b850ed6a Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 2 Sep 2023 11:35:41 +0800 Subject: [PATCH 1/8] feat: zap log utils --- go.mod | 6 +++++- go.sum | 17 +++++------------ next/logger/logger.go | 17 +++++++++++++++++ next/main.go | 13 +++++++++++++ 4 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 next/logger/logger.go create mode 100644 next/main.go diff --git a/go.mod b/go.mod index 9225b6b..f3fbe71 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,11 @@ require ( github.com/klauspost/compress v1.16.7 github.com/robfig/cron v1.2.0 github.com/sirupsen/logrus v1.9.3 + go.uber.org/zap v1.25.0 gopkg.in/yaml.v3 v3.0.1 ) -require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect +require ( + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/sys v0.6.0 // indirect +) diff --git a/go.sum b/go.sum index 9ec184f..86b2028 100644 --- a/go.sum +++ b/go.sum @@ -1,27 +1,20 @@ -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a h1:v6zMvHuY9yue4+QkG/HQ/W67wvtQmWJ4SDo9aK/GIno= github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/next/logger/logger.go b/next/logger/logger.go new file mode 100644 index 0000000..ffeea04 --- /dev/null +++ b/next/logger/logger.go @@ -0,0 +1,17 @@ +package logger + +import "go.uber.org/zap" + +var Logger *zap.SugaredLogger + +func init() { + log, err := zap.NewDevelopment() + if err != nil { + panic("log utils init failed") + } + + // TODO: more zap logger configure + // TODO: reserve raw logger handle + + Logger = log.Sugar() +} diff --git a/next/main.go b/next/main.go new file mode 100644 index 0000000..a106d2d --- /dev/null +++ b/next/main.go @@ -0,0 +1,13 @@ +package main + +import ( + . "XProxy/next/logger" +) + +func main() { + Logger.Debugf("here is %s level", "debug") + Logger.Infof("here is %s level", "info") + Logger.Warnf("here is %s level", "warn") + Logger.Errorf("here is %s level", "error") + +} From c23ba6310e2935429afd368d6e48f10ccd003a31 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 2 Sep 2023 14:38:17 +0800 Subject: [PATCH 2/8] update: more zap logger configure --- go.mod | 4 +- go.sum | 6 +++ next/logger/logger.go | 107 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 110 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index f3fbe71..cdc74a0 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,8 @@ require ( ) require ( + github.com/gookit/color v1.5.4 // indirect + github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/sys v0.6.0 // indirect + golang.org/x/sys v0.10.0 // indirect ) diff --git a/go.sum b/go.sum index 86b2028..7a8abcf 100644 --- a/go.sum +++ b/go.sum @@ -3,18 +3,24 @@ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/next/logger/logger.go b/next/logger/logger.go index ffeea04..a14634e 100644 --- a/next/logger/logger.go +++ b/next/logger/logger.go @@ -1,17 +1,112 @@ package logger -import "go.uber.org/zap" +import ( + "fmt" + "go.uber.org/zap" + "os" + "time" +) +import "go.uber.org/zap/zapcore" var Logger *zap.SugaredLogger +const ( + logTmFmt = "2006-01-02 15:04:05" +) + func init() { - log, err := zap.NewDevelopment() - if err != nil { - panic("log utils init failed") - } + + //coreConfig := zapcore.EncoderConfig{ + // TimeKey: "ts", + // LevelKey: "level", + // NameKey: "logger", + // CallerKey: "caller", + // FunctionKey: zapcore.OmitKey, + // MessageKey: "msg", + // StacktraceKey: "stacktrace", + // LineEnding: zapcore.DefaultLineEnding, // 默认换行符"\n" + // EncodeLevel: zapcore.CapitalColorLevelEncoder, + // EncodeTime: zapcore.RFC3339TimeEncoder, // 日志时间格式显示 + // EncodeDuration: zapcore.MillisDurationEncoder, // 时间序列化,Duration为经过的浮点秒数 + // EncodeCaller: zapcore.ShortCallerEncoder, // 日志行号显示 + //} + // + //encoder := zapcore.NewConsoleEncoder(coreConfig) + // + //newCore := zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel) + // + //logger := zap.New(newCore) + // + //Logger = logger.Sugar() + + GetLogger() + + //log, err := zap.NewDevelopment() + //if err != nil { + // panic("log utils init failed") + //} // TODO: more zap logger configure // TODO: reserve raw logger handle - Logger = log.Sugar() + //Logger = log.Sugar() +} + +func GetLogger() { + config := zapcore.EncoderConfig{ + MessageKey: "M", + LevelKey: "L", + TimeKey: "T", + NameKey: "N", + CallerKey: "C", + FunctionKey: "F", + StacktraceKey: "S", + SkipLineEnding: false, + LineEnding: "!!!\n", + + EncodeLevel: logEncodeLevel, + EncodeTime: logEncodeTime, + EncodeDuration: zapcore.StringDurationEncoder, + EncodeCaller: logEncodeCaller, + + EncodeName: logEncodeName, + ConsoleSeparator: "$$", + } + + //var zc = zap.Config{ + // Level: zap.NewAtomicLevelAt(zapcore.DebugLevel), + // Development: false, + // DisableCaller: false, + // DisableStacktrace: false, + // Sampling: nil, + // Encoding: "json", + // EncoderConfig: config, + // OutputPaths: []string{"stdout"}, + // ErrorOutputPaths: []string{"stderr"}, + // InitialFields: map[string]interface{}{"app": "zapdex"}, + //} + + newCore := zapcore.NewCore(zapcore.NewConsoleEncoder(config), zapcore.Lock(os.Stderr), zapcore.DebugLevel) + //newCore := zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.Lock(os.Stderr), zapcore.DebugLevel) + logger := zap.New(newCore, zap.AddCaller()) + //logger, _ := zc.Build() + zap.ReplaceGlobals(logger) + Logger = logger.Sugar() +} + +func logEncodeLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString("[" + level.CapitalString() + "]") +} + +func logEncodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString("[[" + t.Format(logTmFmt) + "]]") +} + +func logEncodeCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString("{" + caller.TrimmedPath() + "}") +} + +func logEncodeName(loggerName string, enc zapcore.PrimitiveArrayEncoder) { + fmt.Println(loggerName) + enc.AppendString("{{" + loggerName + "}}") } From ac17a453debb6efe2b44eab0425a5a7a13f2ff4a Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 2 Sep 2023 15:20:22 +0800 Subject: [PATCH 3/8] feat: custom log format --- next/logger/logger.go | 46 ++++++++++++++++++++++++++++++++----------- next/main.go | 2 +- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/next/logger/logger.go b/next/logger/logger.go index a14634e..e7360c3 100644 --- a/next/logger/logger.go +++ b/next/logger/logger.go @@ -62,15 +62,17 @@ func GetLogger() { FunctionKey: "F", StacktraceKey: "S", SkipLineEnding: false, - LineEnding: "!!!\n", + LineEnding: "\n", - EncodeLevel: logEncodeLevel, + EncodeLevel: logEncodeLevel, + //EncodeLevel: zapcore.CapitalColorLevelEncoder, EncodeTime: logEncodeTime, EncodeDuration: zapcore.StringDurationEncoder, - EncodeCaller: logEncodeCaller, + //EncodeCaller: logEncodeCaller, + EncodeCaller: zapcore.ShortCallerEncoder, - EncodeName: logEncodeName, - ConsoleSeparator: "$$", + //EncodeName: logEncodeName, + ConsoleSeparator: " ", } //var zc = zap.Config{ @@ -89,24 +91,44 @@ func GetLogger() { newCore := zapcore.NewCore(zapcore.NewConsoleEncoder(config), zapcore.Lock(os.Stderr), zapcore.DebugLevel) //newCore := zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.Lock(os.Stderr), zapcore.DebugLevel) logger := zap.New(newCore, zap.AddCaller()) + //logger := zap.New(newCore) //logger, _ := zc.Build() + //logger.Named("123") + //fmt.Println(logger.Name()) + zap.ReplaceGlobals(logger) Logger = logger.Sugar() } func logEncodeLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString("[" + level.CapitalString() + "]") + enc.AppendString(func(level zapcore.Level) string { + levelStr := level.CapitalString() + // TODO: using shell codes map + switch level { + case zapcore.DebugLevel: + return fmt.Sprintf("\x1b[39m[%s]\x1b[0m", levelStr) + case zapcore.InfoLevel: + return fmt.Sprintf("\x1b[32m[%s]\x1b[0m", levelStr) + case zapcore.WarnLevel: + return fmt.Sprintf("\x1b[33m[%s]\x1b[0m", levelStr) + case zapcore.ErrorLevel: + return fmt.Sprintf("\x1b[31m[%s]\x1b[0m", levelStr) + case zapcore.PanicLevel: + return fmt.Sprintf("\x1b[95m[%s]\x1b[0m", levelStr) + default: + return fmt.Sprintf("[%s]", levelStr) + } + }(level)) } func logEncodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString("[[" + t.Format(logTmFmt) + "]]") + // TODO: using `2006-01-02 15:04:05.xxx` format + enc.AppendString(fmt.Sprintf( + "\x1b[36m%s\x1b[0m \x1b[90m%s\x1b[0m", + "[XProxy]", t.Format("2006-01-02 15:04:05"), + )) } func logEncodeCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString("{" + caller.TrimmedPath() + "}") } - -func logEncodeName(loggerName string, enc zapcore.PrimitiveArrayEncoder) { - fmt.Println(loggerName) - enc.AppendString("{{" + loggerName + "}}") -} diff --git a/next/main.go b/next/main.go index a106d2d..d87fbe8 100644 --- a/next/main.go +++ b/next/main.go @@ -9,5 +9,5 @@ func main() { Logger.Infof("here is %s level", "info") Logger.Warnf("here is %s level", "warn") Logger.Errorf("here is %s level", "error") - + //Logger.Panicf("here is %s level", "panic") } From 4664428b6eee502dbdb241cc02f451f6eb524fde Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Wed, 6 Sep 2023 23:53:01 +0800 Subject: [PATCH 4/8] update: enhance log module --- go.mod | 3 + go.sum | 8 ++ next/logger/encoder.go | 46 ++++++++++++ next/logger/interface.go | 39 ++++++++++ next/logger/logger.go | 157 +++++++++++---------------------------- next/main.go | 16 ++-- 6 files changed, 146 insertions(+), 123 deletions(-) create mode 100644 next/logger/encoder.go create mode 100644 next/logger/interface.go diff --git a/go.mod b/go.mod index cdc74a0..3643107 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,10 @@ require ( ) require ( + github.com/fatih/color v1.15.0 // indirect github.com/gookit/color v1.5.4 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/sys v0.10.0 // indirect diff --git a/go.sum b/go.sum index 7a8abcf..5bee901 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,17 @@ github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -18,6 +25,7 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/next/logger/encoder.go b/next/logger/encoder.go new file mode 100644 index 0000000..546358c --- /dev/null +++ b/next/logger/encoder.go @@ -0,0 +1,46 @@ +package logger + +import ( + "github.com/fatih/color" + "go.uber.org/zap/zapcore" + "time" +) + +func encodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(t.Format("2006-01-02 15:04:05.000")) +} + +func encodeColoredTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(color.WhiteString(t.Format("2006-01-02 15:04:05.000"))) +} + +func encodeCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString("[" + caller.TrimmedPath() + "]") +} + +func encodeColoredCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(color.MagentaString("[" + caller.TrimmedPath() + "]")) +} + +func encodeLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString("[" + level.CapitalString() + "]") +} + +func encodeColoredLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(func(level zapcore.Level) func(string, ...interface{}) string { + switch level { + case zapcore.DebugLevel: + return color.CyanString + case zapcore.InfoLevel: + return color.GreenString + case zapcore.WarnLevel: + return color.YellowString + case zapcore.ErrorLevel: + return color.RedString + case zapcore.PanicLevel: + return color.HiRedString + default: + return color.WhiteString + } + }(level)("[" + level.CapitalString() + "]")) +} diff --git a/next/logger/interface.go b/next/logger/interface.go new file mode 100644 index 0000000..cc86407 --- /dev/null +++ b/next/logger/interface.go @@ -0,0 +1,39 @@ +package logger + +import "go.uber.org/zap/zapcore" + +const ( + DebugLevel = zapcore.DebugLevel + InfoLevel = zapcore.InfoLevel + WarnLevel = zapcore.WarnLevel + ErrorLevel = zapcore.ErrorLevel + PanicLevel = zapcore.PanicLevel +) + +func GetLevel() zapcore.Level { + return handle.level.Level() +} + +func SetLevel(level zapcore.Level) { + handle.level.SetLevel(level) +} + +func Debugf(template string, args ...interface{}) { + handle.sugar.Debugf(template, args...) +} + +func Infof(template string, args ...interface{}) { + handle.sugar.Infof(template, args...) +} + +func Warnf(template string, args ...interface{}) { + handle.sugar.Warnf(template, args...) +} + +func Errorf(template string, args ...interface{}) { + handle.sugar.Errorf(template, args...) +} + +func Panicf(template string, args ...interface{}) { + handle.sugar.Panicf(template, args...) +} diff --git a/next/logger/logger.go b/next/logger/logger.go index e7360c3..320149d 100644 --- a/next/logger/logger.go +++ b/next/logger/logger.go @@ -1,134 +1,61 @@ package logger import ( - "fmt" "go.uber.org/zap" - "os" - "time" + "go.uber.org/zap/zapcore" ) -import "go.uber.org/zap/zapcore" -var Logger *zap.SugaredLogger - -const ( - logTmFmt = "2006-01-02 15:04:05" -) - -func init() { - - //coreConfig := zapcore.EncoderConfig{ - // TimeKey: "ts", - // LevelKey: "level", - // NameKey: "logger", - // CallerKey: "caller", - // FunctionKey: zapcore.OmitKey, - // MessageKey: "msg", - // StacktraceKey: "stacktrace", - // LineEnding: zapcore.DefaultLineEnding, // 默认换行符"\n" - // EncodeLevel: zapcore.CapitalColorLevelEncoder, - // EncodeTime: zapcore.RFC3339TimeEncoder, // 日志时间格式显示 - // EncodeDuration: zapcore.MillisDurationEncoder, // 时间序列化,Duration为经过的浮点秒数 - // EncodeCaller: zapcore.ShortCallerEncoder, // 日志行号显示 - //} - // - //encoder := zapcore.NewConsoleEncoder(coreConfig) - // - //newCore := zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel) - // - //logger := zap.New(newCore) - // - //Logger = logger.Sugar() - - GetLogger() - - //log, err := zap.NewDevelopment() - //if err != nil { - // panic("log utils init failed") - //} +type Logger struct { + logger *zap.Logger + level *zap.AtomicLevel + sugar *zap.SugaredLogger +} - // TODO: more zap logger configure - // TODO: reserve raw logger handle +var handle Logger - //Logger = log.Sugar() +func logConfig(level zap.AtomicLevel, colored bool) zapcore.EncoderConfig { + config := zapcore.EncoderConfig{ + ConsoleSeparator: " ", + MessageKey: "msg", + LevelKey: "level", + TimeKey: "time", + CallerKey: "caller", + EncodeTime: encodeTime, + EncodeLevel: encodeLevel, + EncodeCaller: encodeCaller, + } + if colored { + config.EncodeTime = encodeColoredTime + config.EncodeLevel = encodeColoredLevel + config.EncodeCaller = encodeColoredCaller + } + return config } -func GetLogger() { - config := zapcore.EncoderConfig{ - MessageKey: "M", - LevelKey: "L", - TimeKey: "T", - NameKey: "N", - CallerKey: "C", - FunctionKey: "F", - StacktraceKey: "S", - SkipLineEnding: false, - LineEnding: "\n", +func init() { - EncodeLevel: logEncodeLevel, - //EncodeLevel: zapcore.CapitalColorLevelEncoder, - EncodeTime: logEncodeTime, - EncodeDuration: zapcore.StringDurationEncoder, - //EncodeCaller: logEncodeCaller, - EncodeCaller: zapcore.ShortCallerEncoder, + level := zap.NewAtomicLevelAt(DebugLevel) - //EncodeName: logEncodeName, - ConsoleSeparator: " ", - } + writer, _, _ := zap.Open("/dev/stderr", "/root/XProxy/next/lalala.log") - //var zc = zap.Config{ - // Level: zap.NewAtomicLevelAt(zapcore.DebugLevel), - // Development: false, - // DisableCaller: false, - // DisableStacktrace: false, - // Sampling: nil, - // Encoding: "json", - // EncoderConfig: config, - // OutputPaths: []string{"stdout"}, - // ErrorOutputPaths: []string{"stderr"}, - // InitialFields: map[string]interface{}{"app": "zapdex"}, - //} + core := zapcore.NewCore( + zapcore.NewConsoleEncoder(logConfig(level, false)), + //zapcore.Lock(os.Stderr), + writer, + level, + ) - newCore := zapcore.NewCore(zapcore.NewConsoleEncoder(config), zapcore.Lock(os.Stderr), zapcore.DebugLevel) - //newCore := zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.Lock(os.Stderr), zapcore.DebugLevel) - logger := zap.New(newCore, zap.AddCaller()) - //logger := zap.New(newCore) - //logger, _ := zc.Build() - //logger.Named("123") - //fmt.Println(logger.Name()) + //zapcore.AddSync() + //zap.Open() - zap.ReplaceGlobals(logger) - Logger = logger.Sugar() -} + //return core -func logEncodeLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString(func(level zapcore.Level) string { - levelStr := level.CapitalString() - // TODO: using shell codes map - switch level { - case zapcore.DebugLevel: - return fmt.Sprintf("\x1b[39m[%s]\x1b[0m", levelStr) - case zapcore.InfoLevel: - return fmt.Sprintf("\x1b[32m[%s]\x1b[0m", levelStr) - case zapcore.WarnLevel: - return fmt.Sprintf("\x1b[33m[%s]\x1b[0m", levelStr) - case zapcore.ErrorLevel: - return fmt.Sprintf("\x1b[31m[%s]\x1b[0m", levelStr) - case zapcore.PanicLevel: - return fmt.Sprintf("\x1b[95m[%s]\x1b[0m", levelStr) - default: - return fmt.Sprintf("[%s]", levelStr) - } - }(level)) -} + logger := zap.New(core, zap.AddCaller()) -func logEncodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { - // TODO: using `2006-01-02 15:04:05.xxx` format - enc.AppendString(fmt.Sprintf( - "\x1b[36m%s\x1b[0m \x1b[90m%s\x1b[0m", - "[XProxy]", t.Format("2006-01-02 15:04:05"), - )) -} + handle = Logger{ + logger: logger, + level: &level, + sugar: logger.Sugar(), + } -func logEncodeCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString("{" + caller.TrimmedPath() + "}") } diff --git a/next/main.go b/next/main.go index d87fbe8..6fd8c1c 100644 --- a/next/main.go +++ b/next/main.go @@ -1,13 +1,13 @@ package main -import ( - . "XProxy/next/logger" -) +import "XProxy/next/logger" func main() { - Logger.Debugf("here is %s level", "debug") - Logger.Infof("here is %s level", "info") - Logger.Warnf("here is %s level", "warn") - Logger.Errorf("here is %s level", "error") - //Logger.Panicf("here is %s level", "panic") + + logger.Debugf("here is %s level", "debug") + logger.Infof("here is %s level", "info") + logger.Warnf("here is %s level", "warn") + logger.Errorf("here is %s level", "error") + //logger.Panicf("here is %s level", "panic") + } From 29ad4e4b84994e4454db2b26470e3a95bfb84c27 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Thu, 7 Sep 2023 01:36:40 +0800 Subject: [PATCH 5/8] feat: log module supports multiple outputs --- next/logger/encoder.go | 62 +++++++++++++++++++++++---------------- next/logger/interface.go | 14 ++++++++- next/logger/logger.go | 63 ++++++++++++++++++++++------------------ next/main.go | 30 +++++++++++++++---- 4 files changed, 110 insertions(+), 59 deletions(-) diff --git a/next/logger/encoder.go b/next/logger/encoder.go index 546358c..f7e69e4 100644 --- a/next/logger/encoder.go +++ b/next/logger/encoder.go @@ -1,46 +1,58 @@ package logger import ( - "github.com/fatih/color" + "fmt" + "github.com/gookit/color" "go.uber.org/zap/zapcore" "time" ) -func encodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { +// timeEncoder formats the time as a string. +func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05.000")) } -func encodeColoredTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString(color.WhiteString(t.Format("2006-01-02 15:04:05.000"))) +// timeColoredEncoder formats the time as a colored string +// with `[XProxy]` prefix. +func timeColoredEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(fmt.Sprintf( + "%s %s", + color.Cyan.Render("[XProxy]"), + color.Gray.Render(t.Format("2006-01-02 15:04:05.000")), + )) } -func encodeCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { +// callerEncoder formats caller in square brackets. +func callerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString("[" + caller.TrimmedPath() + "]") } -func encodeColoredCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString(color.MagentaString("[" + caller.TrimmedPath() + "]")) +// callerColoredEncoder formats caller in square brackets +// with magenta color. +func callerColoredEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(color.Magenta.Render("[" + caller.TrimmedPath() + "]")) } -func encodeLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { +// levelEncoder formats log level using square brackets. +func levelEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString("[" + level.CapitalString() + "]") } -func encodeColoredLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString(func(level zapcore.Level) func(string, ...interface{}) string { - switch level { - case zapcore.DebugLevel: - return color.CyanString - case zapcore.InfoLevel: - return color.GreenString - case zapcore.WarnLevel: - return color.YellowString - case zapcore.ErrorLevel: - return color.RedString - case zapcore.PanicLevel: - return color.HiRedString - default: - return color.WhiteString - } - }(level)("[" + level.CapitalString() + "]")) +// levelColoredEncoder formats log level using square brackets +// and uses different colors. +func levelColoredEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { + levelStr := "[" + level.CapitalString() + "]" + switch level { + case zapcore.DebugLevel: + levelStr = color.FgDefault.Render(levelStr) + case zapcore.InfoLevel: + levelStr = color.Green.Render(levelStr) + case zapcore.WarnLevel: + levelStr = color.Yellow.Render(levelStr) + case zapcore.ErrorLevel: + levelStr = color.Red.Render(levelStr) + case zapcore.PanicLevel: + levelStr = color.LightRed.Render(levelStr) + } + enc.AppendString(levelStr) } diff --git a/next/logger/interface.go b/next/logger/interface.go index cc86407..8e34adb 100644 --- a/next/logger/interface.go +++ b/next/logger/interface.go @@ -1,6 +1,9 @@ package logger -import "go.uber.org/zap/zapcore" +import ( + "go.uber.org/zap/zapcore" + "io" +) const ( DebugLevel = zapcore.DebugLevel @@ -37,3 +40,12 @@ func Errorf(template string, args ...interface{}) { func Panicf(template string, args ...interface{}) { handle.sugar.Panicf(template, args...) } + +// AddOutputs adds more plain log outputs. +func AddOutputs(outputs ...io.Writer) { + var writers []zapcore.WriteSyncer + for _, output := range outputs { + writers = append(writers, zapcore.AddSync(output)) + } + addWrites(writers...) +} diff --git a/next/logger/logger.go b/next/logger/logger.go index 320149d..a778b83 100644 --- a/next/logger/logger.go +++ b/next/logger/logger.go @@ -3,59 +3,66 @@ package logger import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" + "os" ) type Logger struct { - logger *zap.Logger - level *zap.AtomicLevel - sugar *zap.SugaredLogger + logger *zap.Logger + level *zap.AtomicLevel + sugar *zap.SugaredLogger + writers []zapcore.WriteSyncer + stdCore zapcore.Core } var handle Logger -func logConfig(level zap.AtomicLevel, colored bool) zapcore.EncoderConfig { +// logConfig generates log config for XProxy. +func logConfig(colored bool) zapcore.EncoderConfig { config := zapcore.EncoderConfig{ ConsoleSeparator: " ", MessageKey: "msg", LevelKey: "level", TimeKey: "time", CallerKey: "caller", - EncodeTime: encodeTime, - EncodeLevel: encodeLevel, - EncodeCaller: encodeCaller, + EncodeTime: timeEncoder, + EncodeLevel: levelEncoder, + EncodeCaller: callerEncoder, } if colored { - config.EncodeTime = encodeColoredTime - config.EncodeLevel = encodeColoredLevel - config.EncodeCaller = encodeColoredCaller + config.EncodeTime = timeColoredEncoder + config.EncodeLevel = levelColoredEncoder + config.EncodeCaller = callerColoredEncoder } return config } func init() { - level := zap.NewAtomicLevelAt(DebugLevel) - - writer, _, _ := zap.Open("/dev/stderr", "/root/XProxy/next/lalala.log") - core := zapcore.NewCore( - zapcore.NewConsoleEncoder(logConfig(level, false)), - //zapcore.Lock(os.Stderr), - writer, - level, + zapcore.NewConsoleEncoder(logConfig(true)), + zapcore.Lock(os.Stderr), level, ) - - //zapcore.AddSync() - //zap.Open() - - //return core - logger := zap.New(core, zap.AddCaller()) - handle = Logger{ - logger: logger, - level: &level, - sugar: logger.Sugar(), + logger: logger, + level: &level, + sugar: logger.Sugar(), + writers: []zapcore.WriteSyncer{}, + stdCore: core, } +} +// addWrites adds more plain log writers. +func addWrites(writers ...zapcore.WriteSyncer) { + handle.writers = append(handle.writers, writers...) + plainCore := zapcore.NewCore( + zapcore.NewConsoleEncoder(logConfig(false)), + zap.CombineWriteSyncers(handle.writers...), + handle.level, + ) + handle.logger = zap.New( + zapcore.NewTee(handle.stdCore, plainCore), + zap.AddCaller(), + ) + handle.sugar = handle.logger.Sugar() } diff --git a/next/main.go b/next/main.go index 6fd8c1c..4640261 100644 --- a/next/main.go +++ b/next/main.go @@ -1,13 +1,33 @@ package main -import "XProxy/next/logger" +import ( + "XProxy/next/logger" + "os" +) func main() { - logger.Debugf("here is %s level", "debug") - logger.Infof("here is %s level", "info") - logger.Warnf("here is %s level", "warn") - logger.Errorf("here is %s level", "error") + //logger.Debugf("here is %s level", "debug") + //logger.Infof("here is %s level", "info") + //logger.Warnf("here is %s level", "warn") + //logger.Errorf("here is %s level", "error") //logger.Panicf("here is %s level", "panic") + fp1, _ := os.Create("demo_1.log") + fp2, _ := os.Create("demo_2.log") + fp3, _ := os.Create("demo_3.log") + + logger.Debugf("output msg 1 at debug") + logger.Infof("output msg 1 at info") + logger.Warnf("output msg 1 at warn") + logger.AddOutputs(fp1, fp2) + logger.SetLevel(logger.InfoLevel) + logger.Debugf("output msg 2 at debug") + logger.Infof("output msg 2 at info") + logger.Warnf("output msg 2 at warn") + logger.SetLevel(logger.WarnLevel) + logger.AddOutputs(fp3) + logger.Debugf("output msg 3 at debug") + logger.Infof("output msg 3 at info") + logger.Warnf("output msg 3 at warn") } From 70b58f5a9cd9f71765c1b452087677e0fdfa5898 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Thu, 7 Sep 2023 02:34:39 +0800 Subject: [PATCH 6/8] fix: log caller with one time skip --- next/logger/logger.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/next/logger/logger.go b/next/logger/logger.go index a778b83..15b5fd3 100644 --- a/next/logger/logger.go +++ b/next/logger/logger.go @@ -42,7 +42,7 @@ func init() { zapcore.NewConsoleEncoder(logConfig(true)), zapcore.Lock(os.Stderr), level, ) - logger := zap.New(core, zap.AddCaller()) + logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1)) handle = Logger{ logger: logger, level: &level, @@ -62,7 +62,7 @@ func addWrites(writers ...zapcore.WriteSyncer) { ) handle.logger = zap.New( zapcore.NewTee(handle.stdCore, plainCore), - zap.AddCaller(), + zap.AddCaller(), zap.AddCallerSkip(1), ) handle.sugar = handle.logger.Sugar() } From d6123a14e96879770f4fb1523c185840f4cf031c Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 9 Sep 2023 22:55:55 +0800 Subject: [PATCH 7/8] feat: show goroutine id in log --- next/logger/encoder.go | 30 ++++++++++++++++++++++++++++-- next/logger/logger.go | 2 ++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/next/logger/encoder.go b/next/logger/encoder.go index f7e69e4..4cacc8a 100644 --- a/next/logger/encoder.go +++ b/next/logger/encoder.go @@ -1,12 +1,26 @@ package logger import ( + "bytes" "fmt" "github.com/gookit/color" "go.uber.org/zap/zapcore" + "runtime" + "strconv" "time" ) +// getGID get goroutine ID only for debugging. +// -> https://blog.sgmansfield.com/2015/12/goroutine-ids/ +func getGID() uint64 { + b := make([]byte, 64) + b = b[:runtime.Stack(b, false)] + b = bytes.TrimPrefix(b, []byte("goroutine ")) + b = b[:bytes.IndexByte(b, ' ')] + n, _ := strconv.ParseUint(string(b), 10, 64) + return n +} + // timeEncoder formats the time as a string. func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05.000")) @@ -24,13 +38,25 @@ func timeColoredEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { // callerEncoder formats caller in square brackets. func callerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString("[" + caller.TrimmedPath() + "]") + if !handle.gid { + enc.AppendString("[" + caller.TrimmedPath() + "]") + } else { + enc.AppendString(fmt.Sprintf("[%s] [%d]", caller.TrimmedPath(), getGID())) + } } // callerColoredEncoder formats caller in square brackets // with magenta color. func callerColoredEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString(color.Magenta.Render("[" + caller.TrimmedPath() + "]")) + if !handle.gid { + enc.AppendString(color.Magenta.Render("[" + caller.TrimmedPath() + "]")) + return + } + enc.AppendString(fmt.Sprintf( + "%s %s", + color.Magenta.Render("["+caller.TrimmedPath()+"]"), + color.Blue.Render(fmt.Sprintf("[%d]", getGID())), + )) } // levelEncoder formats log level using square brackets. diff --git a/next/logger/logger.go b/next/logger/logger.go index 15b5fd3..f57fbff 100644 --- a/next/logger/logger.go +++ b/next/logger/logger.go @@ -7,6 +7,7 @@ import ( ) type Logger struct { + gid bool logger *zap.Logger level *zap.AtomicLevel sugar *zap.SugaredLogger @@ -44,6 +45,7 @@ func init() { ) logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1)) handle = Logger{ + gid: true, logger: logger, level: &level, sugar: logger.Sugar(), From f1618a3c4e418910bd30fa0c5539a49bcfb2484a Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 16 Sep 2023 16:09:33 +0800 Subject: [PATCH 8/8] feat: add verbose option --- next/logger/encoder.go | 47 +++++++++++++++++++++++------------- next/logger/interface.go | 36 +++++++++++++++++----------- next/logger/logger.go | 52 +++++++++++++++++++++++----------------- next/main.go | 5 +++- 4 files changed, 87 insertions(+), 53 deletions(-) diff --git a/next/logger/encoder.go b/next/logger/encoder.go index 4cacc8a..b9eda34 100644 --- a/next/logger/encoder.go +++ b/next/logger/encoder.go @@ -5,14 +5,16 @@ import ( "fmt" "github.com/gookit/color" "go.uber.org/zap/zapcore" + "path/filepath" "runtime" "strconv" + "strings" "time" ) -// getGID get goroutine ID only for debugging. +// getGid get goroutine ID only for debugging. // -> https://blog.sgmansfield.com/2015/12/goroutine-ids/ -func getGID() uint64 { +func getGid() uint64 { b := make([]byte, 64) b = b[:runtime.Stack(b, false)] b = bytes.TrimPrefix(b, []byte("goroutine ")) @@ -21,41 +23,54 @@ func getGID() uint64 { return n } +// getCaller calculate relative source path of caller. +func getCaller(ec zapcore.EntryCaller, verbose bool) string { + file, err := filepath.Rel(logHandle.path, ec.File) + if err != nil { + return "undefined" + } + if verbose { + return file + ":" + strconv.Itoa(ec.Line) + } + file, _ = strings.CutSuffix(file, ".go") // remove `.go` suffix + return file +} + // timeEncoder formats the time as a string. func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05.000")) } // timeColoredEncoder formats the time as a colored string -// with `[XProxy]` prefix. +// with custom prefix. func timeColoredEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(fmt.Sprintf( "%s %s", - color.Cyan.Render("[XProxy]"), + color.Cyan.Render(logHandle.prefix), // colored prefix color.Gray.Render(t.Format("2006-01-02 15:04:05.000")), )) } // callerEncoder formats caller in square brackets. -func callerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { - if !handle.gid { - enc.AppendString("[" + caller.TrimmedPath() + "]") - } else { - enc.AppendString(fmt.Sprintf("[%s] [%d]", caller.TrimmedPath(), getGID())) +func callerEncoder(ec zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { + if !logHandle.verbose { + enc.AppendString("[" + getCaller(ec, false) + "]") + return } + enc.AppendString(fmt.Sprintf("[%d] [%s]", getGid(), getCaller(ec, true))) } -// callerColoredEncoder formats caller in square brackets -// with magenta color. -func callerColoredEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { - if !handle.gid { - enc.AppendString(color.Magenta.Render("[" + caller.TrimmedPath() + "]")) +// callerColoredEncoder formats caller in square brackets with +// magenta color. +func callerColoredEncoder(ec zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { + if !logHandle.verbose { + enc.AppendString(color.Magenta.Render("[" + getCaller(ec, false) + "]")) return } enc.AppendString(fmt.Sprintf( "%s %s", - color.Magenta.Render("["+caller.TrimmedPath()+"]"), - color.Blue.Render(fmt.Sprintf("[%d]", getGID())), + color.Blue.Render(fmt.Sprintf("[%d]", getGid())), + color.Magenta.Render("["+getCaller(ec, true)+"]"), )) } diff --git a/next/logger/interface.go b/next/logger/interface.go index 8e34adb..f58b811 100644 --- a/next/logger/interface.go +++ b/next/logger/interface.go @@ -13,35 +13,43 @@ const ( PanicLevel = zapcore.PanicLevel ) -func GetLevel() zapcore.Level { - return handle.level.Level() -} - -func SetLevel(level zapcore.Level) { - handle.level.SetLevel(level) -} - func Debugf(template string, args ...interface{}) { - handle.sugar.Debugf(template, args...) + logHandle.sugar.Debugf(template, args...) } func Infof(template string, args ...interface{}) { - handle.sugar.Infof(template, args...) + logHandle.sugar.Infof(template, args...) } func Warnf(template string, args ...interface{}) { - handle.sugar.Warnf(template, args...) + logHandle.sugar.Warnf(template, args...) } func Errorf(template string, args ...interface{}) { - handle.sugar.Errorf(template, args...) + logHandle.sugar.Errorf(template, args...) } func Panicf(template string, args ...interface{}) { - handle.sugar.Panicf(template, args...) + logHandle.sugar.Panicf(template, args...) +} + +// GetLevel return the current logger level. +func GetLevel() zapcore.Level { + return logHandle.level.Level() +} + +// SetLevel configure logger output level. Note that debug level +// will output more information and reduce performance. +func SetLevel(level zapcore.Level) { + logHandle.level.SetLevel(level) + if level == DebugLevel { + logHandle.verbose = true + } else { + logHandle.verbose = false + } } -// AddOutputs adds more plain log outputs. +// AddOutputs adds more plain output channel to the logger module. func AddOutputs(outputs ...io.Writer) { var writers []zapcore.WriteSyncer for _, output := range outputs { diff --git a/next/logger/logger.go b/next/logger/logger.go index f57fbff..8e792a5 100644 --- a/next/logger/logger.go +++ b/next/logger/logger.go @@ -4,18 +4,22 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" + "path" + "runtime" ) -type Logger struct { - gid bool +type logger struct { logger *zap.Logger level *zap.AtomicLevel sugar *zap.SugaredLogger writers []zapcore.WriteSyncer - stdCore zapcore.Core + stderr zapcore.Core // fixed stderr output + prefix string // custom output prefix + path string // project absolute path + verbose bool // show goroutine id and caller line } -var handle Logger +var logHandle *logger // singleton logger handle // logConfig generates log config for XProxy. func logConfig(colored bool) zapcore.EncoderConfig { @@ -38,33 +42,37 @@ func logConfig(colored bool) zapcore.EncoderConfig { } func init() { - level := zap.NewAtomicLevelAt(DebugLevel) - core := zapcore.NewCore( - zapcore.NewConsoleEncoder(logConfig(true)), - zapcore.Lock(os.Stderr), level, + zapLevel := zap.NewAtomicLevelAt(InfoLevel) // using info level in default + zapCore := zapcore.NewCore( + zapcore.NewConsoleEncoder(logConfig(true)), // colorful output + zapcore.Lock(os.Stderr), + zapLevel, ) - logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1)) - handle = Logger{ - gid: true, - logger: logger, - level: &level, - sugar: logger.Sugar(), + zapLogger := zap.New(zapCore, zap.AddCaller(), zap.AddCallerSkip(1)) + _, src, _, _ := runtime.Caller(0) // absolute path of current code + logHandle = &logger{ + logger: zapLogger, + level: &zapLevel, + stderr: zapCore, + sugar: zapLogger.Sugar(), writers: []zapcore.WriteSyncer{}, - stdCore: core, + path: path.Join(path.Dir(src), "../"), + prefix: "[XProxy]", + verbose: false, } } // addWrites adds more plain log writers. func addWrites(writers ...zapcore.WriteSyncer) { - handle.writers = append(handle.writers, writers...) + logHandle.writers = append(logHandle.writers, writers...) plainCore := zapcore.NewCore( - zapcore.NewConsoleEncoder(logConfig(false)), - zap.CombineWriteSyncers(handle.writers...), - handle.level, + zapcore.NewConsoleEncoder(logConfig(false)), // without colored + zap.CombineWriteSyncers(logHandle.writers...), + logHandle.level, ) - handle.logger = zap.New( - zapcore.NewTee(handle.stdCore, plainCore), + logHandle.logger = zap.New( + zapcore.NewTee(logHandle.stderr, plainCore), zap.AddCaller(), zap.AddCallerSkip(1), ) - handle.sugar = handle.logger.Sugar() + logHandle.sugar = logHandle.logger.Sugar() } diff --git a/next/main.go b/next/main.go index 4640261..4083a99 100644 --- a/next/main.go +++ b/next/main.go @@ -6,7 +6,6 @@ import ( ) func main() { - //logger.Debugf("here is %s level", "debug") //logger.Infof("here is %s level", "info") //logger.Warnf("here is %s level", "warn") @@ -30,4 +29,8 @@ func main() { logger.Debugf("output msg 3 at debug") logger.Infof("output msg 3 at info") logger.Warnf("output msg 3 at warn") + logger.SetLevel(logger.DebugLevel) + logger.Debugf("output msg 4 at debug") + logger.Infof("output msg 4 at info") + logger.Warnf("output msg 4 at warn") }