github.com/TBD54566975/ftl@v0.219.0/internal/observability/logger.go (about) 1 package observability 2 3 import ( 4 "fmt" 5 6 "github.com/go-logr/logr" 7 8 "github.com/TBD54566975/ftl/internal/log" 9 ) 10 11 type logSink struct { 12 keyValues map[string]interface{} 13 logger *log.Logger 14 } 15 16 func NewOtelLogger(logger *log.Logger, level log.Level) logr.Logger { 17 sink := &logSink{ 18 logger: logger.Scope("otel").Level(level), 19 } 20 return logr.New(sink) 21 } 22 23 var _ logr.LogSink = &logSink{} 24 25 func (l *logSink) Init(info logr.RuntimeInfo) { 26 } 27 28 func (l logSink) Enabled(level int) bool { 29 return otelLevelToLevel(level) >= l.logger.GetLevel() 30 } 31 32 func (l logSink) Info(level int, msg string, kvs ...interface{}) { 33 // otel uses the following mapping for level to our log.Level 34 // 8 = Debug 35 // 4 = Info 36 // 1 = Warning 37 // 0 = Error 38 var logLevel log.Level 39 switch level { 40 case 4: 41 logLevel = log.Info 42 case 8: 43 logLevel = log.Debug 44 case 1: 45 logLevel = log.Warn 46 case 0: 47 logLevel = log.Error 48 default: 49 logLevel = log.Trace 50 } 51 52 logMsg := msg + " " 53 for k, v := range l.keyValues { 54 logMsg += fmt.Sprintf("%s: %+v ", k, v) 55 } 56 for i := 0; i < len(kvs); i += 2 { 57 logMsg += fmt.Sprintf("%s: %+v ", kvs[i], kvs[i+1]) 58 } 59 60 l.logger.Logf(logLevel, logMsg) 61 } 62 63 func (l logSink) Error(err error, msg string, kvs ...interface{}) { 64 l.logger.Errorf(err, msg, kvs...) 65 } 66 67 func (l logSink) WithName(name string) logr.LogSink { 68 return &logSink{ 69 keyValues: l.keyValues, 70 logger: l.logger.Scope(name), 71 } 72 } 73 74 func (l logSink) WithValues(kvs ...interface{}) logr.LogSink { 75 newMap := make(map[string]interface{}, len(l.keyValues)+len(kvs)/2) 76 for k, v := range l.keyValues { 77 newMap[k] = v 78 } 79 for i := 0; i < len(kvs); i += 2 { 80 newMap[kvs[i].(string)] = kvs[i+1] //nolint:forcetypeassert 81 } 82 return &logSink{ 83 keyValues: newMap, 84 logger: l.logger, 85 } 86 } 87 88 func otelLevelToLevel(level int) log.Level { 89 switch level { 90 case 4: 91 return log.Info 92 case 8: 93 return log.Debug 94 case 1: 95 return log.Warn 96 case 0: 97 return log.Error 98 default: 99 return log.Trace 100 } 101 }