Skip to content

Telemetry

Polytoken can export trace data to an OpenTelemetry collector using the OTLP protocol. When you enable telemetry, Polytoken sends spans for agent invocations, model requests, and tool executions, following the draft GenAI semantic conventions.

Telemetry is opt-in and disabled by default. To enable it, add a telemetry block to your user (global) config file:

[telemetry]
protocol = "grpc"
endpoint = "http://localhost:4317"

Polytoken reads this block only from your user config. A project config cannot set or override telemetry settings. This prevents repository-owned configuration from redirecting trace data or injecting headers.

Ambient OTEL_* environment variables do not enable or configure trace export. Every setting comes from the telemetry block.

Polytoken supports two OTLP transports:

  • http/protobuf: sends trace data as HTTP POST requests with Protocol Buffers encoding. Configure the collector’s HTTP endpoint (typically port 4318). Polytoken appends the /v1/traces path automatically.
  • grpc: sends trace data over a gRPC connection using tonic. Configure the collector’s gRPC endpoint (typically port 4317).

The endpoint is the collector’s base URI. Polytoken validates it and rejects endpoints with paths, query parameters, fragments, or userinfo.

Valid examples:

# HTTP/protobuf (collector on port 4318)
[telemetry]
protocol = "http/protobuf"
endpoint = "http://localhost:4318"
# gRPC (collector on port 4317)
[telemetry]
protocol = "grpc"
endpoint = "http://localhost:4317"

For remote collectors with TLS:

[telemetry]
protocol = "grpc"
endpoint = "https://collector.example.com:4317"

You can attach custom headers to each export request. This is useful for authentication tokens or routing metadata. Header keys and values support environment variable substitution:

[telemetry]
protocol = "grpc"
endpoint = "http://localhost:4317"
headers = { "x-api-key" = "${COLLECTOR_API_KEY}" }

Polytoken treats header keys and values as secrets. Header values never appear in diagnostics, logs, or exported spans.

By default, Polytoken identifies itself with the service name polytoken. You can override this:

[telemetry]
protocol = "grpc"
endpoint = "http://localhost:4317"
service_name = "my-polytoken-deployment"

The daemon and exec mode both report the same service name. Polytoken distinguishes them with a separate polytoken.execution_mode resource attribute (daemon or exec).

Each exported span follows the draft OpenTelemetry GenAI semantic conventions (Development status, revision July 2026). Three span types are emitted:

One invoke_agent span (INTERNAL kind) per agent turn. This span covers the full provider/tool/compaction loop from start to terminal return. It records the model, provider, session ID, prompt ID, and final token usage.

One chat span (CLIENT kind) per provider attempt, including retries. Each span records the provider name, model name, and per-request token usage (input, output, cache creation, cache read). Each retry produces a separate span.

One execute_tool span (INTERNAL kind) per tool call. Each span records the tool name, tool call ID, session ID, and prompt ID. The span covers the full tool lifecycle including timeout promotion to a background job.

Polytoken does not export any of the following, regardless of configuration:

  • Prompt content, system instructions, or message bodies
  • Tool arguments or tool results
  • Project paths or filesystem paths
  • Environment variable values
  • Authentication tokens or header values
  • Provider error messages that may contain payloads

These data categories are marked as Opt-In in the GenAI semantic conventions. Polytoken does not implement the opt-in.

Telemetry export is fail-open. If the collector is unreachable, rejects connections, or returns errors, Polytoken continues operating normally. Agent turns are not blocked by export failures. Dropped spans are not retried beyond the SDK’s bounded batch behavior.

When the daemon or exec process exits, Polytoken performs a bounded flush of pending trace data. The flush runs on a dedicated thread with a hard deadline of 10 seconds. If the collector does not respond within the deadline, Polytoken abandons the flush and exits. Pending spans that were not exported may be lost.

This means a slow or unresponsive collector can cause trace data loss during shutdown, but cannot prevent Polytoken from exiting.