Stream logs to an OpenTelemetry collector

An OpenTelemetry log stream sends each request of a gateway environment as one trace to a collector or backend that accepts OTLP over HTTP, about 30 seconds after the request ends.

Before you begin

  • A collector with an OTLP/HTTP receiver, reachable from the internet over https://. Faustine does not send to private addresses. See Collector configuration in the OpenTelemetry docs.
  • The headers the collector requires for authentication, if any.

The stream sends OTLP/HTTP with a JSON body. It does not send OTLP over gRPC.

Add the stream

  1. In the portal, go to Agent Gateway and select your gateway.
  2. Select the Logs tab, then Log settings.
  3. Under Log streams, select Add a stream.
  4. Under Destination, select OpenTelemetry.
  5. Fill in the fields in the table.
  6. Select Send test event. Faustine sends a trace of one request marked test: true and shows Delivered when the collector accepts it.
  7. Select Continue.
  8. Under What to send, choose All requests or Errors and denials, and turn on Discovery calls or Payloads if you want them. Select Continue.
  9. Under Review and create, enter a Name and select Create stream.
Field Value
OTLP/HTTP endpoint The address of the collector, such as https://otel.example.com:4318. Faustine adds /v1/traces.
Headers Headers sent with every batch, such as Authorization. Optional, up to 10. The values are stored encrypted.
Service name The service.name of the traces. Optional. Defaults to faustine-gateway.

The stream's page opens. The first trace reaches the collector about 30 seconds after the next request ends.

What the collector receives

Each batch is one OTLP/HTTP request in JSON, posted to /v1/traces on the endpoint. A request is one trace.

Span Kind Name Main attributes
The request Server tools/call <tool> over MCP, REST <operation> over REST gen_ai.tool.name, mcp.method.name, mcp.session.id, faustine.request.id, faustine.request.status, faustine.actor.name, faustine.client.name
Each call Internal The operation key, such as crm.deals.get faustine.op.key, faustine.connection, faustine.call.status, faustine.upstream.status
Each exchange with your API Client The HTTP method, or <service>/<method> for gRPC http.request.method, url.full, http.response.status_code, server.address, or rpc.system, rpc.service, rpc.method

The resource has service.name, deployment.environment.name (the environment's slug) and faustine.gateway.id, faustine.gateway.slug and faustine.gateway.name. A span that failed has the status ERROR and an error.type attribute. When the stream includes payloads, the request span has gen_ai.tool.call.arguments and gen_ai.tool.call.result, each cut at 8192 characters.

The span of each exchange with your API has the span ID the gateway sent to your API in the traceparent header. If your API sends its own traces to the same backend, its spans appear inside the gateway's trace.

The instrumentation scope is faustine.gateway. Each batch also has an X-Faustine-Delivery header that identifies it.

Other attributes

Span Attributes
The request gen_ai.operation.name (execute_tool), jsonrpc.request.id, client.address, user_agent.original, faustine.request.kind, faustine.request.channel, faustine.deny_reason, faustine.op.key, faustine.actor.kind, faustine.actor.id, faustine.client.version, faustine.client.trace_id, faustine.client.request_id, faustine.run_execution.id
Each call faustine.deny_reason, faustine.upstream.ms, faustine.recipe, faustine.replayed, and with payloads faustine.call.input and faustine.call.output
Each exchange with your API server.port, rpc.grpc.status_code, faustine.attempt.purpose, faustine.attempt.number, faustine.upstream.request_id

An exchange that signed in to your API has (sign-in) after its name. An attribute without a value is left out.

Troubleshooting

Symptom Cause Fix
The test shows "Log streams only reach public hosts." The endpoint resolves to a private or reserved address. Expose the collector on a public address with TLS.
The test shows "Nothing at that path" The endpoint already has a path the collector does not serve. Enter the base address. Faustine adds /v1/traces unless the URL already ends with it.
The test shows "The destination rejected the credentials" The collector requires a header that is missing or wrong. Add it under Headers.

Next steps

Last updated November 11, 2026