From: Dan Fuhry Date: Mon, 30 Dec 2024 19:14:00 +0000 (-0500) Subject: log: make Logger an interface X-Git-Url: https://go.fuhry.dev/?a=commitdiff_plain;h=bce965274f1a537b1700dd3e1882c934aef6f5ab;p=runtime.git log: make Logger an interface Logger needs to be mockable, and for that we need it to be an interface. --- diff --git a/attestation/internal/attestation/server.go b/attestation/internal/attestation/server.go index d6fccdf..f9a945e 100644 --- a/attestation/internal/attestation/server.go +++ b/attestation/internal/attestation/server.go @@ -20,7 +20,7 @@ import ( "go.fuhry.dev/runtime/utils/log" ) -var logger *log.Logger +var logger log.Logger func init() { logger = log.WithPrefix("AttestationServer") diff --git a/grpc/server.go b/grpc/server.go index 94b74be..b095431 100644 --- a/grpc/server.go +++ b/grpc/server.go @@ -30,7 +30,7 @@ type Server struct { port uint16 verifier mtls.MTLSPeerVerifier acl acl.ACLChecker - log *log.Logger + log log.Logger sessions *lru.Cache[string, *session] connFac ConnectionFactory } diff --git a/machines/client.go b/machines/client.go index 0959092..dc9a1f0 100644 --- a/machines/client.go +++ b/machines/client.go @@ -57,7 +57,7 @@ type machinesClient struct { client *http.Client baseUrl string eventsUrl string - logger *log.Logger + logger log.Logger stats *clientStats } diff --git a/machines/coredns_plugin/registry.go b/machines/coredns_plugin/registry.go index 26a0dfc..e1f28c4 100644 --- a/machines/coredns_plugin/registry.go +++ b/machines/coredns_plugin/registry.go @@ -37,7 +37,7 @@ type Result struct { } type registry struct { - log *log.Logger + log log.Logger ctx context.Context cancel context.CancelFunc client machines.MachinesClient diff --git a/machines/coredns_plugin/registry_store.go b/machines/coredns_plugin/registry_store.go index 9ba83e8..a49d133 100644 --- a/machines/coredns_plugin/registry_store.go +++ b/machines/coredns_plugin/registry_store.go @@ -15,7 +15,7 @@ import ( type registryStore struct { mu sync.Mutex `json:"-"` - log *log.Logger + log log.Logger Sites map[string]*machines.Site `json:"Sites"` Domains map[string]*machines.Domain `json:"Domains"` diff --git a/machines/coredns_plugin/setup.go b/machines/coredns_plugin/setup.go index 54b7775..d65d5e7 100644 --- a/machines/coredns_plugin/setup.go +++ b/machines/coredns_plugin/setup.go @@ -20,7 +20,7 @@ func setup(c *caddy.Controller) error { reg := NewRegistry(context.Background()) m := &Machines{ - log: *log.WithPrefix(fmt.Sprintf("plugin/%s_machines", constants.OrgSlug)), + log: log.WithPrefix(fmt.Sprintf("plugin/%s_machines", constants.OrgSlug)), r: reg, } diff --git a/machines/event_watcher.go b/machines/event_watcher.go index 4efa632..24d9006 100644 --- a/machines/event_watcher.go +++ b/machines/event_watcher.go @@ -24,7 +24,7 @@ type MachinesMqttEvent struct { func (mc *machinesClient) NewEventListener(ctx context.Context) (chan MachinesMqttEvent, error) { mqttLogger := mc.logger.AppendPrefix(".mqtt") - mqtt.DEBUG = mqttLogger.WithLevel(log.DEBUG).V(3) + mqtt.DEBUG = mqttLogger.V(3).WithLevel(log.DEBUG) mqtt.WARN = mqttLogger.WithLevel(log.WARNING) mqtt.ERROR = mqttLogger.WithLevel(log.ERROR) mqtt.CRITICAL = mqttLogger.WithLevel(log.CRITICAL) diff --git a/machines/oauth2.go b/machines/oauth2.go index 4a5c61f..03eca7c 100644 --- a/machines/oauth2.go +++ b/machines/oauth2.go @@ -50,7 +50,7 @@ type oauthClient struct { inner http.RoundTripper store *oauthClientCredentials_Store params *oauthAuthParams - log *log.Logger + log log.Logger } func SetupOAuthClient(client *http.Client, tokenEndpoint string, clientId string, clientSecret string, scope []string) error { diff --git a/metrics/metricbus/internal/server.go b/metrics/metricbus/internal/server.go index ba3f78c..1109899 100644 --- a/metrics/metricbus/internal/server.go +++ b/metrics/metricbus/internal/server.go @@ -64,7 +64,7 @@ type mbService struct { } type mbServicer struct { - log *log.Logger + log log.Logger serviceLock sync.RWMutex services map[uint64]*mbService serviceSet *hashset.HashSet[string] @@ -75,7 +75,7 @@ type mbServicer struct { } type mbServer struct { - log *log.Logger + log log.Logger ctx context.Context servicer *mbServicer httpServer *http.Server @@ -209,7 +209,7 @@ func (s *mbServer) Start(ctx context.Context) error { return nil } -func newMetricBusServicer(log *log.Logger) (*mbServicer, error) { +func newMetricBusServicer(log log.Logger) (*mbServicer, error) { s := &mbServicer{ log: log.AppendPrefix(".servicer"), services: make(map[uint64]*mbService, 0), diff --git a/metrics/metricbus/mbclient/client.go b/metrics/metricbus/mbclient/client.go index fd62fef..a74435f 100644 --- a/metrics/metricbus/mbclient/client.go +++ b/metrics/metricbus/mbclient/client.go @@ -21,7 +21,7 @@ type MetricBusService struct { name string instance string - log *log.Logger + log log.Logger client metricBusLowLevelConnection ctx context.Context diff --git a/metrics/mtls/stats.go b/metrics/mtls/stats.go index af87e3f..8315d96 100644 --- a/metrics/mtls/stats.go +++ b/metrics/mtls/stats.go @@ -17,7 +17,7 @@ import ( ) type mtlsMetrics struct { - log *log.Logger + log log.Logger svc *mbclient.MetricBusService diff --git a/mtls/fsnotify/fsnotify.go b/mtls/fsnotify/fsnotify.go index 367906c..9fd4d14 100644 --- a/mtls/fsnotify/fsnotify.go +++ b/mtls/fsnotify/fsnotify.go @@ -23,7 +23,7 @@ var ( var startWatcherMu sync.Mutex var gWatcher *fsnotify.Watcher -var logger *log.Logger +var logger log.Logger var pendingWrites *hashset.HashSet[string] var watched *hashset.HashSet[string] var watchHandlers map[string][]NotifyFunc diff --git a/mtls/identity.go b/mtls/identity.go index 451cd60..ed70ad0 100644 --- a/mtls/identity.go +++ b/mtls/identity.go @@ -40,7 +40,7 @@ const ( var ( defaultMtlsIdentity string - logger *log.Logger + logger log.Logger ) type Identity interface { diff --git a/mtls/provider_keychain_macos.go b/mtls/provider_keychain_macos.go index 104f642..bf10632 100644 --- a/mtls/provider_keychain_macos.go +++ b/mtls/provider_keychain_macos.go @@ -64,7 +64,7 @@ func (kso *kcSignerOpts) HashFunc() crypto.Hash { return kso.hash } -var kcLogger *log.Logger +var kcLogger log.Logger func init() { kcLogger = log.WithPrefix("mtls.macOSKeychain") diff --git a/mtls/verify_names.go b/mtls/verify_names.go index d1d180b..672c62c 100644 --- a/mtls/verify_names.go +++ b/mtls/verify_names.go @@ -90,7 +90,7 @@ type mtlsPeerVerifier struct { MTLSPeerVerifier allowedPrincipals map[IdentityClass]*hashset.HashSet[string] - log *log.Logger + log log.Logger } func NewPeerNameVerifier() MTLSPeerVerifier { diff --git a/sd/monitor.go b/sd/monitor.go index a50fca8..579d6ab 100644 --- a/sd/monitor.go +++ b/sd/monitor.go @@ -18,7 +18,7 @@ type healthCheckingPublisher struct { publisher *SDPublisher healthcheck HealthCheckService etcdClient *etcd_client.Client - logger *log.Logger + logger log.Logger } type SDHealthReport struct { diff --git a/sd/publish.go b/sd/publish.go index 2c56fc8..02f01d1 100644 --- a/sd/publish.go +++ b/sd/publish.go @@ -38,7 +38,7 @@ type SDPublisher struct { mtx *sync.Mutex wg *sync.WaitGroup - logger *log.Logger + logger log.Logger leases etcd_client.Lease lease *etcd_client.LeaseGrantResponse ctx context.Context diff --git a/sd/watcher.go b/sd/watcher.go index 1e334c7..8eca2e9 100644 --- a/sd/watcher.go +++ b/sd/watcher.go @@ -23,7 +23,7 @@ type SDWatcher struct { Service string EtcdClient *etcd_client.Client - logger *log.Logger + logger log.Logger starter *sync.Once lock *sync.RWMutex wg *sync.WaitGroup diff --git a/thirdparty/registry/main.go b/thirdparty/registry/main.go index 592e6a6..63730b9 100644 --- a/thirdparty/registry/main.go +++ b/thirdparty/registry/main.go @@ -31,7 +31,7 @@ import ( "go.fuhry.dev/runtime/utils/log" ) -var logger *log.Logger +var logger log.Logger var DefaultSSLCertificate = "registry." + constants.WebServicesDomain const ( diff --git a/utils/daemon/daemonize.go b/utils/daemon/daemonize.go index 35fcde0..fab9e58 100644 --- a/utils/daemon/daemonize.go +++ b/utils/daemon/daemonize.go @@ -18,7 +18,7 @@ import ( const logDirDefaultMode os.FileMode = 0700 const logFileDefaultMode os.FileMode = 0600 -var logger *log.Logger +var logger log.Logger var stdoutReopenPath, stderrReopenPath string var detach bool diff --git a/utils/log/log.go b/utils/log/log.go index e125f29..aac0de2 100644 --- a/utils/log/log.go +++ b/utils/log/log.go @@ -11,14 +11,62 @@ import ( var logVerbosity int = 0 var logLevel string = "notice" -type Logger struct { +// interface coreLogger contains only the core functionality needed for logging, without +// level or verbosity methods. +// +// This interface can be implemented by mocks for testing. +type coreLogger interface { + WithLevel(Level) coreLogger + + Print(...any) + Printf(string, ...any) + Println(...any) + Fatal(...any) + Fatalf(string, ...any) + Panic(...any) + Panicf(string, ...any) + Panicln(...any) +} + +// interface Logger describes a logger with verbosity and level filtering, and prefix +// management. +type Logger interface { + coreLogger + + AppendPrefix(string) Logger + WithPrefix(string) Logger + V(int) Logger + + Debug(...any) + Debugf(string, ...any) + Info(...any) + Infof(string, ...any) + Notice(...any) + Noticef(string, ...any) + Warning(...any) + Warningf(string, ...any) + Warn(...any) + Warnf(string, ...any) + Error(...any) + Errorf(string, ...any) + Critical(...any) + Criticalf(string, ...any) + Alert(...any) + Alertf(string, ...any) +} + +type internalLogger struct { *log.Logger level Level prefix string } -var defaultLogger *Logger +type logger struct { + *internalLogger +} + +var defaultLogger Logger var defaultLoggerOnce sync.Once func init() { @@ -26,7 +74,7 @@ func init() { flag.StringVar(&logLevel, "v", INFO.String(), "syslog log level for logs") } -func V(level int) *Logger { +func V(level int) Logger { if logVerbosity >= level { return Default() } @@ -34,21 +82,27 @@ func V(level int) *Logger { return NullLogger() } -func Default() *Logger { +func Default() Logger { defaultLoggerOnce.Do(func() { - defaultLogger = &Logger{ - Logger: log.New(os.Stderr, "", log.LstdFlags), + defaultLogger = &logger{ + internalLogger: &internalLogger{ + Logger: log.New(os.Stderr, "", log.LstdFlags), + }, } }) return defaultLogger } -func WithPrefix(prefix string) *Logger { +func WithPrefix(prefix string) Logger { return Default().WithPrefix(prefix) } -func NullLogger() *Logger { - return &Logger{Logger: log.New(io.Discard, "", 0)} +func NullLogger() Logger { + return &logger{ + internalLogger: &internalLogger{ + Logger: log.New(io.Discard, "", 0), + }, + } } func Print(v ...any) { @@ -83,42 +137,36 @@ func Panicln(v ...any) { Default().Panicln(v...) } -func (l *Logger) V(level int) *Logger { - if logVerbosity >= level { - return l - } - return NullLogger() -} - -func (l *Logger) WithPrefix(prefix string) *Logger { - return &Logger{ - Logger: l.Logger, - prefix: prefix, - level: l.level, - } -} - -func (l Logger) WithLevel(lv Level) *Logger { +func (l *internalLogger) WithLevel(lv Level) coreLogger { if lv < LevelFromString(logLevel) { return NullLogger() } - return &Logger{ + return &internalLogger{ Logger: l.Logger, prefix: l.prefix, level: lv, } } -func (l *Logger) AppendPrefix(prefix string) *Logger { - return &Logger{ - Logger: l.Logger, - prefix: l.prefix + prefix, - level: l.level, +func (l *internalLogger) Print(v ...any) { + args := l.prependPrefixes(v) + l.Logger.Print(args...) +} + +func (l *internalLogger) Printf(fmtstr string, v ...any) { + if l.prefix != "" { + fmtstr = "[" + l.prefix + "] " + fmtstr } + + l.Logger.Printf(l.level.prefix(l.Writer())+fmtstr, v...) } -func (l *Logger) prependPrefixes(v []any) []any { +func (l *internalLogger) Println(v ...any) { + l.Print(v...) +} + +func (l *internalLogger) prependPrefixes(v []any) []any { prefix := "" if l.prefix != "" { prefix = "[" + l.prefix + "] " @@ -131,103 +179,113 @@ func (l *Logger) prependPrefixes(v []any) []any { return args } -func (l *Logger) Print(v ...any) { - args := l.prependPrefixes(v) - l.Logger.Print(args...) +func (l *internalLogger) Fatal(v ...any) { + if len(v) > 0 { + if arg1, ok := v[0].(string); ok { + if l.prefix != "" { + v[0] = FATAL.prefix(l.Writer()) + "[" + l.prefix + "] " + arg1 + } + } + } + + l.Logger.Fatal(v...) } -func (l *Logger) Printf(fmtstr string, v ...any) { +func (l *internalLogger) Fatalf(fmtstr string, v ...any) { if l.prefix != "" { - fmtstr = "[" + l.prefix + "] " + fmtstr + fmtstr = FATAL.prefix(l.Writer()) + "[" + l.prefix + "] " + fmtstr } - l.Logger.Printf(l.level.prefix(l.Writer())+fmtstr, v...) + l.Logger.Fatalf(fmtstr, v...) } -func (l *Logger) Println(v ...any) { - l.Print(v...) +func (l *logger) V(level int) Logger { + if logVerbosity >= level { + return l + } + return NullLogger() +} + +func (l *logger) WithPrefix(prefix string) Logger { + return &logger{ + internalLogger: &internalLogger{ + Logger: l.Logger, + prefix: l.internalLogger.prefix, + level: l.level, + }, + } } -func (l *Logger) Debug(v ...any) { +func (l *logger) AppendPrefix(prefix string) Logger { + return &logger{ + internalLogger: &internalLogger{ + Logger: l.Logger, + prefix: l.internalLogger.prefix + prefix, + level: l.level, + }, + } +} + +func (l *logger) Debug(v ...any) { l.WithLevel(DEBUG).Print(v...) } -func (l *Logger) Debugf(fmtstr string, v ...any) { +func (l *logger) Debugf(fmtstr string, v ...any) { l.WithLevel(DEBUG).Printf(fmtstr, v...) } -func (l *Logger) Info(v ...any) { +func (l *logger) Info(v ...any) { l.WithLevel(INFO).Print(v...) } -func (l *Logger) Infof(fmtstr string, v ...any) { +func (l *logger) Infof(fmtstr string, v ...any) { l.WithLevel(INFO).Printf(fmtstr, v...) } -func (l *Logger) Notice(v ...any) { +func (l *logger) Notice(v ...any) { l.WithLevel(NOTICE).Print(v...) } -func (l *Logger) Noticef(fmtstr string, v ...any) { +func (l *logger) Noticef(fmtstr string, v ...any) { l.WithLevel(NOTICE).Printf(fmtstr, v...) } -func (l *Logger) Warning(v ...any) { +func (l *logger) Warning(v ...any) { l.WithLevel(WARNING).Print(v...) } -func (l *Logger) Warningf(fmtstr string, v ...any) { +func (l *logger) Warningf(fmtstr string, v ...any) { l.WithLevel(WARNING).Printf(fmtstr, v...) } -func (l *Logger) Warn(v ...any) { +func (l *logger) Warn(v ...any) { l.WithLevel(WARNING).Print(v...) } -func (l *Logger) Warnf(fmtstr string, v ...any) { +func (l *logger) Warnf(fmtstr string, v ...any) { l.WithLevel(WARNING).Printf(fmtstr, v...) } -func (l *Logger) Error(v ...any) { +func (l *logger) Error(v ...any) { l.WithLevel(ERROR).Print(v...) } -func (l *Logger) Errorf(fmtstr string, v ...any) { +func (l *logger) Errorf(fmtstr string, v ...any) { l.WithLevel(ERROR).Printf(fmtstr, v...) } -func (l *Logger) Critical(v ...any) { +func (l *logger) Critical(v ...any) { l.WithLevel(CRITICAL).Print(v...) } -func (l *Logger) Criticalf(fmtstr string, v ...any) { +func (l *logger) Criticalf(fmtstr string, v ...any) { l.WithLevel(CRITICAL).Printf(fmtstr, v...) } -func (l *Logger) Alert(v ...any) { +func (l *logger) Alert(v ...any) { l.WithLevel(ALERT).Print(v...) } -func (l *Logger) Alertf(fmtstr string, v ...any) { +func (l *logger) Alertf(fmtstr string, v ...any) { l.WithLevel(ALERT).Printf(fmtstr, v...) } - -func (l *Logger) Fatal(v ...any) { - if len(v) > 0 { - if arg1, ok := v[0].(string); ok { - if l.prefix != "" { - v[0] = FATAL.prefix(l.Writer()) + "[" + l.prefix + "] " + arg1 - } - } - } - - l.Logger.Fatal(v...) -} - -func (l *Logger) Fatalf(fmtstr string, v ...any) { - if l.prefix != "" { - fmtstr = FATAL.prefix(l.Writer()) + "[" + l.prefix + "] " + fmtstr - } - - l.Logger.Fatalf(fmtstr, v...) -}