Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions advanced/metrics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ All metrics are prefixed with `wa_` and emitted at the same boundaries as the ma
| `wa_recv_total` | `outcome` = `decrypted`, `duplicate`, `undecryptable`, `skmsg` | Inbound messages by decrypt outcome |
| `wa_send_total` | `kind` = `dm`, `group`, `status` | Outgoing send attempts by kind |
| `wa_retry_receipt_total` | `reason` | Retry receipts sent, by reason |
| `wa_high_retry_total` | `reason` | Retry receipts sent at the high-retry watermark (count ≥ MAX), by reason |
| `wa_retry_unknown_device_total` | `sender_type` = `primary`, `companion` | Retries from a device not in the registry, by sender type |
| `wa_retry_refused_total` | — | Retries refused at the MAX_RETRY loop guard |
| `wa_base_key_collision_total` | — | Base-key collisions that forced a fresh session |
| `wa_iq_total` | `result` = `ok`, `timeout`, `error` | IQ requests by result |
| `wa_reconnect_total` | — | Reconnect attempts |
| `wa_stream_error_total` | — | Stream errors received |
Expand Down
2 changes: 1 addition & 1 deletion advanced/observability.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Spans are grouped under a stable `wa.<area>.<op>` naming scheme so you can filte
| `wa.pair.*` | QR code and pair code authentication |
| `wa.media.*` | Upload, download, history sync, sticker packs, media conn refresh |
| `wa.receipt.*` | Receipt processing (delivered, read, played) |
| `wa.retry.*` | Retry receipt handling |
| `wa.retry.*` | Retry receipt handling; `wa.retry.handle_receipt` records a `count` field (retry depth) so storm depth is aggregable per sender |
| `wa.pdo.*` | Peer Data Operations (message recovery via primary device) |
| `wa.notif.*` | Notification dispatch (group, devices, chatstate, identity change, privacy token) |
| `wa.session.*` | Signal session establishment and crypto |
Expand Down
34 changes: 34 additions & 0 deletions changelog/2026-06-17-retry-warn-levels-and-telemetry.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: "June 17, 2026 — Retry log-level parity and observability counters"
description: "Four new wa_retry_* / wa_base_key_collision_total counters, a retry count field on the handle_receipt span, and two WARN→debug/info corrections that match WA Web's own log levels."
---

## Observability

**Retry-flow observability counters and WA Web log-level parity ([#887](https://github.com/oxidezap/whatsapp-rust/pull/887))**

### New metrics counters

Four new low-cardinality, PII-safe counters are now emitted on the retry flow when the `metrics` feature is enabled. All four compile to inlined no-ops without the feature.

| Counter | Labels | Emitted when |
|---------|--------|--------------|
| `wa_high_retry_total` | `reason` | A retry receipt is sent at the high-retry watermark (count ≥ MAX). Mirrors WA Web's `MessageHighRetryCount` WAM event (id 3132). |
| `wa_retry_unknown_device_total` | `sender_type` = `primary`, `companion` | A retry arrives from a device not in the registry. Mirrors WA Web's `MdRetryFromUnknownDevice` WAM event (id 2178). |
| `wa_retry_refused_total` | — | A retry is refused at the MAX_RETRY loop guard. Turns a chronically thrashing peer into an aggregate health signal instead of requiring log scraping. |
| `wa_base_key_collision_total` | — | A base-key collision forced a fresh session. |

### Tracing span field

`wa.retry.handle_receipt` now records a `count` field (the retry depth for that receipt). This makes retry storm depth aggregable per sender even when the MAX_RETRY cap causes an early return.

### Log-level corrections

Two retry-path `warn!` calls that fired for benign, remote-driven, fully-handled conditions are now emitted at levels matching WA Web's own `WALogger.LOG` (informational):

- **"Refusing retry #N … exceeds max attempts"**: `warn!` → `debug!`. WA Web's `WAWebHandleRetryRequest` uses `LOG` (level 2) for this refusal and reserves `WARN` for real errors (no-requester, device-not-found). The mirror receive-side capped-retry path in `message/retry.rs` already logged at `debug!`.
- **"Base key collision detected …"**: `warn!` → `info!`. WA Web's `WAWebUpdateLocalSignalSession` uses `LOG` for the same-base-key session delete, and the three sibling branches of `update_local_signal_session` already log at `info`.

Both lines now also include the `message_id` so collisions are correlatable to a specific message during a retry storm.

**No behavior change.** Every modification is a log level, an added log field, a counter increment, or a span field. The retry logic (cap value, base-key save/compare/delete, recovery path) is verbatim parity with the WA Web oracle and is untouched.
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
"group": "Changelog",
"pages": [
"changelog/overview",
"changelog/2026-06-17-retry-warn-levels-and-telemetry",
"changelog/2026-06-15-token-tiny-map",
"changelog/2026-06-14-drop-moka-portable-cache",
"changelog/2026-06-12-binary-size-ci",
Expand Down