github.com/livekit/protocol@v1.16.1-0.20240517185851-47e4c6bba773/logger/logger_test.go (about) 1 package logger 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "testing" 7 8 "github.com/stretchr/testify/require" 9 "go.uber.org/zap" 10 "go.uber.org/zap/zapcore" 11 12 "github.com/livekit/protocol/logger/zaputil" 13 ) 14 15 func zapLoggerCore(l Logger) zapcore.Core { 16 return l.(ZapLogger).ToZap().Desugar().Core() 17 } 18 19 func TestLoggerComponent(t *testing.T) { 20 t.Run("inheriting parent level", func(t *testing.T) { 21 l, err := NewZapLogger(&Config{ 22 Level: "info", 23 ComponentLevels: map[string]string{ 24 "mycomponent": "warn", 25 }, 26 }) 27 require.NoError(t, err) 28 29 sub := zapLoggerCore(l.WithComponent("sub")) 30 require.True(t, sub.Enabled(zapcore.InfoLevel)) 31 require.False(t, sub.Enabled(zapcore.DebugLevel)) 32 33 compLogger := zapLoggerCore(l.WithComponent("mycomponent").WithComponent("level2")) 34 require.True(t, compLogger.Enabled(zapcore.WarnLevel)) 35 require.False(t, compLogger.Enabled(zapcore.InfoLevel)) 36 }) 37 38 t.Run("obeys component override", func(t *testing.T) { 39 l, err := NewZapLogger(&Config{ 40 Level: "info", 41 ComponentLevels: map[string]string{ 42 "sub": "debug", 43 "sub2": "error", 44 }, 45 }) 46 require.NoError(t, err) 47 48 sub := zapLoggerCore(l.WithComponent("sub")) 49 sub2 := zapLoggerCore(l.WithComponent("sub2")) 50 require.True(t, sub.Enabled(zapcore.DebugLevel)) 51 require.False(t, sub2.Enabled(zapcore.InfoLevel)) 52 }) 53 54 t.Run("updates dynamically", func(t *testing.T) { 55 config := &Config{ 56 Level: "info", 57 ComponentLevels: map[string]string{ 58 "sub": "debug", 59 "sub2": "error", 60 }, 61 } 62 l, err := NewZapLogger(config) 63 require.NoError(t, err) 64 65 sub := zapLoggerCore(l.WithComponent("sub")) 66 sub2 := zapLoggerCore(l.WithComponent("sub2.test")) 67 err = config.Update(&Config{ 68 Level: "debug", 69 ComponentLevels: map[string]string{ 70 "sub": "info", 71 // sub2 removed 72 }, 73 }) 74 require.NoError(t, err) 75 76 require.True(t, zapLoggerCore(l).Enabled(zapcore.DebugLevel)) 77 require.False(t, sub.Enabled(zapcore.DebugLevel)) 78 require.True(t, sub.Enabled(zapcore.InfoLevel)) 79 require.True(t, sub2.Enabled(zapcore.InfoLevel)) 80 }) 81 82 t.Run("log output matches expected values", func(t *testing.T) { 83 ws := &testBufferedWriteSyncer{} 84 l, err := NewZapLogger(&Config{}, WithTap(zaputil.NewWriteEnabler(ws, zapcore.DebugLevel))) 85 require.NoError(t, err) 86 l.Debugw("foo", "bar", "baz") 87 88 var log struct { 89 Level string 90 TS float64 91 Caller string 92 Msg string 93 Bar string 94 } 95 require.NoError(t, json.Unmarshal(ws.Bytes(), &log)) 96 97 require.Equal(t, "debug", log.Level) 98 require.NotEqual(t, 0, log.TS) 99 require.NotEqual(t, "", log.Caller) 100 require.Equal(t, "foo", log.Msg) 101 require.Equal(t, "baz", log.Bar) 102 }) 103 104 t.Run("component enabler for tapped logger returns lowest enabled level", func(t *testing.T) { 105 tapLevel := zap.NewAtomicLevel() 106 l, err := NewZapLogger(&Config{Level: "info"}, WithTap(zaputil.NewWriteEnabler(&testBufferedWriteSyncer{}, tapLevel))) 107 require.NoError(t, err) 108 109 lvl := l.ComponentLeveler().ComponentLevel("foo") 110 111 // check config level 112 require.False(t, lvl.Enabled(zapcore.DebugLevel)) 113 require.True(t, lvl.Enabled(zapcore.InfoLevel)) 114 115 // check tap level 116 tapLevel.SetLevel(zapcore.DebugLevel) 117 require.True(t, lvl.Enabled(zapcore.DebugLevel)) 118 }) 119 } 120 121 type testBufferedWriteSyncer struct { 122 bytes.Buffer 123 } 124 125 func (t *testBufferedWriteSyncer) Sync() error { return nil }