- Distributed traces via OTLP to any OpenTelemetry-compatible backend (Jaeger, Grafana Tempo, etc.)
- Prometheus metrics scraped from a configurable stats address
- Structured logs written to stdout with configurable level and format
Distributed tracing
Tracing is configured underconfig.tracing (static config file) or frontendPolicies.tracing (dynamic config). Send traces to any OTLP endpoint:
frontendPolicies form used in the telemetry example:
Tracing fields
| Field | Description |
|---|---|
otlpEndpoint | Full OTLP endpoint URL, e.g. http://localhost:4317 |
host | OTLP host in host:port format (used in frontendPolicies) |
otlpProtocol | OTLP transport protocol (grpc or http/protobuf) |
path | OTLP path. Defaults to /v1/traces |
randomSampling | CEL expression or boolean. Initiates a new trace when no incoming trace context is present. Defaults to false |
clientSampling | CEL expression or boolean. Whether to continue a trace from an incoming traceparent header. Defaults to true |
fields.add | Additional attributes to add to every span |
fields.remove | Span attributes to strip before exporting |
Sampling
randomSampling controls whether agentgateway starts new traces for requests that arrive without a trace context. It accepts:
true/false— sample all or none- A float between
0.0and1.0— percentage of requests to sample - A CEL expression that evaluates to a float or boolean
clientSampling controls whether to propagate traces that arrive with an existing traceparent header. It defaults to true (always propagate).
Span fields
Add custom attributes to all spans, or remove default attributes:Access log export via OTLP
Export access logs as OpenTelemetry LogRecords alongside the default stdout output:Prometheus metrics
Metrics are enabled by default and exposed at/metrics on a dedicated stats address. Configure the address with config.statsAddr:
statsAddr is not set, agentgateway defaults to an internal address. Scrape the endpoint to verify:
Key metrics
| Metric | Description |
|---|---|
tool_calls_total | Total MCP tool calls, labelled by server and tool name |
list_calls_total | Total MCP list operations, labelled by resource type |
agentgateway_requests_total | Total HTTP requests, labelled by gateway, method, and status |
Kubernetes scraping
The Helm chart configures Prometheus scraping annotations on pods by default:Structured logging
Configure log level and format underconfig.logging:
Logging fields
| Field | Description |
|---|---|
level | Log level in RUST_LOG syntax. Defaults to info. Supports per-module levels, e.g. rmcp=warn,info |
format | Log output format: json or text |
fields.add | Additional fields to include in every log line |
fields.remove | Fields to strip from log output |
filter | Additional filter expression |
Log level examples
Running the telemetry example
Send requests via MCP Inspector
http://localhost:3000 and invoke a few tools to generate trace data.View traces in Jaeger
Open http://localhost:16686/search and search for
agentgateway spans.OpenTelemetry Collector
For production deployments, route telemetry through the OpenTelemetry Collector. The exampleotel-collector-config.yaml fans out traces to Jaeger and logs to stdout:
Grafana integration
A Grafana dashboard JSON file is included atmanifests/grafana.json. Import it into your Grafana instance to visualize agentgateway metrics alongside traces from Jaeger or Grafana Tempo.
Agentgateway implements the OpenTelemetry Gen AI semantic conventions v1.37.0 for AI-specific span attributes, including model name, token counts, and provider information.