ADR-0028: correlated runtime tracing with value-free events¶
Status: accepted. Local verification passes 641 provider unit cases; broad live acceptance passes 213 provider integration and 61 selected EF cases. A final first-failure classification correction is verified by all 641 units and seven repeated live tracing cases. See the acceptance record (maintainer-local record).
FS-10 requires correlation from EF operation to statement and driver invocation, timing, cancellation, stable event names, sanitized parameter metadata and error classifications. The prior submission-only span did not cover cursor failures, materialization, writes or commits. Extend the existing public ActivitySource instead of adding an exporter dependency or a parallel logging protocol. Applications collect and sample using standard .NET/OpenTelemetry APIs.
Operations own internal spans through cleanup. Statements own a cursor-lifetime span, with the existing client Run span nested beneath it. A wrapper forwards the pinned Driver 6.3 cursor contract: Current, IsOpen, KeysAsync, PeekAsync, FetchAsync, ConsumeAsync and IAsyncEnumerable/IAsyncEnumerator. Its underlying enumerator remains authoritative; no alternate transport or result buffering is introduced. Completion is idempotent, synchronous/asynchronous cursor errors preserve exception identity, and ambient activities are restored around callbacks. There is no wrapper without a sampled statement. No per-row span/event is emitted. Early disposal finishes a query; abandoning an undisposed enumerator retains the existing resource-lifetime problem.
Instrument native Cypher, EXPLAIN, schema metadata, migration transport and connectivity as well as provider LINQ and SaveChanges. Transaction begin/commit/rollback use client spans without changing ordering, cancellation checkpoints, ownership or cleanup. Commit success is tagged acknowledged; failure is unconfirmed. The enclosing operation can fail during cleanup after a successful commit. Nothing in telemetry permits automatic replay or changes ADR-0026.
Statement events have fixed names and no payload. Metadata contains only fixed kind/error categories, top-level parameter counts and broad type counts. Nested collections are neither traversed nor formatted. Fingerprints are restricted to provider-generated query/mutation/schema/connectivity text; native, EXPLAIN and migration text is excluded. No query text, parameter names/values, exception messages, database/connection identity, journal identifiers or model type names are added to spans. Existing EF command logging and explicit query/plan inspection remain separate privacy surfaces. Structural metadata is not anonymization.
The tracing guide specifies operation lifetimes and privacy boundaries. Tests use real .NET ActivityListeners with sampling and concurrent contexts, scripted driver lifecycle failures, and disposable Neo4j for actual query, write, schema and migration behavior. Whole-provider regression passed. A new projector-plus-cleanup regression exposed primary error-category replacement; preserving the first error on each span fixes it without changing exception identity or driver calls. EF compilation/interceptors outside provider calls and direct driver operations from optional tooling/application code are not claimed as provider spans.