restate-server process exports the execution journal — ingress, invocation start, each attempt, invocation end. Your service process exports the agent’s LLM and tool spans. Wrapping your tracer provider in Restate’s RestateTracerProvider attaches the agent spans to the invocation attempt, so once both processes export to Arize AX you get a single trace covering the durable workflow and the agent that runs inside it.
Both exporters are required. If only the service process exports to Arize AX,
RestateTracerProvider still parents the agent spans to a Restate span that never arrives, and the trace lands as orphaned spans with no root. Configure restate-server as well, as shown in Export the Restate journal.Prerequisites
- Python 3.10+ (required by
restate-sdk) - Restate Server and CLI 1.7+
- An Arize AX account (sign up)
- Your Arize AX Space ID and API Key
- An
OPENAI_API_KEYfrom the OpenAI Platform
Launch Arize AX
- Sign in to your Arize AX account.
- From Space Settings, copy your Space ID and API Key. You will set them as
ARIZE_SPACE_IDandARIZE_API_KEYbelow.
Install
This example uses the OpenAI Agents SDK. Any framework with an OpenInference instrumentor works the same way.The
tracing extra installs the OpenTelemetry API that RestateTracerProvider needs, and the openai extra installs the Agents SDK plus Restate’s integration for it. Installing restate-sdk on its own gives you an ImportError on restate.ext.tracing.Configure credentials
Setup tracing
Wrap the tracer provider returned byregister in RestateTracerProvider, then hand that to the instrumentor:
Export the Restate journal
restate-server exports its own spans, so point it at Arize AX too. Arize AX authenticates with the authorization and arize-space-id headers, and reads the project from the openinference.project.name resource attribute. Set all three in the server’s environment:
RESTATE_TRACING_HEADERS__ becomes a hyphen in the header name, so RESTATE_TRACING_HEADERS__ARIZE_SPACE_ID sends arize-space-id. Naming it RESTATE_TRACING_HEADERS__SPACE_ID instead sends space-id, which Arize AX rejects with HTTP 403.
Setting the project matters because restate-server has no flag for it. Reusing $ARIZE_PROJECT_NAME keeps both halves of the trace in one project; give the server a different value and the journal spans and agent spans land in separate projects.
Restate also accepts these headers in a config file under a [tracing-headers] table, but the environment form keeps your API key out of a file on disk.
For EU spaces both exporters have to move, or half the trace goes to the wrong region and you get the orphaned spans described above. Pass
endpoint=Endpoint.ARIZE_EUROPE (from arize.otel) to register in instrumentation.py, and start the server with --tracing-endpoint otlp+https://otlp.eu-west-1a.arize.com/v1/traces.Run Restate
Define the agent as a Restate service.durable_function_tool makes each tool call recoverable, and run_typed records the API call in the journal so a retry replays it instead of repeating it:
Expected output
The ingress returns the handler’s JSON-encoded reply, so the degree sign arrives escaped:Verify in Arize AX
- Open your Arize AX space and select project
restate-tracing-example. - Open the newest trace. It is rooted at the Restate ingress span, with the agent’s spans under the invocation attempt:
RestateTracerProvider flattens the agent spans into siblings under the invocation attempt rather than preserving the agent framework’s own nesting, so the LLM and tool spans sit at the same depth. Restate has said a future release will preserve the original hierarchy.Check from the skill, CLI, or SDK
Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.- Arize skill (agent)
- AX CLI
- SDK
Install the Arize Skills plugin and let your coding agent check for you:Then prompt your agent:
Use the arize-trace skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.
What Arize AX captures
- Restate journal spans for the ingress request, invocation start, every invocation attempt, and invocation end, each carrying
restate.invocation.idandrestate.invocation.target - OpenInference agent, chain, LLM, and tool spans for the agent that runs inside the attempt
- Retries as additional invocation attempt spans in the same trace, so a recovered run shows every attempt rather than only the one that succeeded
Troubleshooting
- Spans appear with no root, or the journal spans are missing.
restate-serveris not exporting. Check its logs forBatchSpanProcessor.Flush.ExportError; aStatus(403, ...)means theauthorizationorarize-space-idheader is wrong. The most common cause is naming the variableRESTATE_TRACING_HEADERS__SPACE_ID, which sendsspace-idrather thanarize-space-id. - Journal spans and agent spans are in different projects.
OTEL_RESOURCE_ATTRIBUTESwas not set for therestate-serverprocess, or it names a different project thanARIZE_PROJECT_NAME. ImportErroronrestate.ext.tracing. Install the extras:pip install "restate-sdk[openai,tracing]".- No traces at all. Confirm
instrumentationis imported beforeagentsin your service module, and that the service was registered withrestate deployments register.