Some bug fixes:

- logging: LogToFile shadowed the package-level fileLogger, so
  IsFileLogger was always false and Shutdown never closed the file
- logging: replace IsJSONHandler's unsafe reflection into slog
  internals with a *slog.JSONHandler type check
- cli: fail if the log file can't be opened instead of silently
  logging to the terminal; return the log shutdown error from Finish
- build.sh: -X flags used the wrong module path, so the version, build
  time and commit were never stamped
This commit is contained in:
bwilliams committed 2026-10-09 17:58:48 +01:00
1 parent 399eccf2de
commit dcb714dc19
7 files changed
+24 -45

No files matched your search

+5 -31
View File
@@ -3,8 +3,6 @@ package logging
import (
"log/slog"
"os"
"reflect"
"unsafe"
"github.com/lmittmann/tint"
)
@@ -33,7 +31,8 @@ func LogToFile(logfile string) error {
}
// Open the log file
fileLogger, err := os.OpenFile(logfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
var err error
fileLogger, err = os.OpenFile(logfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
if err != nil {
return err
}
@@ -67,35 +66,10 @@ func LogToTerminal() {
slog.SetDefault(logger)
}
// IsJSONHandler reports whether h writes JSON, as the file logger does.
func IsJSONHandler(h slog.Handler) bool {
val := reflect.ValueOf(h)
// Ensure we are working with a pointer to a struct (*JSONHandler or *TextHandler or derived)
if val.Kind() != reflect.Pointer || val.Elem().Kind() != reflect.Struct {
return false
}
// Both JSONHandler and TextHandler wrap an unexported field named 'commonHandler'
commonHandlerField := val.Elem().FieldByName("commonHandler")
if !commonHandlerField.IsValid() {
return false
}
// Get the underlying *commonHandler struct pointer
// commonHandlerField is unexported, so we must use unsafe to bypass Go's safety checks
ptr := reflect.NewAt(
commonHandlerField.Type().Elem(),
unsafe.Pointer(commonHandlerField.Pointer()),
)
// Find the unexported 'json' boolean field inside commonHandler
jsonField := ptr.Elem().FieldByName("json")
if !jsonField.IsValid() {
return false
}
// Read the boolean value using unsafe
return *(*bool)(unsafe.Pointer(jsonField.UnsafeAddr()))
_, ok := h.(*slog.JSONHandler)
return ok
}
func IsFileLogger() bool {