From 8a5454cbe24fff5a0c783934d6069e2a826a0f6c Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Fri, 17 Jul 2026 15:10:08 +0300 Subject: [PATCH] docs(metrics): note the two-seam overlap hazard in the truth-home MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit architecture/metrics.md §Two-seam layering framed the recorder and native middleware as purely complementary, omitting that they overlap on the consume/publish series: both emit the same-named duration+count metrics, so one Prometheus registry raises Duplicated timeseries and live OTel meters on both double-count. Record the hazard, the separate-registries / middleware-as-source- of-truth fix, and why the library does not guard it at construction (the collision is raised upstream of the broker, and "both seams configured" is indistinguishable from the correct dual-registry setup). Cross-refs the setup doc, which already covers the operator side. Closes the last open item from the architecture review (candidate #7). Docs only. Co-Authored-By: Claude Opus 4.8 (1M context) --- architecture/metrics.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/architecture/metrics.md b/architecture/metrics.md index 3c5d8ed..ae9344b 100644 --- a/architecture/metrics.md +++ b/architecture/metrics.md @@ -58,3 +58,5 @@ Middleware and recorder are complementary, not redundant. Middleware owns `consu - `nacked_terminal(reason="max_deliveries")` — fires before consume opens Each seam fires for events the other physically cannot observe. Don't collapse them. + +**But they overlap on the bus-scope series.** Complementary is not the whole story: the recorder adapters (`PrometheusRecorder` / `OpenTelemetryRecorder`) and the native middleware both emit the consume/publish duration+count series under the *same* names (the recorders mirror upstream verbatim). Registering both against one Prometheus `CollectorRegistry` raises `Duplicated timeseries` — at whichever seam the user constructs *second*, upstream of the broker — and on OpenTelemetry, live meters on both **double-count** every consume/publish. A both-seams deployment must give them **separate registries** and treat the **middleware as the source of truth** for consume/publish (run the OTel middleware span-only). The library does **not** guard this at construction: the Prometheus collision is raised before the broker sees either seam, and "both seams configured" is indistinguishable from the correct dual-registry setup, so a guard would false-positive on the recommended configuration. It stays an operator concern — see `docs/usage/setup-prometheus-opentelemetry.md`.