1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! Prometheus metrics for scheduled ingress sources (#573).
//!
//! Emitted through the lightweight [`metrics`] facade — the same mechanism
//! `fraiseql-wire` uses for its per-entity counters and histograms, and the only
//! idiom in the workspace that natively supports the per-source labels and the
//! run-duration histogram a source needs. Emissions are captured by the global
//! Prometheus recorder installed at startup
//! ([`crate::metrics_recorder`]) and appended to the `/metrics` endpoint, so
//! **they surface only when the server is built with the `metrics` feature and
//! metrics are enabled** (the same boundary as the wire metrics). The macro calls
//! themselves are cheap no-ops when no recorder is installed, so this module needs
//! no feature gate of its own.
//!
//! Three metrics, all driven from [`SourcePoller::fire_once`](super::SourcePoller):
//!
//! - `fraiseql_source_fires_total{source, result}` — a source firing that ran to completion
//! (`result="ok"`) or whose connector returned an error (`result="error"`). A failed firing
//! re-runs from the last committed cursor on the next tick (at-least-once), so `result="error"`
//! is the source-failure signal — there is no separate source dead-letter queue.
//! - `fraiseql_source_skips_not_leader_total{source}` — a tick this replica skipped because another
//! replica held the single-firing lease. The fleet-wide health of the cross-replica coordination.
//! - `fraiseql_source_run_duration_seconds{source}` — wall-clock of a firing that ran (skips are
//! not recorded — a skip is near-instant and not a run).
use ;
/// `fraiseql_source_fires_total{source, result}` — firings that ran, by outcome.
const FIRES_TOTAL: &str = "fraiseql_source_fires_total";
/// `fraiseql_source_skips_not_leader_total{source}` — ticks skipped (not leader).
const SKIPS_NOT_LEADER_TOTAL: &str = "fraiseql_source_skips_not_leader_total";
/// `fraiseql_source_run_duration_seconds{source}` — run wall-clock, seconds.
const RUN_DURATION_SECONDS: &str = "fraiseql_source_run_duration_seconds";
/// The `result` label for a firing that ran: the connector completed.
pub const RESULT_OK: &str = "ok";
/// The `result` label for a firing that ran but whose connector returned an error.
pub const RESULT_ERROR: &str = "error";
/// Record that `source` fired and ran to completion with the given `result`
/// (`"ok"` or `"error"`), taking `duration_seconds` of wall-clock.
///
/// One call covers both the fire counter and the run-duration histogram — the two
/// only ever move together (a run has an outcome and a duration), so pairing them
/// keeps the caller from recording one without the other.
/// Record that `source` skipped a tick because another replica held the lease.