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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use ;
use PrometheusBuilder;
/// Overrides the default port for the local Prometheus metrics endpoint --
/// mirrors `PIGEON_LOG_DIR`'s precedent (ADR-0073), for the same reason:
/// letting an on-host agent (e.g. Grafana Alloy, ADR-0092) and manual/test
/// use pin a known value without a CLI flag.
pub const METRICS_PORT_ENV_VAR: &str = "PIGEON_METRICS_PORT";
const DEFAULT_PORT: u16 = 9091;
/// `--metrics-port` if given, else `$PIGEON_METRICS_PORT`, else `9091`.
/// Installs the global Prometheus recorder, exposing a pull-based
/// `/metrics` endpoint on localhost for an on-host observability agent
/// (e.g. Grafana Alloy) to scrape and forward to Scaleway Cockpit
/// (ADR-0092). Installed once for the whole process, regardless of which
/// command runs -- cheaper and simpler than threading a port through every
/// job wizard to scope it to job commands only (the way `ResourceSampler`
/// is scoped), and a keyring command binding an unused listener for a few
/// milliseconds costs nothing. Binding failure (e.g. two `pigeon`
/// invocations racing for the same port) is non-fatal: metrics are an
/// observability nicety, never worth failing a command over (same posture
/// as ADR-0068's best-effort IMAP logout).
/// No source `BucketConfig` is in scope at this call site (e.g. an IMAP- or
/// local-dir-sourced job, or a post-download pass operating on already
/// -staged local files) -- the label is always present (ADR-0097), just
/// with this sentinel value, so the metric's label set stays fixed.
const NO_BUCKET: &str = "n/a";
/// Records one item completing one phase of a job's pipeline, live, at the
/// exact moment it happens (ADR-0093) -- labeled `pigeon_job` (not `job`,
/// which Alloy's Prometheus scrape config already reserves to identify the
/// *scrape target* once every instance shares one Cockpit store; colliding
/// with it would silently relabel this as `exported_job`). `phase` reuses
/// each job's existing `FailureBreakdown` field names (e.g. deduplicate's
/// "download"/"hash"/"place"); `outcome` matches that phase's real semantics
/// rather than a forced success/failure binary (e.g. pull_transform's
/// recode step uses "recoded"/"fallback", email_pull's attachment step
/// uses "extracted"/"extraction_failed" since that still counts as synced
/// in the job's own model). Supersedes ADR-0092's `record_job_summary`,
/// which only ever reported once at the very end of a run -- a dashboard
/// built on that never showed anything mid-run. A job's running totals are
/// `sum by (pigeon_job, outcome) (pigeon_job_phase_total{pigeon_job="..."})`.
/// `source_bucket` (ADR-0097) is `Some(alias)` when a source `BucketConfig`
/// is already in scope at the call site, `None` otherwise (see `NO_BUCKET`).
pub
/// Same as `record_phase`, but for a site that already knows it's
/// reporting for several items at once (e.g. email_sync/email_pull's
/// connect/examine/batch failures, each counted per UID in the batch
/// rather than per individual item) -- avoids looping just to call
/// `record_phase` once per UID.
pub
/// Macro-phase indicator for `job`: `0` while local work (download/process/
/// hash/classify/placement -- all pipelined, no single one of them is "the"
/// current phase at any instant) is in progress, `1` once the job has moved
/// into its upload phase. ADR-0019 guarantees this is a real, one-way
/// transition -- upload never starts until all local work is done -- so
/// unlike a per-item phase, a single gauge is an accurate fit here.
pub