Skip to content

Commit f63795f

Browse files
Add OTEL metrics guide (#64)
1 parent 02ab5f7 commit f63795f

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

src/usage/metrics.rs

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
//! # Exporting OpenTelemetry Metrics from Rust to Logfire
2+
//!
3+
//! This guide shows how to export OpenTelemetry metrics from Rust applications to Logfire and use them for creating dashboards and monitoring.
4+
//!
5+
//! ## Overview
6+
//!
7+
//! The Logfire Rust SDK provides built-in support for OpenTelemetry metrics through its metrics API. Metrics are automatically exported to Logfire alongside traces and logs, giving you comprehensive observability for your Rust applications.
8+
//!
9+
//! ## Prerequisites
10+
//!
11+
//! 1. **Set up a Logfire project** at [logfire.pydantic.dev](https://logfire.pydantic.dev/docs/#logfire)
12+
//! 2. **Create a write token** following the [token creation guide](https://logfire.pydantic.dev/docs/how-to-guides/create-write-tokens/)
13+
//! 3. **Set the environment variable**: `export LOGFIRE_TOKEN=your_token_here`
14+
//!
15+
//! ## Available Metric Types
16+
//!
17+
//! The Logfire SDK supports all OpenTelemetry metric types:
18+
//!
19+
//! ### Counters
20+
//!
21+
//! Monotonically increasing values (e.g., request counts, error counts):
22+
//!
23+
//! ```rust
24+
//! use std::sync::LazyLock;
25+
//! use opentelemetry::metrics::Counter;
26+
//!
27+
//! // For counting discrete events
28+
//! static HTTP_REQUESTS: LazyLock<Counter<u64>> = LazyLock::new(|| {
29+
//! logfire::u64_counter("http_requests_total")
30+
//! .with_description("Total HTTP requests")
31+
//! .with_unit("{request}")
32+
//! .build()
33+
//! });
34+
//!
35+
//! // For floating-point measurements
36+
//! static DATA_PROCESSED: LazyLock<Counter<f64>> = LazyLock::new(|| {
37+
//! logfire::f64_counter("data_processed_bytes")
38+
//! .with_description("Total bytes processed")
39+
//! .with_unit("By")
40+
//! .build()
41+
//! });
42+
//! ```
43+
//!
44+
//! ### Gauges
45+
//!
46+
//! Current state values that can go up or down:
47+
//!
48+
//! ```rust
49+
//! use std::sync::LazyLock;
50+
//! use opentelemetry::metrics::Gauge;
51+
//!
52+
//! static ACTIVE_CONNECTIONS: LazyLock<Gauge<u64>> = LazyLock::new(|| {
53+
//! logfire::u64_gauge("active_connections")
54+
//! .with_description("Number of active connections")
55+
//! .with_unit("{connection}")
56+
//! .build()
57+
//! });
58+
//!
59+
//! static CPU_USAGE: LazyLock<Gauge<f64>> = LazyLock::new(|| {
60+
//! logfire::f64_gauge("cpu_usage_percent")
61+
//! .with_description("CPU usage percentage")
62+
//! .with_unit("%")
63+
//! .build()
64+
//! });
65+
//! ```
66+
//!
67+
//! ### Histograms
68+
//!
69+
//! Distribution of values (e.g., request durations, response sizes):
70+
//!
71+
//! ```rust
72+
//! use std::sync::LazyLock;
73+
//! use opentelemetry::metrics::Histogram;
74+
//!
75+
//! static REQUEST_DURATION: LazyLock<Histogram<f64>> = LazyLock::new(|| {
76+
//! logfire::f64_histogram("http_request_duration")
77+
//! .with_description("HTTP request duration")
78+
//! .with_unit("s")
79+
//! .build()
80+
//! });
81+
//!
82+
//! static RESPONSE_SIZE: LazyLock<Histogram<u64>> = LazyLock::new(|| {
83+
//! logfire::u64_histogram("http_response_size")
84+
//! .with_description("HTTP response size")
85+
//! .with_unit("By")
86+
//! .build()
87+
//! });
88+
//! ```
89+
//!
90+
//! ### Up/Down Counters
91+
//!
92+
//! Values that can increase or decrease:
93+
//!
94+
//! ```rust
95+
//! use std::sync::LazyLock;
96+
//! use opentelemetry::metrics::UpDownCounter;
97+
//!
98+
//! static QUEUE_SIZE: LazyLock<UpDownCounter<i64>> = LazyLock::new(|| {
99+
//! logfire::i64_up_down_counter("queue_size")
100+
//! .with_description("Current queue size")
101+
//! .with_unit("{item}")
102+
//! .build()
103+
//! });
104+
//! ```
105+
//!
106+
//! ## Observable Metrics
107+
//!
108+
//! For metrics that need to be sampled periodically rather than recorded on-demand:
109+
//!
110+
//! ```rust
111+
//! use std::sync::LazyLock;
112+
//! use opentelemetry::metrics::ObservableGauge;
113+
//!
114+
//! static MEMORY_USAGE: LazyLock<ObservableGauge<u64>> = LazyLock::new(|| {
115+
//! logfire::u64_observable_gauge("memory_usage_bytes")
116+
//! .with_description("Current memory usage")
117+
//! .with_unit("By")
118+
//! .with_callback(|observer| {
119+
//! // Get current memory usage (example)
120+
//! let memory_usage = get_memory_usage();
121+
//! observer.observe(memory_usage, &[]);
122+
//! })
123+
//! .build()
124+
//! });
125+
//!
126+
//! fn get_memory_usage() -> u64 {
127+
//! // Implementation to get actual memory usage
128+
//! 1024 * 1024 * 100 // Example: 100MB
129+
//! }
130+
//! ```
131+
//!
132+
//! ## Examples
133+
//!
134+
//! For examples using these metrics, see the [examples directory][crate::usage::examples].
135+
//!
136+
//! ## Using Metrics in Logfire Dashboards
137+
//!
138+
//! Once your metrics are being exported to Logfire, you can create dashboards and alerts:
139+
//!
140+
//! ### 1. **View Metrics in Logfire**
141+
//!
142+
//! - Navigate to your Logfire project dashboard
143+
//! - Go to the ["Explore"](https://logfire.pydantic.dev/docs/guides/web-ui/explore/) view
144+
//! - Run `select * from metrics` to view all incoming metrics from your application
145+
//!
146+
//! ## Best Practices
147+
//!
148+
//! 1. **Use Static Variables**: Define metrics as static variables with `LazyLock` for efficiency
149+
//! 2. **Meaningful Names**: Use descriptive metric names following OpenTelemetry conventions
150+
//! 3. **Consistent Labels**: Use consistent label names across related metrics
151+
//! 4. **Appropriate Units**: Specify units (seconds, bytes, requests) for better dashboard formatting
152+
//! 5. **Documentation**: Add descriptions to help with dashboard creation
153+
//! 6. **Label Cardinality**: Be careful with high-cardinality labels (e.g., user IDs) - prefer aggregated metrics
154+
//!
155+
//! ## Troubleshooting
156+
//!
157+
//! ### Metrics Not Appearing
158+
//!
159+
//! - Verify `LOGFIRE_TOKEN` is set correctly
160+
//! - Check that metrics are being recorded (add debug logging)
161+
//! - Ensure the application runs long enough for metrics to be exported
162+
//!
163+
//! ### Performance Issues
164+
//!
165+
//! - Monitor label cardinality - too many unique label combinations can impact performance
166+
//! - Use histograms instead of gauges for distributions
167+
//! - Consider sampling for high-frequency metrics
168+
//!
169+
//! ### Dashboard Issues
170+
//!
171+
//! - Check metric names match exactly (case-sensitive)
172+
//! - Verify time ranges in queries
173+
//! - Use Logfire's query builder to test metric availability
174+
//!
175+
//! This guide provides a complete foundation for implementing metrics in your Rust applications and visualizing them in Logfire dashboards.

src/usage/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,4 @@
9797
//! See [examples] subchapter of this documentation.
9898
9999
pub mod examples;
100+
pub mod metrics;

0 commit comments

Comments
 (0)