metriki_r2d2/lib.rs
1//! # Metriki Instrumentation for r2d2
2//!
3//! This library provides extensions for r2d2, which is generic
4//! database connection pool library, to measure performance for
5//! database applications.
6//!
7//! It provides following metriki metrics:
8//!
9//! * `r2d2.checkout`: A meter records the rate of your application
10//! borrowing connection from the pool
11//! * `r2d2.wait`: A histogram summarizes the distribution of time
12//! spent on borrowing connection from the pool
13//! * `r2d2.timeout`: A meter records the error rate of timeout
14//! borrowing connection
15//! * `r2d2.usage`: A histogram summarizes the distribution of time
16//! for using the connection. Typically this is the time spent to
17//! query your database.
18//!
19//! ## Usage
20//!
21//! Add MetrikiHandler as `r2d2::Builder`
22//!
23//! ```rust,ignore
24//! // Create metriki event handler from metriki global registry
25//! let metriki_handler = MetrikiHandlerBuilder::default()
26//! .registry(global_registry())
27//! .build()
28//! .unwrap();
29//!
30//! let manager = r2d2_foodb::FooConnectionManager::new("localhost:1234");
31//! let pool = r2d2::Pool::builder()
32//! .max_size(15)
33//! // set event handler to the builder
34//! .event_handler(Box::new(metriki_handler))
35//! .build(manager)
36//! .unwrap();
37//! ```
38//!
39//! ## diesel Support
40//!
41//! The Rust ORM library diesel has an re-exported version of r2d2. By
42//! enabling `diesel` feature of `metriki-r2d2`, it will work with the
43//! diesel variant.
44//!
45//! ## Customization
46//!
47//! The metric name prefix `r2d2` can be customized with
48//! `MetrikiHandlerBuilder` by setting `name`. This is required when
49//! you have multiple r2d2 pools in your application.
50//!
51use std::sync::Arc;
52
53use derive_builder::Builder;
54#[cfg(not(feature = "diesel"))]
55use r2d2::{
56 event::{CheckinEvent, CheckoutEvent, TimeoutEvent},
57 HandleEvent,
58};
59
60#[cfg(feature = "diesel")]
61use diesel::r2d2::{
62 event::{CheckinEvent, CheckoutEvent, TimeoutEvent},
63 HandleEvent,
64};
65
66use metriki_core::MetricsRegistry;
67
68// The r2d2 EventHandler that tracks usage of the database connection
69// and its connection pool.
70#[derive(Debug, Builder)]
71pub struct MetrikiHandler {
72 registry: Arc<MetricsRegistry>,
73 #[builder(setter(into), default = "\"r2d2\".to_owned()")]
74 name: String,
75}
76
77impl HandleEvent for MetrikiHandler {
78 fn handle_checkout(&self, event: CheckoutEvent) {
79 self.registry
80 .meter(&format!("{}.checkout", self.name))
81 .mark();
82 self.registry
83 .histogram(&format!("{}.wait", self.name))
84 .update(event.duration().as_millis() as u64);
85 }
86
87 fn handle_timeout(&self, _event: TimeoutEvent) {
88 self.registry
89 .meter(&format!("{}.timeout", self.name))
90 .mark();
91 }
92
93 fn handle_checkin(&self, event: CheckinEvent) {
94 self.registry
95 .histogram(&format!("{}.usage", self.name))
96 .update(event.duration().as_millis() as u64);
97 }
98}