Expand description
Dual-output logging — console (colored) + file (JSON).
§CUSTOMIZE: Why dual logging?
Two simultaneous log destinations serve different audiences:
| Destination | Format | Audience | Purpose |
|---|---|---|---|
| stderr | Pretty | Developer / operator | Human-readable, colorized |
| File | JSON lines | Log aggregator / AI | Machine-parseable, indexed |
The console output is optimized for human scanning: compact timestamps, semantic colors, noise suppression. The file output preserves all fields for programmatic analysis (grep, jq, log aggregators, AI agents).
§CUSTOMIZE: Usage in main.rs
Replace the existing tracing_subscriber setup in main.rs with:
use soma::logging;
let data_dir = config.data_dir(); // e.g. ~/.soma
logging::init(&data_dir, "example")?;In stdio mode, suppress all logs to avoid polluting the MCP JSON stream:
if stdio_mode {
// Don't call logging::init() — tracing stays at warn level on stderr only
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::new("warn"))
.with_writer(std::io::stderr)
.init();
} else {
logging::init(&data_dir, "example")?;
}§CUSTOMIZE: Log file location
Logs are written to {data_dir}/logs/{service}.log.
For the example service this resolves to ~/.soma/logs/example.log.
The file is truncated (not rotated) when it exceeds 10MB. This keeps disk usage predictable and eliminates the complexity of log rotation. For production deployments that need persistent logs, configure a log aggregator (e.g. Loki, Datadog, CloudWatch) to ship from stderr instead.
Modules§
- aurora
- Aurora color palette — ANSI 256 constants for log formatting.
- formatter
- Aurora console log formatter — pretty, colored, human-readable.
Functions§
- init
- Initialise dual logging: pretty console (stderr) + JSON file.
- should_
colorize - Determine whether console log output should include ANSI color codes.