github.com/jxskiss/gopkg@v0.17.3/zlog/dynamic_level.go (about) 1 package zlog 2 3 import "go.uber.org/zap/zapcore" 4 5 type dynamicLevelCore struct { 6 zapcore.Core 7 baseLevel zapcore.LevelEnabler 8 dynLevel *Level 9 levelFunc perLoggerLevelFunc 10 } 11 12 func (c *dynamicLevelCore) Enabled(level zapcore.Level) bool { 13 // Dynamic level takes higher priority. 14 if c.dynLevel != nil { 15 return c.dynLevel.Enabled(level) 16 } 17 // If per logger level func is configured, leave the filtering work to c.Check. 18 if c.levelFunc != nil { 19 return true 20 } 21 return c.baseLevel.Enabled(level) 22 } 23 24 func (c *dynamicLevelCore) With(fields []zapcore.Field) zapcore.Core { 25 clone := c.clone() 26 clone.Core = clone.Core.With(fields) 27 return clone 28 } 29 30 func (c *dynamicLevelCore) Check(entry zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry { 31 var entryLevel = fromZapLevel(entry.Level) 32 if len(entry.Message) >= levelPrefixMinLen && entry.Message[0] == '[' { 33 if level, detected := detectLevel(entry.Message); detected { 34 entryLevel = level 35 entry.Level = entryLevel.toZapLevel() 36 } 37 } 38 39 // Dynamic level takes higher priority. 40 if c.dynLevel != nil { 41 if *c.dynLevel > entryLevel { 42 return ce 43 } 44 return c.Core.Check(entry, ce) 45 } 46 47 // Check per logger levels. 48 if c.levelFunc != nil && entry.LoggerName != "" { 49 level, found := c.levelFunc(entry.LoggerName) 50 if found { 51 if level > entryLevel { 52 return ce 53 } 54 return c.Core.Check(entry, ce) 55 } 56 } 57 58 // Check the configured base level. 59 if !c.baseLevel.Enabled(entry.Level) { 60 return ce 61 } 62 return c.Core.Check(entry, ce) 63 } 64 65 func (c *dynamicLevelCore) clone() *dynamicLevelCore { 66 return &dynamicLevelCore{ 67 Core: c.Core, 68 baseLevel: c.baseLevel, 69 dynLevel: c.dynLevel, 70 levelFunc: c.levelFunc, 71 } 72 } 73 74 func (c *dynamicLevelCore) changeLevel(level Level) *dynamicLevelCore { 75 if c.dynLevel != nil && *c.dynLevel == level { 76 return c 77 } 78 79 clone := c.clone() 80 clone.dynLevel = &level 81 return clone 82 } 83 84 func tryChangeLevel(level Level) func(zapcore.Core) zapcore.Core { 85 return func(core zapcore.Core) zapcore.Core { 86 if dyn, ok := core.(*dynamicLevelCore); ok { 87 return dyn.changeLevel(level) 88 } 89 return &dynamicLevelCore{ 90 Core: core, 91 baseLevel: level, 92 dynLevel: &level, 93 } 94 } 95 } 96 97 // for testing 98 func unwrapDynamicLevelCore(core zapcore.Core) zapcore.Core { 99 for { 100 wrapped, ok := core.(*dynamicLevelCore) 101 if !ok { 102 return core 103 } 104 core = wrapped.Core 105 } 106 }