///|
/// Trace-id propagation middleware (← go-zero's `trace` handler): continue the
/// inbound `traceparent` trace or start a new one, mint a child span, and stamp
/// both `traceparent` and a convenience `x-trace-id` onto the response so the id
/// flows to the client and downstream calls. The per-assembly seed counter keeps
/// span ids distinct across the requests this layer serves. Requests whose path
/// is listed in `ignore_paths` are left untraced (← `WithTraceIgnorePaths`, the
/// blacklist that keeps health checks out of the trace store), as are non-HTTP
/// scopes.
pub fn tracing(
header~ : String = "x-trace-id",
ignore_paths~ : Array[String] = [],
) -> Middleware {
let counter : Ref[Int64] = { val: 0L, }
inner => {
(scope, receive, send) => {
match scope {
Http(hs) if !ignore_paths.contains(hs.path) => {
counter.val = counter.val + 1L
let inbound = scope_header(scope, "traceparent")
let ctx = @trace.next_trace_context(inbound, counter.val)
let wrapped : @moonasgi.Send = event => {
match event {
HttpResponseStart(status~, headers~, trailers~) =>
send(
@moonasgi.Event::HttpResponseStart(
status~,
headers=[
(header, ctx.trace_id),
("traceparent", ctx.to_traceparent()),
..headers,
],
trailers~,
),
)
other => send(other)
}
}
inner(scope, receive, wrapped)
}
_ => inner(scope, receive, send)
}
}
}
}