github.com/rudderlabs/rudder-go-kit@v0.30.0/logger/config.go (about) 1 package logger 2 3 import ( 4 "errors" 5 "sync" 6 7 "go.uber.org/zap/zapcore" 8 9 "github.com/rudderlabs/rudder-go-kit/config" 10 ) 11 12 // factoryConfig is the configuration for the logger 13 type factoryConfig struct { 14 rootLevel int // the level for the root logger 15 enableNameInLog bool // whether to include the logger name in the log message 16 enableStackTrace *config.Reloadable[bool] // for fatal logs 17 18 levelConfig *syncMap[string, int] // preconfigured log levels for loggers 19 levelConfigCache *syncMap[string, int] // cache of all calculated log levels for loggers 20 21 // zap specific config 22 clock zapcore.Clock 23 } 24 25 // SetLogLevel sets the log level for the given logger name 26 func (fc *factoryConfig) SetLogLevel(name, levelStr string) error { 27 level, ok := levelMap[levelStr] 28 if !ok { 29 return errors.New("invalid level value : " + levelStr) 30 } 31 if name == "" { 32 fc.rootLevel = level 33 } else { 34 fc.levelConfig.set(name, level) 35 } 36 fc.levelConfigCache = newSyncMap[string, int]() 37 return nil 38 } 39 40 // getOrSetLogLevel returns the log level for the given logger name or sets it using the provided function if no level is set 41 func (fc *factoryConfig) getOrSetLogLevel(name string, parentLevelFunc func() int) int { 42 if name == "" { 43 return fc.rootLevel 44 } 45 46 if level, found := fc.levelConfigCache.get(name); found { 47 return level 48 } 49 level := func() int { // either get the level from the config or use the parent's level 50 if level, ok := fc.levelConfig.get(name); ok { 51 return level 52 } 53 return parentLevelFunc() 54 }() 55 fc.levelConfigCache.set(name, level) // cache the level 56 return level 57 } 58 59 // newSyncMap creates a new syncMap 60 func newSyncMap[K comparable, V any]() *syncMap[K, V] { 61 return &syncMap[K, V]{m: map[K]V{}} 62 } 63 64 // syncMap is a thread safe map for getting and setting keys concurrently 65 type syncMap[K comparable, V any] struct { 66 mu sync.RWMutex 67 m map[K]V 68 } 69 70 func (sm *syncMap[K, V]) get(key K) (V, bool) { 71 sm.mu.RLock() 72 defer sm.mu.RUnlock() 73 v, ok := sm.m[key] 74 return v, ok 75 } 76 77 func (sm *syncMap[K, V]) set(key K, value V) { 78 sm.mu.Lock() 79 defer sm.mu.Unlock() 80 sm.m[key] = value 81 }