Files
job-search/internal/log/logging.go
T

97 lines
2.5 KiB
Go

/*
Copyright © 2026 Craig Williams <craig@avsdev.uk>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package log
import (
"log/slog"
"os"
"reflect"
"unsafe"
"github.com/lmittmann/tint"
)
var logLevel slog.LevelVar
// Set up the logger using defaults
func Init() {
logLevel.Set(slog.LevelWarn)
opts := &slog.HandlerOptions{
Level: &logLevel,
}
handler := slog.NewTextHandler(os.Stdout, opts)
logger := slog.New(handler)
slog.SetDefault(logger)
}
// Enable info level logging
func EnableInfo() {
if logLevel.Level() > slog.LevelInfo {
logLevel.Set(slog.LevelInfo)
slog.Info("Info logging enabled")
}
}
// Enable debug level logging
func EnableDebug() {
if logLevel.Level() > slog.LevelDebug {
logLevel.Set(slog.LevelDebug)
slog.Debug("Debug logging enabled")
}
}
func LogToTerminal() {
opts := &tint.Options{
Level: &logLevel,
TimeFormat: "*",
}
handler := tint.NewTextHandler(os.Stdout, opts)
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()))
}