github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/zlog/dynamic_level_test.go (about) 1 package zlog 2 3 import ( 4 "bytes" 5 "context" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "go.uber.org/zap" 10 "go.uber.org/zap/zapcore" 11 ) 12 13 func TestDynamicLevelCore(t *testing.T) { 14 buf := &bytes.Buffer{} 15 logger, _, err := NewWithOutput(&Config{Development: false, Level: "error"}, zapcore.AddSync(buf)) 16 assert.Nil(t, err) 17 18 // assert we get a dynamicLevelCore 19 _ = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core { 20 _, ok := core.(*dynamicLevelCore) 21 assert.True(t, ok) 22 return core 23 })) 24 25 // the level is "error", these messages won't be logged 26 logger.Debug("debug message 1") 27 logger.Info("info message 1") 28 logger.Warn("warn message 1") 29 30 // this error message will be logged 31 logger.Error("error message 1") 32 33 got1 := buf.String() 34 assert.NotContains(t, got1, "debug message 1") 35 assert.NotContains(t, got1, "info message 1") 36 assert.NotContains(t, got1, "warn message 1") 37 assert.Contains(t, got1, "error message 1") 38 39 // change level to debug 40 logger = logger.WithOptions(zap.WrapCore(changeLevel(DebugLevel))) 41 logger.Debug("debug message 2") 42 logger.Info("info message 2") 43 logger.Warn("warn message 2") 44 logger.Error("error message 2") 45 46 got2 := buf.String() 47 assert.Contains(t, got2, "debug message 2") 48 assert.Contains(t, got2, "info message 2") 49 assert.Contains(t, got2, "warn message 2") 50 assert.Contains(t, got2, "error message 2") 51 } 52 53 func TestDynamicLevelCore_ChangeLevelWithCtx(t *testing.T) { 54 var buf = &bytes.Buffer{} 55 var _replace = func(buf *bytes.Buffer) func() { 56 cfg := &Config{ 57 Level: "warn", 58 GlobalConfig: GlobalConfig{ 59 CtxHandler: CtxHandler{ 60 WithCtx: func(ctx context.Context) (result CtxResult) { 61 if ctx.Value("level") != nil { 62 level := ctx.Value("level").(Level) 63 result.Level = &level 64 } 65 return result 66 }, 67 }, 68 }, 69 } 70 l, p, err := NewWithOutput(cfg, zapcore.AddSync(buf)) 71 if err != nil { 72 panic(err) 73 } 74 return ReplaceGlobals(l, p) 75 } 76 defer _replace(buf)() 77 78 // the level is "warn", this info message won't be logged 79 ctx1 := context.Background() 80 WithCtx(ctx1).Info("info message 1") 81 82 got1 := buf.String() 83 assert.NotContains(t, got1, "info message 1") 84 85 // set level to "info" from ctx, info messages will be logged 86 ctx2 := context.WithValue(context.Background(), "level", InfoLevel) 87 WithCtx(ctx2).Debug("debug message 2") 88 WithCtx(ctx2).Info("info message 2") 89 90 got2 := buf.String() 91 assert.NotContains(t, got2, "debug message 2") 92 assert.Contains(t, got2, "info message 2") 93 } 94 95 var ( 96 benchmarkMessage = "some test debug message is not too long and not too short" 97 benchmarkFields = []zap.Field{ 98 zap.String("key1", "value1"), 99 zap.String("some_key_2", "some_value2"), 100 zap.Int64("some_key_3", 183491839141471), 101 zap.Int64s("some_slice_key_4", []int64{18412, 1312490194301, 318431849, 18912438918941}), 102 } 103 ) 104 105 func BenchmarkZapCore(b *testing.B) { 106 logger := newBenchmarkZapCoreLogger() 107 108 b.ResetTimer() 109 b.ReportAllocs() 110 for i := 0; i < b.N; i++ { 111 logger.Trace(benchmarkMessage, benchmarkFields...) 112 logger.Debug(benchmarkMessage, benchmarkFields...) 113 logger.Info(benchmarkMessage, benchmarkFields...) 114 logger.Warn(benchmarkMessage, benchmarkFields...) 115 } 116 } 117 118 func BenchmarkDynamicLevelCore(b *testing.B) { 119 logger := newBenchmarkDynamicLevelCoreLogger() 120 121 b.ResetTimer() 122 b.ReportAllocs() 123 for i := 0; i < b.N; i++ { 124 logger.Trace(benchmarkMessage, benchmarkFields...) 125 logger.Debug(benchmarkMessage, benchmarkFields...) 126 logger.Info(benchmarkMessage, benchmarkFields...) 127 logger.Warn(benchmarkMessage, benchmarkFields...) 128 } 129 } 130 131 type discardWriter struct{} 132 133 func (w *discardWriter) Write(p []byte) (n int, err error) { 134 return len(p), nil 135 } 136 137 func (w *discardWriter) Sync() error { 138 return nil 139 } 140 141 func newBenchmarkZapCoreLogger() Logger { 142 logger, _, err := NewWithOutput(&Config{Development: false, Level: "info"}, &discardWriter{}) 143 if err != nil { 144 panic(err) 145 } 146 147 // Make sure we unwrap the dynamic level wrapper. 148 logger = logger.WithOptions(zap.WrapCore(unwrapDynamicLevelCore)) 149 _ = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core { 150 if _, ok := core.(*dynamicLevelCore); ok { 151 panic("core is wrapped by dynamicLevelCore") 152 } 153 return core 154 })) 155 return Logger{Logger: logger} 156 } 157 158 func newBenchmarkDynamicLevelCoreLogger() Logger { 159 logger, _, err := NewWithOutput(&Config{Development: false, Level: "info"}, &discardWriter{}) 160 if err != nil { 161 panic(err) 162 } 163 164 // Make sure we get a wrapped dynamic level core. 165 logger = logger.WithOptions(zap.WrapCore(changeLevel(DebugLevel))) 166 _ = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core { 167 if _, ok := core.(*dynamicLevelCore); !ok { 168 panic("core is not wrapped by dynamicLevelCore") 169 } 170 return core 171 })) 172 return Logger{Logger: logger} 173 }