Upstream pool connectivity and failover observability via monitoring API and Prometheus metrics #463
gimballock
started this conversation in
Ideas
Replies: 1 comment
No hard opinions for the other questions |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Motivation
Operators running Translator Proxy (or JD Client) against one or more upstream pools currently have no observability into the state of those upstream connections. When the Translator falls back from one pool to another (via
FallbackCoordinator), the only signal today is log output. There is no API or metric that answers:This makes it difficult to build dashboards that show upstream routing state, trigger alerts on failover events, or validate post-failover health — all of which are standard operational requirements for production mining deployments.
Use Cases
Failover dashboards — An operator running Translator against a primary and secondary pool needs a panel showing which pool is active, with color-coded health status. The sv2-ui currently infers connection health from
/healthendpoint reachability, but has no way to show which upstream pool is active or that a failover has occurred.Alerting on upstream disconnection — If all configured upstream pools become unreachable, this is a P1 event. Today there is no metric to trigger on — you'd have to parse logs or wait for
sv2_server_shares_accepted_totalto flatline.Failover event audit trail — After an incident, operators need to know how many failovers occurred, what time they happened, and whether the system converged back to the primary. A simple counter + timestamp would enable this.
Connection failure diagnostics — Distinguishing between "pool is down" and "noise handshake failed" or "auth rejected" requires per-pool failure visibility. Reason-level detail could potentially be addressed by a general recently-seen-errors mechanism (if that concept moves forward) rather than requiring dedicated per-reason counters here.
Multi-pool health comparison — In deployments with 2+ upstream pools, operators want to see per-pool share acknowledgement rates side-by-side to detect a degraded (but not dead) pool.
Current Internal State
The building blocks are already present in the codebase:
FallbackCoordinator(stratum-apps/src/fallback_coordinator.rs) — Orchestrates fallback: triggers cancellation, waits for all registered components to complete cleanup, then a new coordinator is instantiated for the next cycle. This struct knows when a fallback is triggered but doesn't persist any statistics.Translator's status loop (
miner-apps/translator/src/lib/mod.rs) — CatchesState::UpstreamShutdown, triggers fallback, then callsinit_upstreams()which iterates through the upstream list with retries. This loop knows which pool address it's connecting to and whether each attempt succeeded or failed, but this information is not surfaced to the monitoring layer.ServerMonitoringtrait (stratum-apps/src/monitoring/server.rs) — Currently reports per-channel share stats and hashrate for the connected upstream. It does not report which upstream is connected or any connection lifecycle events.Design Parameters
Following the project's established monitoring philosophy:
No code-site counters or histograms — All new state should be tracked in internal data structures and exposed as Gauges (point-in-time snapshots) by the monitoring layer, consistent with the existing pattern.
API-first, then Prometheus — New fields should appear in the JSON API structs first (e.g.,
ServerInfoor a newUpstreamInfo), then be wired to Prometheus gauges insnapshot_cache.rsandprometheus_metrics.rs.Minimal core-logic changes — The state tracking should be concentrated in the coordination/status layer, not scattered across protocol handlers.
Label cardinality — Upstream pool addresses are low-cardinality (typically 1-3 per Translator instance), so per-pool labels are safe.
Proposed Data to Expose
These are suggestions for discussion — the specific struct layout and naming should be decided by the community.
Option A: Extend
ServerMonitoring/ServerInfoAdd fields to the existing server monitoring structs:
This would flow through the existing
ServerMonitoringtrait →SnapshotCache→ API + Prometheus path.Prometheus gauges derived from this:
sv2_upstream_connectedpool_addresssv2_upstream_failbacks_totalsv2_upstream_connection_failures_totalpool_addresssv2_upstream_last_fallback_timestampOption B: Separate
UpstreamMonitoringtraitIf the community prefers to keep
ServerMonitoringfocused on per-channel share/hashrate data, a new trait could be introduced:This would be optionally composed into
MonitoringServeralongside the existing traits.Questions for the Community
Scope — Should this cover only Translator, or also JD Client (which has a similar upstream connection pattern)?
Failure reasons — Should
connection_failurescarry a reason label (e.g.,noise_handshake,auth,timeout,protocol_error), or is a simple per-address count sufficient? Labeling by reason is more useful for debugging but adds complexity.Trait placement — Option A (extend
ServerMonitoring) vs Option B (new trait)? Option A is simpler; Option B is cleaner separation.Pool address format — Should the label be the raw config address string (e.g.,
pool.example.com:3333), or a normalized identifier?Relationship to recently-seen-errors — If a general error-window mechanism is added (as discussed elsewhere), should upstream connection failures feed into that instead of having dedicated counters?
References
stratum-apps/src/monitoring/— existing monitoring modulestratum-apps/src/fallback_coordinator.rs— fallback orchestrationminer-apps/translator/src/lib/mod.rs— Translator status loop with fallback handlingminer-apps/translator/src/lib/sv2/upstream/mod.rs— upstream connection managementAll reactions