diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-08-18 15:58:37 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-08-20 15:57:39 +0200 |
| commit | 9884eca784e853e48ff82ecd904890d28b2fe0fa (patch) | |
| tree | da7ce36527d68d48d974149cbd3214285b39ce35 | |
| parent | 408a1d0ec8f22623769eba7f7923d6268ba834ca (diff) | |
| download | muhqs-game-9884eca784e853e48ff82ecd904890d28b2fe0fa.tar.gz muhqs-game-9884eca784e853e48ff82ecd904890d28b2fe0fa.zip | |
allow game log to be configured using command line flags
| -rw-r--r-- | go/client/main.go | 15 | ||||
| -rw-r--r-- | go/log/handler.go | 41 | ||||
| -rw-r--r-- | go/log/log.go | 30 |
3 files changed, 81 insertions, 5 deletions
diff --git a/go/client/main.go b/go/client/main.go index b631269e..2d936d55 100644 --- a/go/client/main.go +++ b/go/client/main.go @@ -3,13 +3,15 @@ package main import ( "flag" "io" - "log" + "log/slog" "os" + "strings" "github.com/hajimehoshi/ebiten/v2" "muhq.space/muhqs-game/go/activities" "muhq.space/muhqs-game/go/font" + "muhq.space/muhqs-game/go/log" ) const ( @@ -50,8 +52,19 @@ func main() { flag.StringVar(&startMenu.mapPath, "map", "the-kraken", "the map to load") flag.StringVar(&startMenu.remote, "remote", "", "address of remote game to connect to") + + logLevel := flag.Int("logLevel", int(slog.LevelInfo.Level()), "active log level") + loggedFilesVar := flag.String("loggedFiles", "", "files to log") flag.Parse() + if *logLevel != int(slog.LevelInfo.Level()) || *loggedFilesVar != "" { + loggedFiles := strings.Split(*loggedFilesVar, " ") + log.Configure(loggedFiles, &slog.HandlerOptions{ + AddSource: true, + Level: slog.Level(*logLevel), + }) + } + ebiten.SetWindowSize(app.windowWidth, app.windowHeight) ebiten.SetWindowTitle("Muhq's Game") diff --git a/go/log/handler.go b/go/log/handler.go new file mode 100644 index 00000000..75231098 --- /dev/null +++ b/go/log/handler.go @@ -0,0 +1,41 @@ +package log + +import ( + "context" + "log/slog" + "os" + "runtime" + + "golang.org/x/exp/slices" +) + +type gameLogHandler struct { + h slog.Handler + files []string +} + +func NewGameLogHandler(files []string, opts *slog.HandlerOptions) *gameLogHandler { + return &gameLogHandler{h: slog.NewTextHandler(os.Stdout, opts), files: files} +} + +func (h *gameLogHandler) Enabled(ctx context.Context, level slog.Level) bool { + return h.h.Enabled(ctx, level) +} + +func (h *gameLogHandler) Handle(ctx context.Context, r slog.Record) error { + frames := runtime.CallersFrames([]uintptr{r.PC}) + frame, _ := frames.Next() + if slices.Contains(h.files, frame.File) { + return nil + } + + return h.h.Handle(ctx, r) +} + +func (h *gameLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + return &gameLogHandler{h: h.h.WithAttrs(attrs), files: h.files} +} + +func (h *gameLogHandler) WithGroup(name string) slog.Handler { + return &gameLogHandler{h: h.h.WithGroup(name), files: h.files} +} diff --git a/go/log/log.go b/go/log/log.go index ff090425..dbe3af66 100644 --- a/go/log/log.go +++ b/go/log/log.go @@ -8,18 +8,32 @@ import ( "os" ) -const GameLogLevel = 99 +var GameLogLevel slog.Level = 99 + +var Logger *slog.Logger var handleGameRecord func(any) +// RegisterGameRecordHandler registers a callback for game records. +// The registered callback can be used by the game's UI to present game log entries to the user. +func RegisterGameRecordHandler(handler func(any)) { + handleGameRecord = handler +} + func init() { - // TODO: allow to specify the value and the file - l := slog.New(slog.NewTextHandler( + Logger = slog.New(slog.NewTextHandler( os.Stdout, &slog.HandlerOptions{AddSource: true})) - slog.SetDefault(l) + slog.SetDefault(Logger) +} + +// Configure controls the logging behavior of the default logger. +func Configure(files []string, opts *slog.HandlerOptions) { + Logger = slog.New(NewGameLogHandler(files, opts)) + slog.SetDefault(Logger) } +// Game calls the registered handleGameRecord callback and [Logger.Log] on the default logger. func Game(obj any) { if handleGameRecord != nil { handleGameRecord(obj) @@ -28,34 +42,42 @@ func Game(obj any) { slog.Log(context.Background(), GameLogLevel, msg) } +// Debug calls [Logger.Debug] on the default logger. func Debug(msg string, args ...any) { slog.Debug(msg, args...) } +// Info calls [Logger.Info] on the default logger. func Info(msg string, args ...any) { slog.Info(msg, args...) } +// Warn calls [Logger.Warn] on the default logger. func Warn(msg string, args ...any) { slog.Warn(msg, args...) } +// Error calls [Logger.Error] on the default logger. func Error(msg string, args ...any) { slog.Error(msg, args...) } +// Fatal calls [log.Fatal]. func Fatal(args ...any) { log.Fatal(args...) } +// Fatalf calls [log.Fatalf]. func Fatalf(msg string, args ...any) { log.Fatalf(msg, args...) } +// Panic calls [log.Panic]. func Panic(args ...any) { log.Panic(args...) } +// Panicf calls [log.Panicf]. func Panicf(msg string, args ...any) { log.Panicf(msg, args...) } |
