ff_observability/lib.rs
1//! FlowFabric observability — OTEL metrics registry + typed handles.
2//!
3//! This crate is the single place that touches OpenTelemetry / Prometheus.
4//! Consumers (`ff-server`, `ff-engine`, `ff-scheduler`) take an optional dep
5//! on `ff-observability` behind their own `observability` feature; enabling
6//! the consumer-feature transitively enables `ff-observability/enabled`.
7//!
8//! ## Feature model
9//!
10//! * `enabled` **off** (default) — all types compile to zero-cost no-op
11//! shims. No OTEL / Prometheus crates in the dep tree. Call sites use
12//! the same `Metrics::new()` entry point as the real backend; every
13//! instrument method is a no-op.
14//! * `enabled` **on** — real OTEL `MeterProvider` + Prometheus exporter.
15//! `Metrics::new()` registers all instruments; [`Metrics::render`]
16//! returns the text-exposition body for `/metrics`.
17//!
18//! Call sites under both features use **identical call shape** — that's
19//! the whole point of the indirection. If the shim ever grew a feature
20//! skew we'd lose the "same source compiles both ways" guarantee.
21
22#![forbid(unsafe_code)]
23
24#[cfg(feature = "enabled")]
25mod real;
26#[cfg(not(feature = "enabled"))]
27mod shim;
28
29#[cfg(feature = "enabled")]
30pub use real::Metrics;
31#[cfg(not(feature = "enabled"))]
32pub use shim::Metrics;
33
34/// Terminal attempt outcome label for `ff_attempt_outcome_total`.
35///
36/// The variant set is fixed at 5 by the Observability RFC prereq #4
37/// adjudication so cardinality stays bounded at `5 × N lanes`. Kept
38/// feature-agnostic (defined here, not in `real`/`shim`) so call sites
39/// can construct the value identically whether metrics are compiled in
40/// or not.
41#[derive(Clone, Copy, Debug, PartialEq, Eq)]
42pub enum AttemptOutcome {
43 /// Attempt completed successfully (terminal-ok / `complete` FCALL).
44 Ok,
45 /// Attempt failed terminally — no retries left.
46 Error,
47 /// Attempt failed with classification = `Timeout`.
48 Timeout,
49 /// Attempt was cancelled (worker or flow-level cancel).
50 Cancelled,
51 /// Attempt failed but a retry was scheduled.
52 Retry,
53}
54
55impl AttemptOutcome {
56 /// Stable `&'static str` label — matches the Prometheus exposition.
57 pub fn as_stable_str(&self) -> &'static str {
58 match self {
59 AttemptOutcome::Ok => "ok",
60 AttemptOutcome::Error => "error",
61 AttemptOutcome::Timeout => "timeout",
62 AttemptOutcome::Cancelled => "cancelled",
63 AttemptOutcome::Retry => "retry",
64 }
65 }
66}
67
68// Sentry error-reporting module. Gated behind the `sentry` feature,
69// orthogonal to `enabled` (OTEL metrics) — consumers can turn either
70// on without pulling the other. See [`sentry`] module docs for the
71// env-var contract and usage.
72#[cfg(feature = "sentry")]
73pub mod sentry;
74
75#[cfg(feature = "sentry")]
76pub use sentry::{init_sentry, tracing_layer as sentry_tracing_layer};