Skip to content

Commit 889f3ce

Browse files
committed
simulate(tui): capture SDK logs to a file instead of discarding
1 parent d9cab93 commit 889f3ce

2 files changed

Lines changed: 40 additions & 7 deletions

File tree

cmd/lk/simulate_tui.go

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import (
3131
tea "github.com/charmbracelet/bubbletea"
3232
"github.com/charmbracelet/lipgloss"
3333
"github.com/go-logr/logr"
34+
"go.uber.org/zap"
35+
"go.uber.org/zap/zapcore"
3436

3537
"github.com/livekit/livekit-cli/v2/pkg/util"
3638
"github.com/livekit/protocol/livekit"
@@ -41,12 +43,9 @@ import (
4143

4244
func runSimulateTUI(config *simulateConfig) error {
4345
// SDK/protocol log lines go to stderr behind the alt screen and would all
44-
// spill into the terminal when the TUI exits; the agent log file and the
45-
// run report carry the diagnostics instead.
46-
discard := logger.LogRLogger(logr.Discard())
47-
logger.SetLogger(discard, "lk")
48-
lksdk.SetLogger(discard)
49-
log.SetOutput(io.Discard)
46+
// spill into the terminal when the TUI exits; capture them in a file
47+
// instead, surfaced as a path on exit like the agent log.
48+
cliLogPath := redirectLogsToFile()
5049

5150
launcher := launchSimulationAgent(config)
5251
m := newSimulateModel(config, launcher)
@@ -82,6 +81,10 @@ func runSimulateTUI(config *simulateConfig) error {
8281
}
8382
}
8483

84+
if cliLogPath != "" {
85+
out.Statusf("CLI logs: %s", cliLogPath)
86+
}
87+
8588
// The summary (which carries the chat transcripts) may have landed after
8689
// the TUI's last poll; refresh once so the report includes it.
8790
if m.run != nil && m.run.Summary == nil && m.runID != "" {
@@ -114,6 +117,36 @@ func runSimulateTUI(config *simulateConfig) error {
114117
return nil
115118
}
116119

120+
// redirectLogsToFile points the protocol/SDK/stdlib loggers at a temp file
121+
// and returns its path; on failure the logs are discarded (they would
122+
// otherwise corrupt the TUI and spill on exit).
123+
func redirectLogsToFile() string {
124+
f, err := os.CreateTemp("", "lk-simulate-cli-*.log")
125+
if err != nil {
126+
discard := logger.LogRLogger(logr.Discard())
127+
logger.SetLogger(discard, "lk")
128+
lksdk.SetLogger(discard)
129+
log.SetOutput(io.Discard)
130+
return ""
131+
}
132+
core := zapcore.NewCore(
133+
zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
134+
zapcore.AddSync(f),
135+
zapcore.InfoLevel,
136+
)
137+
zl, err := logger.FromZapLogger(zap.New(core), &logger.Config{Level: "info"})
138+
if err != nil {
139+
discard := logger.LogRLogger(logr.Discard())
140+
logger.SetLogger(discard, "lk")
141+
lksdk.SetLogger(discard)
142+
} else {
143+
logger.SetLogger(zl, "lk")
144+
lksdk.SetLogger(zl)
145+
}
146+
log.SetOutput(f)
147+
return f.Name()
148+
}
149+
117150
// --- Styles ---
118151

119152
// Color styles are functions so they read the active theme palette at render time and

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ require (
3333
github.com/twitchtv/twirp v8.1.3+incompatible
3434
github.com/urfave/cli/v3 v3.9.0
3535
go.uber.org/atomic v1.11.0
36+
go.uber.org/zap v1.28.0
3637
golang.org/x/sync v0.20.0
3738
golang.org/x/time v0.15.0
3839
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af
@@ -243,7 +244,6 @@ require (
243244
go.opentelemetry.io/otel/trace v1.44.0 // indirect
244245
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
245246
go.uber.org/multierr v1.11.0 // indirect
246-
go.uber.org/zap v1.28.0 // indirect
247247
go.uber.org/zap/exp v0.3.0 // indirect
248248
go.yaml.in/yaml/v3 v3.0.4 // indirect
249249
golang.org/x/crypto v0.52.0 // indirect

0 commit comments

Comments
 (0)