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  }