Logging: structured slog messages throughout, and WithLogger options so callers choose the logger

Log messages are lower-case event names with their details as key/value
attributes ("error" for errors), in place of formatted strings.

Loggable package take a WithLogger option as part of their "New*" call,
defaulting to slog.Default(). Each tags its lines with its `component`.

Some debug loggers print directly rather than using slog when in
terminal logging mode.
This commit is contained in:
bwilliams committed 2026-10-15 16:10:52 +01:00
1 parent 0b5fde9563
commit 043e307663
49 files changed
+598 -248

No files matched your search

+25 -20
View File
@@ -1,10 +1,13 @@
package config
import (
"context"
"fmt"
"log/slog"
"maps"
"slices"
"git.avsdev.uk/Go/job-search/internal/logging"
)
// PrintTerminal prints the configuration to stdout as String formats it.
@@ -23,31 +26,33 @@ func (conf JobSearchConfig) PrintYaml() {
}
// PrintLog logs each configuration key and value, sorted by key, at atLevel:
// debug, warn, error, or info for any other level.
// debug, warn, error, or info for any other level. On a terminal it logs one
// line and prints the values under it as "key = value" lines; elsewhere each
// value is a log entry of its own.
func (conf JobSearchConfig) PrintLog(atLevel slog.Level) {
var logFn func(args ...interface{})
switch atLevel {
case slog.LevelDebug:
logFn = func(args ...interface{}) {
slog.Debug(fmt.Sprint(args...))
}
case slog.LevelError:
logFn = func(args ...interface{}) {
slog.Error(fmt.Sprint(args...))
}
case slog.LevelWarn:
logFn = func(args ...interface{}) {
slog.Warn(fmt.Sprint(args...))
}
case slog.LevelDebug, slog.LevelWarn, slog.LevelError:
default:
logFn = func(args ...interface{}) {
slog.Info(fmt.Sprint(args...))
}
atLevel = slog.LevelInfo
}
ctx := context.Background()
logger := slog.Default()
flat := conf.Flatten()
for _, k := range slices.Sorted(maps.Keys(flat)) {
logFn("\t", k, " = ", flat[k])
keys := slices.Sorted(maps.Keys(flat))
if logging.WritesToTerminal(logger.Handler()) {
if !logger.Enabled(ctx, atLevel) {
return
}
logger.Log(ctx, atLevel, "config values", "count", len(keys))
for _, key := range keys {
logging.PrintToTerminal(fmt.Sprintf("\t%s = %v", key, flat[key]))
}
return
}
for _, key := range keys {
logger.Log(ctx, atLevel, "config value", "key", key, "value", flat[key])
}
}