vllm-project / vllm-project/agentic-api
feat: OpenTelemetry foundation — opt-in OTLP export and correlated logs (#279 phase 1)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 284
- Forks
- 74
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 93
Description
Problem statement / motivation
Parent: #279 (phase 1 of the three-PR sequence proposed in the design comment on #279).
Make telemetry a first-class, off-by-default capability of the agentic-server binary: SDK/provider lifecycle, OTLP/HTTP export, the tracing → OpenTelemetry bridge, trace-correlated local logs, bounded export buffering, and deadline-bounded shutdown. Ship one root http.server.request span and the two HTTP semantic-convention metrics so the pipeline is verifiable end-to-end against a Collector. Execution-level spans and project metrics follow in phases 2 and 3.
A prototype of the config/lifecycle/subscriber half already exists on a local branch (typed OTEL_* config, providers, bridge, log correlation, 18 unit + 5 integration tests against an OTLP/HTTP stub); this issue covers finishing it into a mergeable PR.
Proposed solution
- Land the existing prototype (config, lifecycle, subscriber, tests) and fold in review follow-ups: gate
CorrelatedFormaton bridge presence so disabled mode does no per-event work; make the exporter's TLS feature explicit instead of relying on unification withrmcp-reqwest. - Add
TelemetryLayer+ body wrapper + request guard; wire it inbuild_router_with_auth. - Integration tests against an in-process OTLP/HTTP stub decoding protobuf: service identity on traces and metrics; root span for
/v1/responses(proxy route) with the attribute allow-list; body-drop closes the span and finalizes the gauge; unresponsive/slow Collector does not affect request latency; shutdown honours the deadline. - Docs page; note the
Runtime::shutdown_timeoutbehaviour change in the PR description.
Alternatives considered
Acceptance criteria (maps to #279 phase 1)
- With no exporter selected (or
OTEL_SDK_DISABLED=true) no provider/exporter/thread is created and a test proves no connection is made to the configured endpoint. - With
otlpselected, a Collector/stub receives spans and metrics whose resource carriesservice.name(defaultagentic-api),service.version(crate version), and mergedOTEL_RESOURCE_ATTRIBUTES. -
grpc/http/jsonprotocol values and unknown exporter values fail startup with a typed error;--help/--versionnever build exporters. - A request produces an
http.server.requestspan that closes after the last body byte (streaming included) and carries only allow-listed attributes. -
http.server.request.durationandhttp.server.active_requestsfinalize exactly once on success, error status, and mid-body client disconnect. - Log lines inside an exported span carry
trace_id/span_id;RUST_LOG=agentic_core=errorleaves export unchanged;OTEL_TRACES_SAMPLER_ARG=0leaves local logs unchanged; SDK export failures appear locally atWARNby default. - A Collector that accepts the connection and never responds does not stall request delivery; shutdown completes within its deadline;
SIGTERMexit is clean on the disabled, healthy, and black-hole-endpoint paths. -
cargo fmt --check,cargo clippy --all-targets -- -D warnings,cargo test --workspace,pre-commit run --all-filespass; all new crates declarerust-version ≤ 1.85(CI enforcement is tracked separately, see the MSRV issue).
Non-goals
Executor-stage spans, W3C extraction/injection for requests, WebSocket instrumentation, execution/delivery outcome semantics (phase 2); project metrics, timing definitions, Collector compose example (phase 3); OTLP log export; gRPC; agentic-llm-d wiring (the telemetry::init entry point is reusable for it later).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing telemetry prototype and the telemetry::init entry point, then trace build_router_with_auth and the Runtime::shutdown_timeout behavior. Check the listed unit and integration tests and the OTLP/HTTP stub requirements before changing anything. Done means the acceptance criteria pass, including disabled-mode behavior, request spans and metrics, correlated logs, bounded shutdown, documentation, and the required workspace checks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend, observability, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100