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.

Corresponding OTEL_* environment variables supersede the values in this block per the OpenTelemetry SDK environment variable specification. Env vars do not enable export without a telemetry block. Invalid values are warned about and treated as unset. See the OTel SDK env var spec for the full specification.

Config fieldSignal-specific env varGeneral env var
telemetry.protocolOTEL_EXPORTER_OTLP_TRACES_PROTOCOLOTEL_EXPORTER_OTLP_PROTOCOL
telemetry.endpointOTEL_EXPORTER_OTLP_TRACES_ENDPOINTOTEL_EXPORTER_OTLP_ENDPOINT
telemetry.headersOTEL_EXPORTER_OTLP_TRACES_HEADERSOTEL_EXPORTER_OTLP_HEADERS
telemetry.service_nameOTEL_SERVICE_NAMEOTEL_RESOURCE_ATTRIBUTES (service.name key)
(no config field)OTEL_EXPORTER_OTLP_TRACES_TIMEOUTOTEL_EXPORTER_OTLP_TIMEOUT

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 telemetry.endpoint config field is the collector’s base URI. Polytoken validates it and rejects endpoints with paths, query parameters, fragments, or userinfo. Only the origin (scheme, host, and optional port) is accepted.

Endpoints set via OTEL_EXPORTER_OTLP_TRACES_ENDPOINT or OTEL_EXPORTER_OTLP_ENDPOINT follow OTel OTLP rules and may include base paths. The signal-specific endpoint is used as-is. The general endpoint gets /v1/traces appended for HTTP/protobuf with URL-aware path joining.

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 as span content, 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

The configured service name and request headers intentionally affect telemetry resource attributes and export requests. These are configuration values that you set, not exported data content.

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.