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
//! One-call observability bootstrap for Rust services.
//!
//! `telemetry-init` replaces the estate's hand-wired
//! `tracing_subscriber` + `otelkit` + `metrics-kit` init blocks (~40–80
//! lines each, six dialects) with a single fallible call that wires, in
//! estate-default shape:
//!
//! - **Logs** — `tracing_subscriber` with an `EnvFilter` (the configured
//! directive, overridden by `RUST_LOG`) and a `fmt` layer: single-line
//! JSON by default, human format for local dev.
//! - **Metrics** — a lock-free
//! [`metrics_kit::Registry`] with a cardinality budget, handed to you
//! as an [`Arc`] so hot-path handles register through it (feature
//! `metrics`, default on).
//! - **Traces** — an `opentelemetry-otlp` exporter wired as a
//! `tracing-opentelemetry` layer with `service.name`/`service.version`
//! resource attributes and parent-based ratio sampling (feature
//! `otlp`, default off).
//!
//! # Design
//!
//! - **One init, typed failure.** [`Telemetry::init`] returns
//! [`TelemetryError`]; double-initialization — the global subscriber is
//! a once-per-process resource — is [`TelemetryError::AlreadyInitialized`],
//! never a panic.
//! - **No hidden globals for metrics.** The registry is returned to the
//! caller as an [`Arc`] (the metrics-kit pattern). Only the tracing
//! subscriber is global, because that is tracing's own design.
//! - **Explicit shutdown, best-effort drop.** [`Telemetry::shutdown`] is
//! the guaranteed flush path and idempotent; [`Drop`] does a
//! best-effort flush in case teardown is forgotten.
//! - **No silent fallbacks.** Requesting [`LogFormat::Json`] without the
//! `json` feature is a configuration error, not quiet plain text.
//!
//! # Example
//!
//! ```
//! use telemetry_init::{LogFormat, Telemetry, TelemetryConfig};
//!
//! let telemetry = Telemetry::init(
//! TelemetryConfig::new("payments-api")
//! .version(env!("CARGO_PKG_VERSION"))
//! .log_format(LogFormat::Pretty)
//! .log_level("info"),
//! )?;
//!
//! tracing::info!("service started");
//!
//! telemetry.shutdown()?;
//! # Ok::<(), telemetry_init::TelemetryError>(())
//! ```
//!
//! # Metrics
//!
//! With the default `metrics` feature, [`Telemetry::metrics`] hands back
//! the registry for hot-path registration:
//!
//! ```
//! # #[cfg(feature = "metrics")]
//! # {
//! use telemetry_init::{Telemetry, TelemetryConfig};
//!
//! let telemetry = Telemetry::init(
//! TelemetryConfig::new("payments-api").metrics_budget(4096),
//! )?;
//!
//! let requests = telemetry
//! .metrics()
//! .counter("http_requests_total", "Total HTTP requests.", &[])
//! .expect("unique series name");
//! requests.inc();
//!
//! assert!(telemetry.metrics().render().contains("http_requests_total 1"));
//! telemetry.shutdown()?;
//! # }
//! # Ok::<(), telemetry_init::TelemetryError>(())
//! ```
//!
//! # Traces (feature `otlp`)
//!
//! ```rust,ignore
//! let telemetry = Telemetry::init(
//! TelemetryConfig::new("payments-api")
//! .otlp_endpoint("http://localhost:4317")
//! .sample_rate(0.1),
//! )?;
//! ```
//!
//! # Why not `otelkit::init`?
//!
//! `otelkit` v2's public API is a whole-subscriber init: `otelkit::init`
//! installs its own global subscriber and returns a flush guard. It
//! cannot compose as a layer inside this crate's single subscriber, and
//! its OTLP path ignores the log format and `RUST_LOG`. telemetry-init
//! therefore wires `opentelemetry-otlp` + `tracing-opentelemetry`
//! directly, keeping one code path for every feature combination.
//!
//! # Feature flags
//!
//! | Feature | Default | Description |
//! |----------|---------|-------------|
//! | `metrics` | yes | metrics-kit registry via [`Telemetry::metrics`] |
//! | `json` | yes | JSON log format (`LogFormat::Json`) |
//! | `otlp` | no | OTLP trace export via `opentelemetry-otlp` |
//!
//! [`Arc`]: std::sync::Arc
pub use DEFAULT_METRICS_BUDGET;
pub use ;
pub use TelemetryError;
pub use ;