Files
kebab/crates/kebab-app/src/logging.rs
altair823 685007789a style: cargo fmt --all (round 4 ingest log feature follow-up)
Phase C4 executor 의 마지막 `fix(test): clippy + fmt fixes` commit 이
test file 부분만 fmt 적용. workspace 전체 fmt 누락 발견 → cargo fmt --all
적용. 모든 import alphabetical reorder + line wrapping 정합.

추가 untracked artifact 동시 commit:
- docs/superpowers/specs/2026-05-28-v0.20-ingest-log-spec.md (491 line, ACCEPT)
- docs/superpowers/plans/2026-05-28-v0.20-ingest-log-plan.md (616 line, ACCEPT)

workspace test: 1370 passed / 0 failed / 50 ignored, ingest_log_smoke green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 04:18:40 +00:00

46 lines
1.5 KiB
Rust

//! Tracing initialization helper for `kb-cli`.
//!
//! Daily-rolling file appender at `~/.local/state/kebab/logs/` per task spec.
//! Returns a `WorkerGuard` that the caller must keep alive until program
//! exit (so buffered log lines flush).
use anyhow::Result;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LogLevel {
Default,
Verbose,
Debug,
}
/// Initialize tracing. Returns a guard to keep alive until exit. Idempotent
/// — a second call is a no-op (the second `try_init` is dropped silently
/// but the guard is still returned so the caller can keep it alive).
pub fn init(level: LogLevel) -> Result<WorkerGuard> {
let log_dir = kebab_config::Config::xdg_state_dir().join("logs");
std::fs::create_dir_all(&log_dir)?;
let file_appender = tracing_appender::rolling::daily(&log_dir, "kb.log");
let (nb, guard) = tracing_appender::non_blocking(file_appender);
let env_filter = match level {
LogLevel::Default => {
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("warn"))
}
LogLevel::Verbose => EnvFilter::new("info"),
LogLevel::Debug => EnvFilter::new("debug"),
};
let registry = tracing_subscriber::registry()
.with(env_filter)
.with(fmt::layer().with_writer(nb).with_ansi(false));
// `try_init` rather than `init` so a second call (e.g. in tests) is a
// no-op.
let _ = registry.try_init();
Ok(guard)
}