Skip to content

Commit 874f6bf

Browse files
xerialclaude
andauthored
fix(runi-log): write logs to stderr (#17)
## Summary - `init_with_env` uses `IsTerminal` on stderr to choose human vs JSON format, but `fmt::layer()` defaults to **stdout** — so a `2>log` redirect would ship JSON to stdout while the TTY check still saw a terminal. - Pin all three layers (`init_with_env` TTY, `init_with_env` non-TTY, `init_with_level`) to `std::io::stderr` so the writer and the terminal check agree, and match the usual CLI convention of logs-on-stderr. ## Test plan - [x] `cargo build -p runi-log --all-targets` - [x] `cargo test -p runi-log` - [x] `cargo clippy -p runi-log --all-targets -- -D warnings` - [x] `cargo fmt --all -- --check` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent aa25dbd commit 874f6bf

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

runi-log/src/lib.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,19 @@ pub fn init_with_env(env_var: &str) {
2525
if is_terminal {
2626
tracing_subscriber::registry()
2727
.with(filter)
28-
.with(fmt::layer().event_format(UniFormatter::new(true)))
28+
.with(
29+
fmt::layer()
30+
.with_writer(std::io::stderr)
31+
.event_format(UniFormatter::new(true)),
32+
)
2933
.init();
3034
} else {
3135
tracing_subscriber::registry()
3236
.with(filter)
3337
.with(
3438
fmt::layer()
3539
.json()
40+
.with_writer(std::io::stderr)
3641
.with_target(true)
3742
.with_file(true)
3843
.with_line_number(true),
@@ -46,7 +51,11 @@ pub fn init_with_level(level: &str) {
4651
let filter = EnvFilter::new(level);
4752
tracing_subscriber::registry()
4853
.with(filter)
49-
.with(fmt::layer().event_format(UniFormatter::new(true)))
54+
.with(
55+
fmt::layer()
56+
.with_writer(std::io::stderr)
57+
.event_format(UniFormatter::new(true)),
58+
)
5059
.init();
5160
}
5261

0 commit comments

Comments
 (0)