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:
1 parent
0b5fde9563
commit
043e307663
49 files changed
+598
-248
No files matched your search
@@ -18,9 +18,11 @@ func saveGlobals(t *testing.T) {
|
||||
t.Helper()
|
||||
level := logLevel.Level()
|
||||
def := slog.Default()
|
||||
out, detect := terminal, isTerminal
|
||||
t.Cleanup(func() {
|
||||
logLevel.Set(level)
|
||||
slog.SetDefault(def)
|
||||
terminal, isTerminal = out, detect
|
||||
Shutdown()
|
||||
})
|
||||
}
|
||||
@@ -155,3 +157,52 @@ func TestLogToTerminal(t *testing.T) {
|
||||
t.Fatal("terminal handler ignores the package level")
|
||||
}
|
||||
}
|
||||
|
||||
// On an interactive terminal the handler, and loggers derived from it, report
|
||||
// that they write to the terminal; when stdout is a file or pipe they don't.
|
||||
func TestWritesToTerminal(t *testing.T) {
|
||||
for _, interactive := range []bool{true, false} {
|
||||
saveGlobals(t)
|
||||
isTerminal = func(*os.File) bool {
|
||||
return interactive
|
||||
}
|
||||
|
||||
LogToTerminal()
|
||||
|
||||
derived := slog.Default().With("component", "test").WithGroup("g")
|
||||
for name, h := range map[string]slog.Handler{
|
||||
"default": slog.Default().Handler(),
|
||||
"derived": derived.Handler(),
|
||||
} {
|
||||
if got := WritesToTerminal(h); got != interactive {
|
||||
t.Errorf(
|
||||
"interactive %v, %s: WritesToTerminal = %v",
|
||||
interactive, name, got,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if WritesToTerminal(slog.DiscardHandler) {
|
||||
t.Error("another handler reported as the terminal")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintToTerminal(t *testing.T) {
|
||||
saveGlobals(t)
|
||||
out, err := os.Create(filepath.Join(t.TempDir(), "terminal"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer out.Close()
|
||||
terminal = out
|
||||
|
||||
PrintToTerminal("line one\nline two")
|
||||
|
||||
got, err := os.ReadFile(out.Name())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(got) != "line one\nline two\n" {
|
||||
t.Errorf("printed %q; want the text as it is, then a newline", got)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user