Every request carries a TraceContext that any code running in the request can read, without passing it as a parameter. Use it to put a request id in your logs, and forward it on outbound calls so logs from different services can be matched up. It is always on.
import 'package:revali_router/revali_router.dart';
final requestId = TraceContext.current?.requestId;
TraceContext.current stays available across awaits. Outside a request (at startup, or in a timer) it is
null.
| Field | Contents |
|---|---|
requestId |
Taken from the incoming
X-Request-Id
header. If the header is missing or blank, a random 32-character hex id is generated. Always set.
|
traceparent |
The W3C traceparent header, if the caller sent one. It is never generated. |
tracestate |
The W3C tracestate header, if the caller sent one. |
baggage |
A mutable
Map<String, String>
parsed from the
baggage
header. It is sent to every service you forward it to, so keep secrets and personal data out of it.
|
Revali forwards traceparent but doesn't create spans. Collectors that understand W3C Trace Context keep working.
Forwarding to Another Service#
Revali never forwards these headers on its own. outboundHeaders() returns the headers that are set and leaves out the rest:
final headers = TraceContext.current?.outboundHeaders() ?? const {};
// {'X-Request-Id': '...', 'traceparent': '...', 'tracestate': '...', 'baggage': 'tenant=acme'}
With a generated revali_client, add them to every call with
HeaderInterceptor. It never overwrites a header that the call itself sets:
import 'package:revali_client/revali_client.dart';
import 'package:revali_router/revali_router.dart';
final server = Server(
client: HttpPackageClient(
interceptors: [
HeaderInterceptor(
() => TraceContext.current?.outboundHeaders() ?? const {},
),
],
),
);
outboundHeaders() never includes the caller's Authorization header. If a downstream service needs it, add it yourself at that call, because only you know whether the target is trusted.
Forwarding Through a Queue#
Publish with the same headers. Inside the consumer, TraceContext.current
is then the context of the request that published the message:
await broker.publish(
'order.placed',
jsonEncode(order),
headers: TraceContext.current?.outboundHeaders() ?? const {},
);