github.com/Aoi-hosizora/ahlib-more@v1.5.1-0.20230404072844-256112befaf6/xlogrus/xlogrus_test.go (about) 1 package xlogrus 2 3 import ( 4 "fmt" 5 "github.com/Aoi-hosizora/ahlib-more/xrotation" 6 "github.com/Aoi-hosizora/ahlib/xtesting" 7 "github.com/sirupsen/logrus" 8 "io" 9 "io/ioutil" 10 "os" 11 "runtime" 12 "strings" 13 "testing" 14 "time" 15 ) 16 17 func TestSimpleFormatter(t *testing.T) { 18 l := logrus.New() 19 l.SetLevel(logrus.TraceLevel) 20 sb := &strings.Builder{} 21 l.SetOutput(io.MultiWriter(os.Stdout, sb)) 22 23 d := time.Date(2021, 12, 29, 18, 16, 13, 0, time.FixedZone("", 8*60*60)) 24 for _, tc := range []struct { 25 giveFmt *SimpleFormatter 26 giveReport bool 27 giveFn func(l *logrus.Entry) 28 want string 29 }{ 30 {NewSimpleFormatter(), false, func(l *logrus.Entry) { l.Trace("test") }, 31 "\x1b[37mTRAC\x1b[0m [2021-12-29T18:16:13+08:00] test\n"}, 32 {NewSimpleFormatter(WithTimestampFormat("")), false, func(l *logrus.Entry) { l.Buffer = nil; l.Debug("test") }, 33 "\x1b[37mDEBU\x1b[0m [2021-12-29T18:16:13+08:00] test\n"}, 34 {NewSimpleFormatter(WithTimestampFormat("2006-01-02 15:04:05")), false, func(l *logrus.Entry) { l.Info("test") }, 35 "\x1b[34mINFO\x1b[0m [2021-12-29 18:16:13] test\n"}, 36 {NewSimpleFormatter(WithTimeLocation(time.UTC)), false, func(l *logrus.Entry) { l.Warn("test") }, 37 "\x1b[33mWARN\x1b[0m [2021-12-29T10:16:13Z] test\n"}, 38 {NewSimpleFormatter(WithTimeLocation(time.FixedZone("", -2*60*60))), false, func(l *logrus.Entry) { l.Warn("test") }, 39 "\x1b[33mWARN\x1b[0m [2021-12-29T08:16:13-02:00] test\n"}, 40 {NewSimpleFormatter(WithDisableColor(false)), false, func(l *logrus.Entry) { l.Error("test") }, 41 "\x1b[31mERRO\x1b[0m [2021-12-29T18:16:13+08:00] test\n"}, 42 {NewSimpleFormatter(WithTimestampFormat("2006-01-02"), WithDisableColor(true), WithTimeLocation(time.Local)), false, func(l *logrus.Entry) { l.Panic("test") }, 43 "PANI [2021-12-29] test\n"}, 44 45 {NewSimpleFormatter(), true, func(l *logrus.Entry) { l.Trace("test") }, 46 "\x1b[37mTRAC\x1b[0m [2021-12-29T18:16:13+08:00] \x1b[2mxlogrus_test.go:45 xlogrus.TestSimpleFormatter.func8()\x1b[0m > test\n"}, 47 {NewSimpleFormatter(WithCallerFormatter(func(*runtime.Frame) (string, string) { return "", "" })), true, func(l *logrus.Entry) { l.Debug("test") }, 48 "\x1b[37mDEBU\x1b[0m [2021-12-29T18:16:13+08:00] test\n"}, 49 {NewSimpleFormatter(WithCallerFormatter(func(*runtime.Frame) (string, string) { return "", "fn()" }), WithDisableColor(true)), true, func(l *logrus.Entry) { l.Info("test") }, 50 "INFO [2021-12-29T18:16:13+08:00] fn() > test\n"}, 51 {NewSimpleFormatter(WithCallerFormatter(func(*runtime.Frame) (string, string) { return "aaa.go:123", "fff()" })), true, func(l *logrus.Entry) { l.Warn("test") }, 52 "\x1b[33mWARN\x1b[0m [2021-12-29T18:16:13+08:00] \x1b[2maaa.go:123 fff()\x1b[0m > test\n"}, 53 54 {NewSimpleFormatter(WithLevelFormatter(func(l logrus.Level) string { return l.String() })), false, func(l *logrus.Entry) { l.Trace("test") }, 55 "\x1b[37mtrace\x1b[0m [2021-12-29T18:16:13+08:00] test\n"}, 56 {NewSimpleFormatter(WithLevelFormatter(func(l logrus.Level) string { return "" })), false, func(l *logrus.Entry) { l.Debug("test") }, 57 "\x1b[37m\x1b[0m [2021-12-29T18:16:13+08:00] test\n"}, 58 {NewSimpleFormatter(WithLevelFormatter(func(l logrus.Level) string { return l.String()[:1] })), false, func(l *logrus.Entry) { l.Info("test") }, 59 "\x1b[34mi\x1b[0m [2021-12-29T18:16:13+08:00] test\n"}, 60 {NewSimpleFormatter(WithLevelFormatter(func(l logrus.Level) string { return strings.ToUpper(l.String())[:1] }), WithDisableColor(true)), false, func(l *logrus.Entry) { l.Error("test") }, 61 "E [2021-12-29T18:16:13+08:00] test\n"}, 62 63 {NewSimpleFormatter(WithMessageFormatter(func(l, t, c, m string) string { return fmt.Sprintf("%s %s: %s\n", t, l, m) }), WithTimestampFormat("2006-01-02 15:04:05")), false, func(l *logrus.Entry) { l.Trace("test") }, 64 "2021-12-29 18:16:13 \x1b[37mTRAC\x1b[0m: test\n"}, 65 {NewSimpleFormatter(WithMessageFormatter(func(l, t, c, m string) string { return "" })), false, func(l *logrus.Entry) { l.Debug("test") }, 66 ""}, 67 {NewSimpleFormatter(WithMessageFormatter(func(l, t, c, m string) string { return fmt.Sprintf("[%s] [%s] %s\n", t, l, m) }), WithDisableColor(true)), false, func(l *logrus.Entry) { l.Info("test") }, 68 "[2021-12-29T18:16:13+08:00] [INFO] test\n"}, 69 {NewSimpleFormatter(WithMessageFormatter(func(l, t, c, m string) string { return fmt.Sprintf("%s[%s] %s\n", l, t, m) }), WithLevelFormatter(func(l logrus.Level) string { return strings.ToUpper(l.String())[:1] })), false, func(l *logrus.Entry) { l.Warn("test") }, 70 "\x1b[33mW\x1b[0m[2021-12-29T18:16:13+08:00] test\n"}, 71 } { 72 l.SetFormatter(tc.giveFmt) 73 l.SetReportCaller(tc.giveReport) 74 sb.Reset() 75 76 entry := l.WithTime(d).WithField("key", "value") 77 func() { 78 defer func() { recover() }() 79 tc.giveFn(entry) 80 }() 81 xtesting.Equal(t, sb.String(), tc.want) 82 } 83 } 84 85 func TestLogrusFormatters(t *testing.T) { 86 l := logrus.New() 87 l.SetLevel(logrus.TraceLevel) 88 sb := &strings.Builder{} 89 l.SetOutput(io.MultiWriter(os.Stdout, sb)) 90 91 d := time.Date(2022, 1, 20, 14, 56, 20, 123456789, time.Local) 92 for _, tc := range []struct { 93 giveFmt logrus.Formatter 94 giveFunc func(*logrus.Entry, ...interface{}) 95 giveFields logrus.Fields 96 giveMsg string 97 giveReport bool 98 want string 99 }{ 100 {RFC3339JsonFormatter(), (*logrus.Entry).Debug, logrus.Fields{}, "hello world 1", false, 101 `{"@@time":"2022-01-20T14:56:20.123456789+08:00","@level":"debug","@message":"hello world 1","entries":{}}`}, 102 {RFC3339JsonFormatter(), (*logrus.Entry).Info, logrus.Fields{"key": "v"}, "hello world 2", false, 103 `{"@@time":"2022-01-20T14:56:20.123456789+08:00","@level":"info","@message":"hello world 2","entries":{"key":"v"}}`}, 104 {RFC3339JsonFormatter(), (*logrus.Entry).Warn, logrus.Fields{"empty": ""}, "hello world 3", false, 105 `{"@@time":"2022-01-20T14:56:20.123456789+08:00","@level":"warning","@message":"hello world 3","entries":{"empty":""}}`}, 106 {RFC3339JsonFormatter(), (*logrus.Entry).Error, logrus.Fields{"i": 123, "f": 3.14}, "hello world 4", true, 107 `{"@@time":"2022-01-20T14:56:20.123456789+08:00","@level":"error","@message":"hello world 4","entries":{"f":3.14,"i":123},`}, 108 109 {RFC3339ColoredTextFormatter(), (*logrus.Entry).Debug, logrus.Fields{}, "hello world 1", false, "\x1b[37mDEBU\x1b[0m[2022-01-20T14:56:20+08:00] hello world 1"}, 110 {RFC3339ColoredTextFormatter(), (*logrus.Entry).Info, logrus.Fields{"key": "v"}, "hello world 2", false, "\x1b[36mINFO\x1b[0m[2022-01-20T14:56:20+08:00] hello world 2 \x1b[36mkey\x1b[0m=\"v\""}, 111 {RFC3339ColoredTextFormatter(), (*logrus.Entry).Warn, logrus.Fields{"empty": ""}, "hello world 3", false, "\x1b[33mWARN\x1b[0m[2022-01-20T14:56:20+08:00] hello world 3 \x1b[33mempty\x1b[0m=\"\""}, 112 {RFC3339ColoredTextFormatter(), (*logrus.Entry).Error, logrus.Fields{"i": 123, "f": 3.14}, "hello world 4", false, "\x1b[31mERRO\x1b[0m[2022-01-20T14:56:20+08:00] hello world 4 \x1b[31mf\x1b[0m=\"3.14\" \x1b[31mi\x1b[0m=\"123\""}, 113 } { 114 t.Run(tc.giveMsg, func(t *testing.T) { 115 l.SetFormatter(tc.giveFmt) 116 l.SetReportCaller(tc.giveReport) 117 118 sb.Reset() 119 entry := l.WithTime(d).WithFields(tc.giveFields) 120 tc.giveFunc(entry, tc.giveMsg) 121 l.SetReportCaller(false) 122 xtesting.Equal(t, sb.String()[:len(tc.want)], tc.want) 123 }) 124 } 125 126 t.Run("caller", func(t *testing.T) { 127 entry := l.WithTime(d) 128 entry.Level = logrus.DebugLevel 129 entry.Message = "xxx" 130 entry.Caller = &runtime.Frame{ 131 Function: "github.com/aaa/bbb.ccc.ddd", 132 File: "aaa/bbb/ccc.go", 133 Line: 99, 134 } 135 l.SetReportCaller(true) 136 entry.Logger = l 137 138 // 1. 139 fmt1 := RFC3339JsonFormatter() 140 bs, err := fmt1.Format(entry) 141 _, _ = os.Stdout.Write(bs) 142 xtesting.Nil(t, err) 143 xtesting.Equal(t, string(bs), "{\"@@time\":\"2022-01-20T14:56:20.123456789+08:00\",\"@level\":\"debug\",\"@message\":\"xxx\",\"entries\":{},\"file\":\"aaa/bbb/ccc.go:99\",\"function\":\"github.com/aaa/bbb.ccc.ddd\"}\n") 144 145 // 2. 146 fmt2 := RFC3339ColoredTextFormatter() 147 bs, err = fmt2.Format(entry) 148 _, _ = os.Stdout.Write(bs) 149 xtesting.Nil(t, err) 150 xtesting.Equal(t, string(bs), "\x1b[37mDEBU\x1b[0m[2022-01-20T14:56:20+08:00]ccc.go:99 bbb.ccc.ddd() xxx \n") 151 }) 152 } 153 154 func TestRotationHook(t *testing.T) { 155 l := logrus.New() 156 l.SetLevel(logrus.TraceLevel) 157 l.SetFormatter(&logrus.TextFormatter{FullTimestamp: true, TimestampFormat: time.RFC3339, ForceColors: true}) 158 l.SetOutput(os.Stdout) 159 160 type Os = []RotationHookOption 161 rl, err := xrotation.New("logger.log") 162 xtesting.Nil(t, err) 163 rl2, err := xrotation.New("console.log") 164 xtesting.Nil(t, err) 165 166 for _, tc := range []struct { 167 giveRotation *xrotation.RotationLogger 168 giveOptions Os 169 giveFn func(l *logrus.Entry) 170 wantPanic bool 171 wantLevels []logrus.Level 172 wantFilename string 173 wantContent string 174 }{ 175 {nil, Os{}, nil, true, nil, "", ""}, 176 {nil, Os{WithRotateLevel(logrus.TraceLevel)}, nil, true, nil, "", ""}, 177 {rl, Os{WithRotateLevel(logrus.TraceLevel)}, func(l *logrus.Entry) { l.Trace("test") }, 178 false, logrus.AllLevels, "logger.log", "{\"key\":\"value\",\"level\":\"trace\",\"msg\":\"test\",\"time\":\"2021-12-29T18:16:13+08:00\"}\n"}, 179 {rl2, Os{WithRotateLevel(logrus.DebugLevel), WithRotateFormatter(&logrus.JSONFormatter{})}, func(l *logrus.Entry) { l.Debug("test") }, 180 false, logrus.AllLevels[:logrus.DebugLevel+1], "console.log", "{\"key\":\"value\",\"level\":\"debug\",\"msg\":\"test\",\"time\":\"2021-12-29T18:16:13+08:00\"}\n"}, 181 {rl, Os{WithRotateFormatter(&logrus.TextFormatter{})}, func(l *logrus.Entry) { l.Info("test") }, 182 false, logrus.AllLevels[:logrus.WarnLevel+1], "", ""}, 183 {rl, Os{WithRotateFormatter(&logrus.TextFormatter{DisableColors: true})}, func(l *logrus.Entry) { l.Warn("test") }, 184 false, logrus.AllLevels[:logrus.WarnLevel+1], "logger.log", "time=\"2021-12-29T18:16:13+08:00\" level=warning msg=test key=value\n"}, 185 {rl2, Os{WithRotateLevel(99999), WithRotateFormatter(NewSimpleFormatter(WithDisableColor(true)))}, func(l *logrus.Entry) { l.Panic("test") }, 186 false, []logrus.Level{logrus.PanicLevel}, "console.log", "PANI [2021-12-29T18:16:13+08:00] test\n"}, 187 } { 188 if tc.wantPanic { 189 xtesting.Panic(t, func() { NewRotationHook(tc.giveRotation, tc.giveOptions...) }) 190 continue 191 } 192 hook := NewRotationHook(tc.giveRotation, tc.giveOptions...) 193 l.Hooks = logrus.LevelHooks{} 194 l.AddHook(hook) 195 xtesting.Equal(t, hook.Levels(), tc.wantLevels) 196 if tc.wantFilename != "" { 197 _ = os.Remove(tc.wantFilename) 198 } 199 200 entry := l.WithTime(time.Date(2021, 12, 29, 18, 16, 13, 0, time.Local)).WithField("key", "value") 201 func() { 202 defer func() { recover() }() 203 tc.giveFn(entry) 204 }() 205 _, err := os.Stat(tc.wantFilename) 206 if tc.wantFilename == "" { 207 xtesting.True(t, os.IsNotExist(err)) 208 } else { 209 xtesting.Nil(t, err) 210 bs, err := ioutil.ReadFile(tc.wantFilename) 211 xtesting.Nil(t, err) 212 xtesting.Equal(t, string(bs), tc.wantContent) 213 } 214 215 if o := hook.rotation; o != nil { 216 xtesting.Nil(t, o.Close()) 217 } 218 if tc.wantFilename != "" { 219 xtesting.Nil(t, os.Remove(tc.wantFilename)) 220 } 221 } 222 }