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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! # FastMetrics
//!
//! [][actions]
//! [][docs.rs]
//! [][crates.io]
//! [][crates.io]
//! [][crates.io]
//! [][whatrustisit]
//! [][deepwiki]
//!
//! [actions]: https://github.com/koushiro/fastmetrics/actions
//! [docs.rs]: https://docs.rs/fastmetrics
//! [crates.io]: https://crates.io/crates/fastmetrics
//! [whatrustisit]: https://www.whatrustisit.com
//! [deepwiki]: https://deepwiki.com/koushiro/fastmetrics
//!
//! OpenMetrics / Prometheus client library for Rust.
//!
//! A pure-Rust implementation of the [OpenMetrics] specification for transmitting cloud-native
//! metrics at scale, and it's compatible with [Prometheus].
//!
//! ## Features
//!
//! - Full support for [OpenMetrics] specification
//! - Fast encoding in both text and protobuf exposition format
//! - Text
//! - Prometheus text: `0.0.4`, `1.0.0`
//! - OpenMetrics text: `0.0.1`, `1.0.0`
//! - V1 escaping schemes: `allow-utf-8`, `underscores`, `dots`, `values`
//! - Protobuf
//! - [Prometheus protobuf schema]
//! - [OpenMetrics protobuf schema]
//! - Customizable metric types (currently a set of commonly used metric types are provided)
//! - Hierarchical metric organization with namespaces and subsystems
//! - Support for variable and constant labels
//! - Derive macros to simplify code (e.g., like registering metrics, label handling, etc.)
//!
//! [Prometheus]: https://prometheus.io
//! [OpenMetrics]: https://github.com/prometheus/OpenMetrics/blob/main/specification/OpenMetrics.md
//! [Prometheus protobuf schema]: https://github.com/prometheus/client_model/blob/master/io/prometheus/client/metrics.proto
//! [OpenMetrics protobuf schema]: https://github.com/prometheus/OpenMetrics/blob/main/proto/openmetrics_data_model.proto
//!
//! ## Example
//!
//! ```rust
//! use fastmetrics::{
//! encoder::{EncodeLabel, EncodeLabelSet, EncodeLabelValue, LabelSetEncoder, LabelEncoder},
//! error::Result,
//! format::text::{self, TextProfile},
//! metrics::{counter::Counter, family::Family},
//! raw::LabelSetSchema,
//! registry::Registry,
//! };
//!
//! #[derive(Clone, Eq, PartialEq, Hash)]
//! struct Labels {
//! method: Method,
//! status: u16,
//! }
//!
//! // Can use `#[derive(LabelSet)]` or `#[derive(EncodeLabelSet, LabelSetSchema)]`
//! // to simplify the code, but need to enable `derive` feature
//!
//! impl LabelSetSchema for Labels {
//! fn names() -> Option<&'static [&'static str]> {
//! Some(&["method", "status"])
//! }
//! }
//!
//! impl EncodeLabelSet for Labels {
//! fn encode(&self, encoder: &mut dyn LabelSetEncoder) -> Result<()> {
//! encoder.encode(&("method", &self.method))?;
//! encoder.encode(&("status", &self.status))?;
//! Ok(())
//! }
//! }
//!
//! #[derive(Clone, Eq, PartialEq, Hash)]
//! enum Method {
//! Get,
//! Put,
//! }
//!
//! // Can use `#[derive(EncodeLabelValue)]` to simplify the code, but need to enable `derive` feature
//! impl EncodeLabelValue for Method {
//! fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
//! match self {
//! Self::Get => encoder.encode_str_value("Get"),
//! Self::Put => encoder.encode_str_value("Put"),
//! }
//! }
//! }
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Create a registry with a namespace and some constant labels
//! let mut registry = Registry::builder()
//! .with_namespace("myapp")
//! .with_const_labels([("env", "prod")])
//! .build()?;
//!
//! // Register a simple counter
//! let requests = <Counter>::default();
//! registry.register("requests", "Total requests processed", requests.clone())?;
//!
//! // Register a counter metric family for tracking requests with labels
//! let http_requests = Family::<Labels, Counter>::default();
//! registry.register(
//! "http_requests",
//! "Total HTTP requests",
//! http_requests.clone()
//! )?;
//!
//! // Update the simple counter
//! requests.inc();
//! assert_eq!(requests.total(), 1);
//!
//! // Update the counter family
//! let labels = Labels { method: Method::Get, status: 200 };
//! http_requests.with_or_new(&labels, |req| req.inc());
//! assert_eq!(http_requests.with(&labels, |req| req.total()), Some(1));
//!
//! // Export metrics in text format
//! let mut output = String::new();
//! text::encode(&mut output, ®istry, TextProfile::default())?;
//! // println!("{}", output);
//! assert!(output.contains(r#"myapp_http_requests_total{env="prod",method="Get",status="200"} 1"#));
//! # Ok(())
//! # }
//! ```
// Enforce platform requirements without interfering with crate-level inner docs (`//!`).
// This must live after the crate docs block.
compile_error!;
pub use fastmetrics_derive as derive;