Telemetry

Configure tracing output and optional OTLP span export with TelemetryConfig and a single init call.

adk-rs instruments itself with the tracing crate. The telemetry feature adds a one-shot init that wires a tracing-subscriber stack — an env-style filter plus a formatted stderr layer — and the otel feature extends it with an OpenTelemetry OTLP export pipeline.

TelemetryConfig

FieldTypeMeaning
filterOption<String>RUST_LOG-style filter, e.g. adk_rs=debug,info. Defaults to info. A set RUST_LOG environment variable takes precedence over this field.
formatLogFormatstderr output format: Compact (default), Pretty, or Json (newline-delimited, for log aggregators).
otlp_endpointOption<String>OTLP HTTP endpoint URL. Only used when the otel feature is enabled; ignored otherwise.
service_nameOption<String>service.name on the OTel resource. Defaults to adk-rs.

init

fn init(cfg: TelemetryConfig) -> Result<()>
Initialise tracing once at process start. Idempotent — a second call is a no-op, so libraries and tests can call it defensively. Filter resolution order: RUST_LOG env var, then cfg.filter, then info.
Plain structured loggingrust
use adk_rs::telemetry::{LogFormat, TelemetryConfig, init};

init(TelemetryConfig {
    filter: Some("adk_rs=debug,info".into()),
    format: LogFormat::Json,
    ..TelemetryConfig::default()
})?;

What gets traced

The crate creates spans via #[tracing::instrument] at the three layers you most often need to correlate:

  • RunnerRunner::run opens a span carrying app and agent fields, so every event of a turn nests under one root span.
  • AgentsLlmAgent::run opens a span with agent and invocation (the invocation id) fields.
  • Models — each provider’s generate_content (Gemini, Anthropic, OpenAI-compatible) opens a span with a model field, capturing per-call latency. Request bodies are skipped from the span fields.

Beneath the spans, the crate logs events at conventional levels: warn for recoverable conditions (webhook delivery failures, non-loopback binds, schema fallbacks), debug for protocol details, and error for stream failures surfaced to HTTP clients. Tool execution is visible through the agent span’s events rather than a dedicated per-tool span.

OTLP export (feature otel)

With otel enabled and otlp_endpoint set, init builds an opentelemetry-otlp HTTP span exporter pointed at the endpoint, wraps it in a batch exporter on the Tokio runtime, attaches a resource with your service_name, and layers tracing-opentelemetry into the subscriber. Every tracing span above — runner, agent, model — is then exported as an OTel trace. When otlp_endpoint is None, no OTel layer is installed even with the feature on.

Cargo.tomltoml
[dependencies]
adk-rs = { version = "0.6", features = ["gemini", "otel"] }
# "otel" implies "telemetry"
Exporting to an OTLP collectorrust
use adk_rs::telemetry::{TelemetryConfig, init};

init(TelemetryConfig {
    filter: Some("info".into()),
    otlp_endpoint: Some("http://localhost:4318/v1/traces".into()),
    service_name: Some("weather-agent".into()),
    ..TelemetryConfig::default()
})?;