diff --git a/internal/log/logging.go b/internal/log/logging.go index 7acbf39..18d373f 100644 --- a/internal/log/logging.go +++ b/internal/log/logging.go @@ -19,6 +19,8 @@ package log import ( "log/slog" "os" + "reflect" + "unsafe" "github.com/lmittmann/tint" ) @@ -61,3 +63,34 @@ func LogToTerminal() { logger := slog.New(handler) slog.SetDefault(logger) } + +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())) +}