@@ -2,6 +2,7 @@ package log
7 "runtime/debug"
8 "runtime/debug"
@@ -10,6 +11,7 @@ import (
12 "github.com/charmbracelet/crush/internal/event"
13 "github.com/charmbracelet/crush/internal/event"
14+ "github.com/charmbracelet/x/term"
13 "gopkg.in/natefinch/lumberjack.v2"
15 "gopkg.in/natefinch/lumberjack.v2"
@@ -18,7 +20,7 @@ var (
18 initialized atomic.Bool
20 initialized atomic.Bool
21−func Setup(logFile string, debug bool) {
23+func Setup(logFile string, debug bool, ws ...io.Writer) {
22 initOnce.Do(func() {
24 initOnce.Do(func() {
23 logRotator := &lumberjack.Logger{
25 logRotator := &lumberjack.Logger{
24 Filename: logFile,
26 Filename: logFile,
@@ -33,12 +35,26 @@ func Setup(logFile string, debug bool) {
33 level = slog.LevelDebug
35 level = slog.LevelDebug
36− logger := slog.NewJSONHandler(logRotator, &slog.HandlerOptions{
38+ opts := &slog.HandlerOptions{
37 Level: level,
39 Level: level,
38 AddSource: true,
40 AddSource: true,
43+ var handlers []slog.Handler
44+ handlers = append(handlers, slog.NewJSONHandler(logRotator, opts))
46+ for _, w := range ws {
50+ if f, ok := w.(term.File); ok && term.IsTerminal(f.Fd()) {
51+ handlers = append(handlers, slog.NewTextHandler(w, opts))
53+ handlers = append(handlers, slog.NewJSONHandler(w, opts))
41− slog.SetDefault(slog.New(logger))
57+ slog.SetDefault(slog.New(slog.NewMultiHandler(handlers...)))
42 initialized.Store(true)
58 initialized.Store(true)