Trace distributed agents
Keep one trace connected as a request crosses services.
Distributed tracing keeps one live request in a single Judgment trace as it crosses services. It does this by propagating OpenTelemetry context between them. Use Durable work instead when a queue, retry, or human approval wait resumes the work later.
Use the same Judgment project across all services. Give each service a distinct
service.name resource attribute when you initialize its tracer, not on
individual spans. One trace then shows every hop while the services stay
distinguishable.
Set the session ID on the upstream root before injecting the outgoing headers.
The SDK includes that ID in Judgment baggage. Tracer.continue_trace() and
Tracer.continueTrace() restore the baggage with the trace context, so
downstream child spans inherit the same session ID automatically.
Prerequisites
- Configure the same Judgment organization and project in every participating service. See Project routing.
- Give each service a distinct
service.nameresource attribute. - Initialize the tracer before any service creates spans.
- Identify the upstream root and the outgoing and incoming request boundaries.
Send trace state
Inject the current trace context into the outgoing request:
from judgeval.trace.propagation import inject
headers = {}
inject(headers)
response = httpx.post(DOWNSTREAM_URL, json=payload, headers=headers)import { propagation } from "judgeval";
const headers: Record<string, string> = {};
propagation.inject(headers);
await fetch(DOWNSTREAM_URL, { method: "POST", headers, body });Receive trace state
Continue the trace before starting child spans. A span that starts first gets a new trace ID, which makes the request appear as two unrelated traces. Middleware is a reliable place to continue the trace because it covers every incoming request:
with Tracer.continue_trace(request.headers):
result = handle_request(payload)await Tracer.continueTrace(req.headers, async () => {
return handleRequest(payload);
});Delayed queue work needs a stable job or session ID instead of the live request’s trace context. Start a new trace when the worker receives the task. See Durable work.
Verify
First run the shared verification checklist. Then send one request through both services. The downstream spans should appear under the upstream root in one trace. Two traces mean the context did not arrive or was restored after a downstream span had already started.
Troubleshooting
| Symptom | Check |
|---|---|
| Two traces appear for one request | Continue the incoming context before starting any downstream span. |
| Downstream spans are missing | Confirm the carrier headers reached the service and its tracer exports to the same project. |
| Downstream session is missing | Set the session ID before injecting upstream context and use continue_trace or continueTrace to restore baggage. |
| Queue work extends the live trace | Start a new trace when the queued job begins and reuse only the stable session ID. |
Related pages
- Group traces into sessions
- Durable work for work that resumes after a queue or human approval wait
- Trace conventions