libp2p_metrics/
lib.rs

1// Copyright 2021 Protocol Labs.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21//! Auxiliary crate recording protocol and Swarm events and exposing them as
22//! metrics in the [OpenMetrics] format.
23//!
24//! [OpenMetrics]: https://github.com/OpenObservability/OpenMetrics/
25//!
26//! See `examples` directory for more.
27
28#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
29
30mod bandwidth;
31#[cfg(feature = "dcutr")]
32mod dcutr;
33#[cfg(feature = "gossipsub")]
34mod gossipsub;
35#[cfg(feature = "identify")]
36mod identify;
37#[cfg(feature = "kad")]
38mod kad;
39#[cfg(feature = "ping")]
40mod ping;
41mod protocol_stack;
42#[cfg(feature = "relay")]
43mod relay;
44mod swarm;
45
46pub use bandwidth::Transport as BandwidthTransport;
47pub use prometheus_client::registry::Registry;
48
49/// Set of Swarm and protocol metrics derived from emitted events.
50pub struct Metrics {
51    #[cfg(feature = "dcutr")]
52    dcutr: dcutr::Metrics,
53    #[cfg(feature = "gossipsub")]
54    gossipsub: gossipsub::Metrics,
55    #[cfg(feature = "identify")]
56    identify: identify::Metrics,
57    #[cfg(feature = "kad")]
58    kad: kad::Metrics,
59    #[cfg(feature = "ping")]
60    ping: ping::Metrics,
61    #[cfg(feature = "relay")]
62    relay: relay::Metrics,
63    swarm: swarm::Metrics,
64}
65
66impl Metrics {
67    /// Create a new set of Swarm and protocol [`Metrics`].
68    ///
69    /// ```
70    /// use libp2p_metrics::Metrics;
71    /// use prometheus_client::registry::Registry;
72    /// let mut registry = Registry::default();
73    /// let metrics = Metrics::new(&mut registry);
74    /// ```
75    pub fn new(registry: &mut Registry) -> Self {
76        let sub_registry = registry.sub_registry_with_prefix("libp2p");
77        Self {
78            #[cfg(feature = "dcutr")]
79            dcutr: dcutr::Metrics::new(sub_registry),
80            #[cfg(feature = "gossipsub")]
81            gossipsub: gossipsub::Metrics::new(sub_registry),
82            #[cfg(feature = "identify")]
83            identify: identify::Metrics::new(sub_registry),
84            #[cfg(feature = "kad")]
85            kad: kad::Metrics::new(sub_registry),
86            #[cfg(feature = "ping")]
87            ping: ping::Metrics::new(sub_registry),
88            #[cfg(feature = "relay")]
89            relay: relay::Metrics::new(sub_registry),
90            swarm: swarm::Metrics::new(sub_registry),
91        }
92    }
93}
94
95/// Recorder that can record Swarm and protocol events.
96pub trait Recorder<Event> {
97    /// Record the given event.
98    fn record(&self, event: &Event);
99}
100
101#[cfg(feature = "dcutr")]
102impl Recorder<libp2p_dcutr::Event> for Metrics {
103    fn record(&self, event: &libp2p_dcutr::Event) {
104        self.dcutr.record(event)
105    }
106}
107
108#[cfg(feature = "gossipsub")]
109impl Recorder<libp2p_gossipsub::Event> for Metrics {
110    fn record(&self, event: &libp2p_gossipsub::Event) {
111        self.gossipsub.record(event)
112    }
113}
114
115#[cfg(feature = "identify")]
116impl Recorder<libp2p_identify::Event> for Metrics {
117    fn record(&self, event: &libp2p_identify::Event) {
118        self.identify.record(event)
119    }
120}
121
122#[cfg(feature = "kad")]
123impl Recorder<libp2p_kad::Event> for Metrics {
124    fn record(&self, event: &libp2p_kad::Event) {
125        self.kad.record(event)
126    }
127}
128
129#[cfg(feature = "ping")]
130impl Recorder<libp2p_ping::Event> for Metrics {
131    fn record(&self, event: &libp2p_ping::Event) {
132        self.ping.record(event)
133    }
134}
135
136#[cfg(feature = "relay")]
137impl Recorder<libp2p_relay::Event> for Metrics {
138    fn record(&self, event: &libp2p_relay::Event) {
139        self.relay.record(event)
140    }
141}
142
143impl<TBvEv> Recorder<libp2p_swarm::SwarmEvent<TBvEv>> for Metrics {
144    fn record(&self, event: &libp2p_swarm::SwarmEvent<TBvEv>) {
145        self.swarm.record(event);
146
147        #[cfg(feature = "identify")]
148        self.identify.record(event)
149    }
150}