// examples/log_pipeline — runnable demonstration of the `src/logging`
// direction as a realistic request-handling pipeline: distributed tracing
// spans with W3C traceparent propagation, structured events rendered as
// JSON and logfmt, PII redaction before shipping, and level accounting.
//
// Run with:
// moon run examples/log_pipeline
///|
fn simulate_request(user : String, ok : Bool) -> Unit {
let span = @log.enter_span("handle_request")
@log.log(Info, {
"msg": VStr("request received"),
"user": VStr(user),
"password": VStr("hunter2"),
})
let inner = @log.enter_span("route_lookup")
@log.log(Debug, {
"msg": VStr("routing"),
"algo": VStr("bidirectional_dijkstra"),
})
@log.exit_span(inner)
if ok {
@log.log(Info, { "msg": VStr("request ok"), "status": VInt(200) })
} else {
@log.log(Error, { "msg": VStr("upstream failed"), "status": VInt(502) })
}
@log.exit_span(span)
}
///|
fn main {
@log.reset_logger()
let trace = @log.begin_trace()
println("=== distributed tracing ===")
println("trace id : \{trace.value}")
simulate_request("alice", true)
simulate_request("mallory", false)
let ctx = @log.capture_context()
println("traceparent : \{@log.inject_traceparent(ctx)}")
println("finished spans: \{@log.finished_spans().length()}")
println("")
let events = @log.captured_events()
println("=== formatting: same event, three renderers ===")
let first = events[0]
println("json : \{@log.format_json(first)}")
println("logfmt: \{@log.format_logfmt(first)}")
println("pretty: \{@log.format_pretty(first)}")
println("")
println("=== redaction before shipping ===")
let policy = @log.RedactionPolicy::by_names(["password", "token"])
let scrubbed = @log.redact(policy, first)
println("scrubbed: \{@log.format_logfmt(scrubbed)}")
println("")
println("=== env filter: module thresholds like RUST_LOG ===")
match @log.parse_env_filter("warn,router=debug") {
Ok(filter) => {
println("directive 'warn,router=debug':")
let fallback = filter.fallback.label()
let router = filter.threshold_for("router").label()
println(" fallback threshold: \{fallback}, router threshold: \{router}")
}
Err(e) => println("filter error at \{e.pos}: \{e.message}")
}
println("")
println("=== level accounting ===")
let counts = @log.count_by_level(events)
for level in ([Trace, Debug, Info, Warn, Error] : Array[@log.Level]) {
println(" \{level.label()}: \{@log.level_count(counts, level)}")
}
}