// Copyright 2024 schukai GmbH // SPDX-License-Identifier: AGPL-3.0 package jobqueue import ( "go.uber.org/zap" "log" "os" "sync" ) // Logger interface, that your library's users have to implement type Logger interface { Info(msg string, keysAndValues ...interface{}) Warn(msg string, keysAndValues ...interface{}) Error(msg string, keysAndValues ...interface{}) Trace(msg string, keysAndValues ...interface{}) } type DefaultLogger struct { *log.Logger } func (l *DefaultLogger) Info(msg string, keysAndValues ...interface{}) { l.Print("INFO: "+msg, keysAndValues) } func (l *DefaultLogger) Error(msg string, keysAndValues ...interface{}) { l.Print("ERROR: "+msg, keysAndValues) } func (l *DefaultLogger) Warn(msg string, keysAndValues ...interface{}) { l.Print("WARN: "+msg, keysAndValues) } func (l *DefaultLogger) Trace(msg string, keysAndValues ...interface{}) { l.Print("DEBUG: "+msg, keysAndValues) } // Ensure DefaultLogger satisfies the Logger interface. var _ Logger = (*DefaultLogger)(nil) var ( internalLogger Logger mu sync.Mutex ) func init() { internalLogger = &DefaultLogger{ Logger: log.New(os.Stderr, "", log.LstdFlags), } } // SetLogger sets a custom logger func SetLogger(l Logger) { mu.Lock() defer mu.Unlock() internalLogger = l } // Info logs an informational message to the current logger func Info(msg string, keysAndValues ...interface{}) { mu.Lock() defer mu.Unlock() if internalLogger == nil { return } internalLogger.Info(msg, keysAndValues...) } // Error logs an error message to the current logger func Error(msg string, keysAndValues ...interface{}) { mu.Lock() defer mu.Unlock() if internalLogger == nil { return } internalLogger.Error(msg, keysAndValues...) } // Warn logs a warning message to the current logger func Warn(msg string, keysAndValues ...interface{}) { mu.Lock() defer mu.Unlock() if internalLogger == nil { return } internalLogger.Warn(msg, keysAndValues...) } func Trace(msg string, keysAndValues ...interface{}) { mu.Lock() defer mu.Unlock() if internalLogger == nil { return } internalLogger.Trace(msg, keysAndValues...) } type ZapAdapter struct { logger *zap.Logger mu sync.Mutex } func NewZapAdapter(logger *zap.Logger) *ZapAdapter { return &ZapAdapter{ logger: logger, } } func (l *ZapAdapter) Info(msg string, keysAndValues ...interface{}) { if l.logger == nil { return } l.logger.Info(msg, zap.Any("Info", keysAndValues)) } func (l *ZapAdapter) Warn(msg string, keysAndValues ...interface{}) { if l.logger == nil { return } l.logger.Warn(msg, zap.Any("Warn", keysAndValues)) } func (l *ZapAdapter) Error(msg string, keysAndValues ...interface{}) { if l.logger == nil { return } l.logger.Error(msg, zap.Any("Error", keysAndValues)) } func (l *ZapAdapter) Trace(msg string, keysAndValues ...interface{}) { if l.logger == nil { return } l.logger.Debug(msg, zap.Any("Debug", keysAndValues)) } // Ensure ZapAdapter satisfies the Logger interface. var _ Logger = (*ZapAdapter)(nil) // SetZapLogger sets a custom logger func SetZapLogger(logger *zap.Logger) { mu.Lock() defer mu.Unlock() internalLogger = NewZapAdapter(logger) }