diff --git a/internal/cmd/server.go b/internal/cmd/server.go index 67fb4c771b590495b6baa8dd9da2d8fd9de4822a..460d5280e18930c2008db1199aac18a5b281a83d 100644 --- a/internal/cmd/server.go +++ b/internal/cmd/server.go @@ -13,6 +13,7 @@ import ( "github.com/charmbracelet/crush/internal/config" crushlog "github.com/charmbracelet/crush/internal/log" "github.com/charmbracelet/crush/internal/server" + "github.com/charmbracelet/x/term" "github.com/spf13/cobra" ) @@ -42,7 +43,12 @@ var serverCmd = &cobra.Command{ } logFile := filepath.Join(config.GlobalCacheDir(), "server-"+safeNameRegexp.ReplaceAllString(serverHost, "_"), "crush.log") - crushlog.Setup(logFile, debug) + + if term.IsTerminal(os.Stderr.Fd()) { + crushlog.Setup(logFile, debug, os.Stderr) + } else { + crushlog.Setup(logFile, debug) + } hostURL, err := server.ParseHostURL(serverHost) if err != nil { diff --git a/internal/log/log.go b/internal/log/log.go index 9463c3bd97956da3ab895b8600f79d1c05790844..54a0620f18debcf442ed3dd2f8c1739d6aec3696 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -2,6 +2,7 @@ package log import ( "fmt" + "io" "log/slog" "os" "runtime/debug" @@ -10,6 +11,7 @@ import ( "time" "github.com/charmbracelet/crush/internal/event" + "github.com/charmbracelet/x/term" "gopkg.in/natefinch/lumberjack.v2" ) @@ -18,7 +20,7 @@ var ( initialized atomic.Bool ) -func Setup(logFile string, debug bool) { +func Setup(logFile string, debug bool, ws ...io.Writer) { initOnce.Do(func() { logRotator := &lumberjack.Logger{ Filename: logFile, @@ -33,12 +35,26 @@ func Setup(logFile string, debug bool) { level = slog.LevelDebug } - logger := slog.NewJSONHandler(logRotator, &slog.HandlerOptions{ + opts := &slog.HandlerOptions{ Level: level, AddSource: true, - }) + } + + var handlers []slog.Handler + handlers = append(handlers, slog.NewJSONHandler(logRotator, opts)) + + for _, w := range ws { + if w == nil { + continue + } + if f, ok := w.(term.File); ok && term.IsTerminal(f.Fd()) { + handlers = append(handlers, slog.NewTextHandler(w, opts)) + } else { + handlers = append(handlers, slog.NewJSONHandler(w, opts)) + } + } - slog.SetDefault(slog.New(logger)) + slog.SetDefault(slog.New(slog.NewMultiHandler(handlers...))) initialized.Store(true) }) }