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
113
114
115
116
117
118
119
120
121
122
123
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/destination `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.
/// `pub(crate)` so `import` (ADR-0102) can reuse it for `destination_bucket`
/// on `pigeon_upload_*`, which has no `BucketConfig` on either side.
pub 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. transform's
/// transcode step uses "transcoded"/"copied_through", 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.
///
/// That guarantee is a precondition, not a given: a job whose pipeline
/// pushes each file as soon as it is ready (`transform`, ADR-0116) has no
/// such transition -- it is still downloading the last file while the first
/// is already pushed -- so it deliberately does not emit this gauge at all
/// (ADR-0130) rather than report a transition that never happened as
/// described. `pigeon_job_phase_total` is the right instrument for those
/// jobs; only call this one where ADR-0019's ordering actually holds.
pub