nm/
observe.rs

1use std::time::Duration;
2
3use num_traits::AsPrimitive;
4
5use crate::Magnitude;
6
7/// Operations for observing the occurrences of an event.
8///
9/// This is implemented primarily by [`Event`][1] but also by [`ObservationBatch`][2],
10/// thereby providing an abstraction for callers that wish to support both single and batch events.
11///
12/// [1]: crate::Event
13/// [2]: crate::ObservationBatch
14pub trait Observe {
15    /// Observes an event that has no explicit magnitude.
16    ///
17    /// By convention, this is represented as a magnitude of 1. We expose a separate
18    /// method for this to make it clear that the magnitude has no inherent meaning.
19    ///
20    /// # Example
21    ///
22    /// ```
23    /// use nm::Event;
24    ///
25    /// thread_local! {
26    ///     static REQUESTS: Event = Event::builder()
27    ///         .name("requests")
28    ///         .build();
29    /// }
30    ///
31    /// // Count a single request occurrence
32    /// REQUESTS.with(|event| event.observe_once());
33    /// ```
34    fn observe_once(&self);
35
36    /// Observes an event with a specific magnitude.
37    ///
38    /// # Example
39    ///
40    /// ```
41    /// use nm::Event;
42    ///
43    /// thread_local! {
44    ///     static SENT_BYTES: Event = Event::builder()
45    ///         .name("sent_bytes")
46    ///         .build();
47    /// }
48    ///
49    /// // Record sending 1024 bytes
50    /// SENT_BYTES.with(|event| event.observe(1024));
51    /// ```
52    fn observe(&self, magnitude: impl AsPrimitive<Magnitude>);
53
54    /// Observes an event with the magnitude being the indicated duration in milliseconds.
55    ///
56    /// Only the whole number part of the duration is used - fractional milliseconds are ignored.
57    /// Values outside the i64 range are not guaranteed to be correctly represented.
58    ///
59    /// # Example
60    ///
61    /// ```
62    /// use std::time::Duration;
63    ///
64    /// use nm::Event;
65    ///
66    /// thread_local! {
67    ///     static REQUEST_DURATION: Event = Event::builder()
68    ///         .name("request_duration_ms")
69    ///         .build();
70    /// }
71    ///
72    /// let duration = Duration::from_millis(250);
73    /// REQUEST_DURATION.with(|event| event.observe_millis(duration));
74    /// ```
75    fn observe_millis(&self, duration: Duration);
76
77    /// Observes the duration of a function call, in milliseconds.
78    ///
79    /// # Example
80    ///
81    /// ```
82    /// use nm::Event;
83    ///
84    /// thread_local! {
85    ///     static DATABASE_QUERY_TIME: Event = Event::builder()
86    ///         .name("database_query_time_ms")
87    ///         .build();
88    /// }
89    ///
90    /// fn query_database() -> String {
91    /// #     // Simulated database query
92    /// #     "result".to_string()
93    /// }
94    ///
95    /// let result =
96    ///     DATABASE_QUERY_TIME.with(|event| event.observe_duration_millis(|| query_database()));
97    /// ```
98    fn observe_duration_millis<F, R>(&self, f: F) -> R
99    where
100        F: FnOnce() -> R;
101}