Summary
Switch from the current plain-text tracing output to structured JSON logging. Makes logs parseable by log aggregators (Loki, CloudWatch, etc.) and easier to filter/search.
Current state
Uses tracing_subscriber::fmt() with default text format and env-filter.
Proposed
- Add
tracing-subscriber JSON format layer (already has the feature: json)
- Toggle via env var:
MAYL_LOG_FORMAT=json (default: text for local dev)
- Keep
RUST_LOG / env-filter for level control
- Structured fields already in place (
info!(user = %smtp_user, ...)) — just need the formatter swap
Implementation
let subscriber = tracing_subscriber::fmt()
.with_env_filter(
EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "mayl=info".parse().unwrap()),
);
if env_or("MAYL_LOG_FORMAT", "text") == "json" {
subscriber.json().init();
} else {
subscriber.init();
}
Add "json" to tracing-subscriber features in Cargo.toml.
Verification
Summary
Switch from the current plain-text tracing output to structured JSON logging. Makes logs parseable by log aggregators (Loki, CloudWatch, etc.) and easier to filter/search.
Current state
Uses
tracing_subscriber::fmt()with default text format andenv-filter.Proposed
tracing-subscriberJSON format layer (already has the feature:json)MAYL_LOG_FORMAT=json(default:textfor local dev)RUST_LOG/ env-filter for level controlinfo!(user = %smtp_user, ...)) — just need the formatter swapImplementation
Add
"json"to tracing-subscriber features in Cargo.toml.Verification
MAYL_LOG_FORMAT=json cargo runoutputs JSON linescargo runstill outputs plain text (default)info!/warn!/error!fields appear as JSON keys