Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f17682c
Add opt-in deferred gated diagnostics capture (prototype)
NaluTripician Jun 15, 2026
287e3f3
Integrate gated diagnostics capture with DiagnosticsContext
NaluTripician Jun 15, 2026
b0f10eb
Re-home diagnostics under the capture engine (ownership flip)
NaluTripician Jun 15, 2026
e34a82a
Short-circuit the diagnostics build under the Off gate
NaluTripician Jun 15, 2026
f4efe3b
Document append-log rewrite as investigated + rejected
NaluTripician Jun 15, 2026
dbb4d6e
Add .NET-style summary block + diagnostics encoding option
NaluTripician Jun 15, 2026
696608c
Add RFC3339 wall-clock timestamps to diagnostics
NaluTripician Jun 16, 2026
05f8404
Rework capture hot path to a typed event log
NaluTripician Jun 17, 2026
e1f177c
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-rust in…
NaluTripician Jun 17, 2026
44edb13
Update live capture test to new create_driver API
NaluTripician Jun 17, 2026
122f19e
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-rust in…
NaluTripician Jun 17, 2026
d9acacc
Add 'verbosities' to cosmos cspell ignore list
NaluTripician Jun 17, 2026
b2399f4
Refine capture event log per review (RAII lease, newtypes)
NaluTripician Jun 18, 2026
8218244
Add user agent to the diagnostics summary block
NaluTripician Jun 18, 2026
56759f4
Merge branch 'main' into nalutripician/diagnostics-capture-redesign
NaluTripician Jun 18, 2026
a6b2f60
Populate per-event stage durations in diagnostics
NaluTripician Jun 18, 2026
e3d9a25
Phase A: make diagnostics-capture prototype honest and gated
NaluTripician Jun 22, 2026
b97b2ad
Capture real transport facets + server duration; harden codec
NaluTripician Jun 22, 2026
70176ca
Correct DIAGNOSTICS-CAPTURE.md to the gate-direct driver wiring
NaluTripician Jun 22, 2026
097ad4c
Fix docs.rs build: qualify DiagnosticsContext doc link in gate.rs
NaluTripician Jun 23, 2026
1495150
Fix cSpell failures: rename refr/overallocate/uncomputed
NaluTripician Jun 23, 2026
a6ca3c9
Format: wrap long assert after ref_req rename
NaluTripician Jun 23, 2026
7305407
Remove Off capture mode; split build vs JSON bench
NaluTripician Jun 23, 2026
5f2d983
Bound Cosmos diagnostics under retry storms
NaluTripician Jul 1, 2026
5ab4ec1
Merge remote-tracking branch 'upstream/main' into nalutripician/cosmo…
NaluTripician Jul 6, 2026
085f87f
Bound compaction runs; address storm-safe review
NaluTripician Jul 6, 2026
fa3ff28
Make Phase-2 compaction record/rollup selection coherent; harden live…
NaluTripician Jul 6, 2026
65482db
Add cosmos spellings for storm-safe diagnostics
NaluTripician Jul 6, 2026
0c0e89a
Merge upstream/main into cosmos-diagnostics-storm-safe
NaluTripician Jul 7, 2026
c626a9b
Merge branch 'main' into nalutripician/cosmos-diagnostics-storm-safe
NaluTripician Jul 7, 2026
103230f
Merge upstream/main into cosmos-diagnostics-storm-safe
NaluTripician Jul 9, 2026
9d31cbc
Merge branch 'main' into nalutripician/cosmos-diagnostics-storm-safe
NaluTripician Jul 9, 2026
0d1e474
Merge upstream/main into cosmos-diagnostics-storm-safe
NaluTripician Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions sdk/cosmos/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"ignoreWords": [
"accountname",
"activityid",
"aggregatable",
"ALPN",
"apacsoutheast",
"Appleby's",
Expand Down Expand Up @@ -219,6 +220,7 @@
"pgcosmos",
"PIDS",
"Pigw",
"pingpong",
"pinning",
"Pkrange",
"pkranges",
Expand Down Expand Up @@ -255,6 +257,7 @@
"rhost",
"RNTBD",
"rgby",
"rollup",
"roundtripped",
"roundtrips",
"RTLD",
Expand Down Expand Up @@ -305,6 +308,7 @@
"ukwest",
"unavail",
"uncollapsed",
"uncompacted",
"uncontended",
"undrained",
"unfaulted",
Expand Down Expand Up @@ -337,6 +341,10 @@
"usseceast",
"ussecwest",
"ussecwestcentral",
"varint",
"varints",
"Vecs",
"verbosities",
"vnext",
"westcentralus",
"westeurope",
Expand Down
4 changes: 2 additions & 2 deletions sdk/cosmos/azure_data_cosmos/tests/framework/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ pub fn assert_region_not_contacted(
.count();
assert_eq!(
on_region, 0,
"expected zero tracked requests on excluded region {:?}, but {} of {} requests landed there (regions contacted: {:?})",
"expected zero tracked requests on excluded region {:?}, but {} of {} retained requests landed there (regions contacted: {:?})",
excluded_region,
on_region,
diagnostics.request_count(),
requests.len(),
diagnostics.regions_contacted()
);
}
Expand Down
5 changes: 5 additions & 0 deletions sdk/cosmos/azure_data_cosmos_driver/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@

- The `User-Agent` header now advertises enabled client features (PPCB, HTTP/2) via the cross-SDK `|F<HEX>` feature-flag token, consistent with the .NET and Java Cosmos SDKs. ([#4635](https://github.com/Azure/azure-sdk-for-rust/pull/4635))
- Added support for using a native query planning library to generate query plans locally, avoiding a Gateway round-trip on cross-partition queries. Gated behind the `__internal_native_query_plan` feature flag. ([#4554](https://github.com/Azure/azure-sdk-for-rust/pull/4554))
- Added a prototype **diagnostics capture engine** (`diagnostics::capture`) behind the **off-by-default `capture_engine` feature**. It is **not** the driver's default diagnostics path: the always-on `DiagnosticsContextBuilder` continues to produce the diagnostics surfaced by `CosmosResponse::diagnostics()` with full fidelity. What ships unconditionally from this module is the **gate** β€” a `DiagnosticsPolicy` (`Threshold`/`Always`, default `Always`) plus `should_build`, evaluated at operation end to decide whether the builder-produced context is *also* exposed through the new gated accessors `CosmosResponse::capture_diagnostics()` and `CosmosError::capture_diagnostics()`. The gate never builds the surfaced context; it only governs exposure. There is no `Off` mode β€” diagnostics are always collected so that every operation stays diagnosable. Behind `capture_engine`, the engine explores a future capture-then-reconstruct path: a lock-free, pooled hot-path recorder appends to a typed, two-list **event log** (an `EventLogStorage`: `Vec<Span>` + `Vec<Attr>`) β€” recording an event is a single `Vec::push`. A `Span` carries a `kind`, an `Option<SpanId>` parent (`SpanId` is a `NonZero` index+1, so `Option<SpanId>` uses the niche), and op-relative `TimeOffset` start/end; an `Attr` is a typed key/value tagged with its `SpanId`, with `AttrValue` keeping the path allocation-light (`U64`/`F64`/first-class `Status(CosmosStatus)` plus `StaticStr(&'static str)`, `SharedStr(Arc<str>)`, owned `Str(Box<str>)`). The pooled storage is leased through an `EventLog` RAII handle that returns it to the pool on drop. Past the gate the flat lists are replayed onto a `DiagnosticsContextBuilder`; the reconstruction carries the captured per-attempt facets (pipeline type, transport security/kind, HTTP version) and the server-reported duration, reconstructed from what was recorded rather than hardcoded, and a parity harness validates it against the builder. The path stays behind the feature because the live driver pipeline does not yet feed the recorder. The public `DiagnosticsContext` type, the non-optional `response.diagnostics()` accessor, and the `azure_data_cosmos` boundary are **unchanged** (additive, non-breaking). See `DIAGNOSTICS-CAPTURE.md`.
- Added a `.NET CosmosDiagnostics`-style top-level **`summary`** block to `DiagnosticsContext` (`DiagnosticsSummary`, reachable via `DiagnosticsContext::summary()`). It aggregates over the collected requests β€” `(status, sub-status)` histogram, total request charge, request/retry/throttle counts, regions contacted, final status, top error, total elapsed, and the client **`user_agent`** (SDK + runtime identity, via `DiagnosticsSummary::user_agent()`) β€” and is **computed lazily on first access** (never on the hot path) and cached via `OnceLock`, so a context whose diagnostics are never inspected pays nothing for it. Serialized as the first section of the diagnostics output; the `user_agent` is omitted when the driver did not supply one, so existing output is unchanged.
- Added a **`DiagnosticsEncoding`** client option on `DriverOptions` (`DriverOptionsBuilder::with_diagnostics_encoding` / `DriverOptions::diagnostics_encoding`) controlling how diagnostics render to a string via the new `DiagnosticsContext::encode(encoding)` and `CosmosResponse::diagnostics_string(encoding)`: `Json` (pretty, **default** β€” output unchanged), `Compact` (minified JSON), and `Encoded` (base64 of the compact JSON, decodable, for size-sensitive logging). Additive and non-breaking.
- Added serializable **wall-clock timestamps** (RFC 3339 / ISO 8601) to the diagnostics output. `DiagnosticsContext` (and its `summary`) now carry an operation `start_time`/`end_time`, and each `RequestDiagnostics` attempt carries a `start_time` plus an optional `end_time`, captured with `azure_core::time::OffsetDateTime` alongside the existing `Instant`-based durations. These absolute timestamps let diagnostics be correlated against server-side and external logs. Additive and non-breaking: the fields exist only when a context is built, durations are unchanged, and an in-flight attempt's `end_time` is omitted (`skip_serializing_if`).
- Added **retry-storm compaction** to the always-on `DiagnosticsContext`, giving a bounded-size guarantee under 4xx/5xx retry storms. When an operation accumulates more per-attempt records than the new configurable `DiagnosticsOptions::max_request_diagnostics` cap (`DiagnosticsOptionsBuilder::with_max_request_diagnostics`, env `AZURE_COSMOS_DIAGNOSTICS_MAX_REQUESTS`, default `512`, min `16`), runs of near-identical consecutive retries (same region / endpoint / status / sub-status / execution-context) are collapsed at operation finalization into first + last + a count, with an order-robust global key-bucket fallback that keeps the retained count within the cap even under a region ping-pong. The aggregate `summary` is computed from the full attempt list *before* compaction, so the `(status, sub-status)` histogram, retry/throttle counts, total RU and regions stay exact; `DiagnosticsContext::request_count()` still reports the true total, and new accessors `DiagnosticsContext::retained_request_count()` and `DiagnosticsContext::compaction()` (returning the new `CompactionInfo` / `CompactedRun`) expose the bounded retained count and a per-run rollup. The per-run rollup and the retained list are themselves bounded so the serialized artifact stays independent of storm *cardinality* (e.g. a `410` fan-out across thousands of physical-partition endpoints): `CompactionInfo` reports `total_runs`, and `omitted_runs` / `omitted_request_count` when the rollup is capped, plus `retained_truncated` when the retained list hit the cap β€” so every drop is **explicit**, never silent. Under the global key-bucket fallback the retained records and the per-run rollup are drawn from the **same** cap-bounded set of largest runs, so every retained attempt has a matching run in the rollup (coherent for a span emitter). The bounded-size guarantee applies to the finalized serialized artifact and retained list, **not** to live mid-operation memory (the in-flight per-attempt list still grows one entry per attempt; only finalization bounds it). Detailed JSON gains a top-level `compaction` object only when compaction fires (`skip_serializing_if`), so output stays byte-identical for normal operations. Additive and non-breaking.
- Restructured the client / runtime options layering on the driver. Two new nested option groups, a per-client overrides surface on `DriverOptionsBuilder`, and a single canonical `AZURE_COSMOS_PPCB_*` namespace for partition-failover environment variables. The driver now consumes partition-failover configuration once at construction (`CosmosDriver::new` no longer fabricates an `OperationOptionsView` outside any operation context) ([#4588](https://github.com/Azure/azure-sdk-for-rust/pull/4588)):
- Added new nested `OperationOptions::throughput_control` group (`ThroughputControlOptions` / `…Builder` / `…View`, mirroring the `ThrottlingRetryOptions` pattern). Exposes three layered fields ([#4588](https://github.com/Azure/azure-sdk-for-rust/pull/4588)):
- `group_name: Option<ThroughputControlGroupName>` β€” replaces the old top-level `OperationOptions::throughput_control_group`.
Expand Down
28 changes: 28 additions & 0 deletions sdk/cosmos/azure_data_cosmos_driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ uuid = { workspace = true, features = ["v4", "fast-rng"] }

[dev-dependencies]
azure_identity.workspace = true
criterion.workspace = true
quick-xml.workspace = true
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = [
Expand Down Expand Up @@ -78,6 +79,15 @@ rustls = ["reqwest", "reqwest/rustls", "__tls"]
native_tls = ["reqwest", "reqwest/native-tls", "__tls"]
fault_injection = []
preview_dtx = [] # Enables preview Distributed Transaction APIs. Disabled by default and not production-ready.
# `capture_engine` exposes the prototype deferred, append-only diagnostics
# **capture** engine (`diagnostics::capture::{event, context, encode, pool,
# recorder}` plus `gate::finish`). It is OFF by default and is NOT
# production-ready: the shipping diagnostics path is the always-on
# `DiagnosticsContextBuilder` and the unconditional Off/Threshold/Always gate.
# The event-log engine is opt-in scaffolding for evaluating a future capture
# -> reconstruct path (see DIAGNOSTICS-CAPTURE.md). It is not covered by SemVer
# and may change or disappear at any time.
capture_engine = []
# `__internal_in_memory_emulator` exposes the in-memory query evaluator
# (`crate::query::eval`, `crate::query::value`) used by the in-memory Cosmos DB
# emulator. The evaluator intentionally trades full Cosmos parity for emulator
Expand Down Expand Up @@ -126,6 +136,11 @@ name = "multi_region_failover"
path = "tests/multi_region_failover.rs"
required-features = ["fault_injection"]

[[test]]
name = "live_storm_diagnostics"
path = "tests/live_storm_diagnostics.rs"
required-features = ["fault_injection"]

[[test]]
name = "gateway_query_plan_comparison"
path = "tests/gateway_query_plan_comparison.rs"
Expand All @@ -135,3 +150,16 @@ required-features = ["__internal_testing"]
name = "in_memory_emulator"
path = "tests/in_memory_emulator.rs"
required-features = ["__internal_in_memory_emulator"]

# The capture-engine example tests exercise `diagnostics::capture::{recorder,
# pool, finish}`, which only exist behind the off-by-default `capture_engine`
# feature.
[[test]]
name = "diagnostics_examples"
path = "tests/diagnostics_examples.rs"
required-features = ["capture_engine"]

[[bench]]
name = "diagnostics_capture"
harness = false
required-features = ["capture_engine"]
Loading
Loading