From 9a3c29363349e012d58c15cf61b20f8ed91066ce Mon Sep 17 00:00:00 2001 From: Toby Lawrence Date: Sun, 25 Oct 2020 16:59:44 -0400 Subject: [PATCH] massive docs tweaks --- metrics/Cargo.toml | 1 + metrics/examples/basic.rs | 75 ++++++-- metrics/src/common.rs | 50 +++-- metrics/src/key.rs | 51 +++-- metrics/src/label.rs | 23 ++- metrics/src/lib.rs | 391 ++++++++++++++++++++++++++------------ metrics/src/recorder.rs | 15 +- 7 files changed, 413 insertions(+), 193 deletions(-) diff --git a/metrics/Cargo.toml b/metrics/Cargo.toml index cd5c86a..60fa779 100644 --- a/metrics/Cargo.toml +++ b/metrics/Cargo.toml @@ -28,6 +28,7 @@ name = "macros" harness = false [dependencies] +beef = "0.4" metrics-macros = { version = "0.1.0-alpha.1", path = "../metrics-macros" } proc-macro-hack = "0.5" once_cell = "1" diff --git a/metrics/examples/basic.rs b/metrics/examples/basic.rs index 5a5faf0..a0a5bca 100644 --- a/metrics/examples/basic.rs +++ b/metrics/examples/basic.rs @@ -1,4 +1,14 @@ -use metrics::{counter, gauge, histogram, increment, Key, Recorder, Unit}; +//! This example is part unit test and part demonstration. +//! +//! We show all of the registration macros, as well as all of the "emission" macros, the ones you +//! would actually call to update a metric. +//! +//! We demonstrate the various permutations of values that can be passed in the macro calls, all of +//! which are documented in detail for the respective macro. +use metrics::{ + counter, gauge, histogram, increment, register_counter, register_gauge, register_histogram, + Key, Recorder, Unit, +}; #[allow(dead_code)] static RECORDER: PrintRecorder = PrintRecorder; @@ -56,21 +66,58 @@ fn main() { let server_name = "web03".to_string(); init_print_logger(); - for _ in 0..3 { - increment!("requests_processed"); - increment!("requests_processed", "request_type" => "admin"); - } + + let common_labels = &[("listener", "frontend")]; + + // Go through registration: + register_counter!("requests_processed", "number of requests processed"); + register_counter!("bytes_sent", Unit::Bytes); + register_gauge!("connection_count", common_labels); + register_histogram!( + "svc.execution_time", + Unit::Milliseconds, + "execution time of request handler" + ); + register_gauge!("unused_gauge", "service" => "backend"); + register_histogram!("unused_histogram", Unit::Seconds, "unused histo", "service" => "middleware"); + + // All the supported permutations of `increment!`: + increment!("requests_processed"); + increment!("requests_processed", "request_type" => "admin"); increment!("requests_processed", "request_type" => "admin", "server" => server_name.clone()); - counter!("requests_processed", 1); - counter!("requests_processed", 1, "request_type" => "admin"); - counter!("requests_processed", 1, "request_type" => "admin", "server" => server_name.clone()); + increment!("requests_processed", common_labels); + increment!(<"requests_processed">); + increment!(<"requests_processed">, "request_type" => "admin"); + increment!(<"requests_processed">, "request_type" => "admin", "server" => server_name.clone()); + increment!(<"requests_processed">, common_labels); + + // All the supported permutations of `counter!`: + counter!("bytes_sent", 64); + counter!("bytes_sent", 64, "listener" => "frontend"); + counter!("bytes_sent", 64, "listener" => "frontend", "server" => server_name.clone()); + counter!("bytes_sent", 64, common_labels); + counter!(<"bytes_sent">, 64); + counter!(<"bytes_sent">, 64, "listener" => "frontend"); + counter!(<"bytes_sent">, 64, "listener" => "frontend", "server" => server_name.clone()); + counter!(<"bytes_sent">, 64, common_labels); + + // All the supported permutations of `gauge!`: gauge!("connection_count", 300.0); gauge!("connection_count", 300.0, "listener" => "frontend"); gauge!("connection_count", 300.0, "listener" => "frontend", "server" => server_name.clone()); - histogram!("service.execution_time", 70); - histogram!("service.execution_time", 70, "type" => "users"); - histogram!("service.execution_time", 70, "type" => "users", "server" => server_name.clone()); - histogram!(<"service.execution_time">, 70); - histogram!(<"service.execution_time">, 70, "type" => "users"); - histogram!(<"service.execution_time">, 70, "type" => "users", "server" => server_name.clone()); + gauge!("connection_count", 300.0, common_labels); + gauge!(<"connection_count">, 300.0); + gauge!(<"connection_count">, 300.0, "listener" => "frontend"); + gauge!(<"connection_count">, 300.0, "listener" => "frontend", "server" => server_name.clone()); + gauge!(<"connection_count">, 300.0, common_labels); + + // All the supported permutations of `histogram!`: + histogram!("svc.execution_time", 70); + histogram!("svc.execution_time", 70, "type" => "users"); + histogram!("svc.execution_time", 70, "type" => "users", "server" => server_name.clone()); + histogram!("svc.execution_time", 70, common_labels); + histogram!(<"svc.execution_time">, 70); + histogram!(<"svc.execution_time">, 70, "type" => "users"); + histogram!(<"svc.execution_time">, 70, "type" => "users", "server" => server_name.clone()); + histogram!(<"svc.execution_time">, 70, common_labels); } diff --git a/metrics/src/common.rs b/metrics/src/common.rs index 6821b1d..60dd0f0 100644 --- a/metrics/src/common.rs +++ b/metrics/src/common.rs @@ -1,4 +1,7 @@ -use std::borrow::Cow; +#[cfg(target_pointer_width = "64")] +use beef::lean::Cow; +#[cfg(not(target_pointer_width = "64"))] +use beef::Cow; /// An allocation-optimized string. /// @@ -111,6 +114,9 @@ impl Unit { /// Gets the canonical string label for the given unit. /// + /// For example, the canonical label for Seconds` would be `s`, while for `Nanoseconds, it would + /// be `ns`. + /// /// Not all units have a meaningful display label and so may be empty. pub fn as_canonical_label(&self) -> &str { match self { @@ -145,6 +151,8 @@ impl Unit { } /// Converts the string representation of a unit back into `Unit` if possible. + /// + /// The value passed here should match the output of [`Unit::as_str`]. pub fn from_str(s: &str) -> Option { match s { "count" => Some(Unit::Count), @@ -189,14 +197,26 @@ impl Unit { /// Whether or not this unit relates to the measurement of data. pub fn is_data_based(&self) -> bool { match self { - Unit::Terabytes | Unit::Gigabytes | Unit::Megabytes | Unit::Kilobytes | Unit::Bytes => { - true - } - Unit::Terabits | Unit::Gigabits | Unit::Megabits | Unit::Kilobits | Unit::Bits => true, - Unit::TerabytesPerSecond | Unit::GigabytesPerSecond | Unit::MegabytesPerSecond => true, - Unit::KilobytesPerSecond | Unit::BytesPerSecond | Unit::TerabitsPerSecond => true, - Unit::GigabitsPerSecond | Unit::MegabitsPerSecond | Unit::KilobitsPerSecond => true, - Unit::BitsPerSecond => true, + Unit::Terabytes + | Unit::Gigabytes + | Unit::Megabytes + | Unit::Kilobytes + | Unit::Bytes + | Unit::Terabits + | Unit::Gigabits + | Unit::Megabits + | Unit::Kilobits + | Unit::Bits + | Unit::TerabytesPerSecond + | Unit::GigabytesPerSecond + | Unit::MegabytesPerSecond + | Unit::KilobytesPerSecond + | Unit::BytesPerSecond + | Unit::TerabitsPerSecond + | Unit::GigabitsPerSecond + | Unit::MegabitsPerSecond + | Unit::KilobitsPerSecond + | Unit::BitsPerSecond => true, _ => false, } } @@ -204,12 +224,16 @@ impl Unit { /// Whether or not this unit relates to the measurement of data rates. pub fn is_data_rate_based(&self) -> bool { match self { - Unit::TerabytesPerSecond | Unit::GigabytesPerSecond | Unit::MegabytesPerSecond => true, - Unit::KilobytesPerSecond + Unit::TerabytesPerSecond + | Unit::GigabytesPerSecond + | Unit::MegabytesPerSecond + | Unit::KilobytesPerSecond | Unit::BytesPerSecond | Unit::TerabitsPerSecond - | Unit::Gigabits => true, - Unit::MegabitsPerSecond | Unit::KilobitsPerSecond | Unit::BitsPerSecond => true, + | Unit::Gigabits + | Unit::MegabitsPerSecond + | Unit::KilobitsPerSecond + | Unit::BitsPerSecond => true, _ => false, } } diff --git a/metrics/src/key.rs b/metrics/src/key.rs index 4e3c213..c00ad21 100644 --- a/metrics/src/key.rs +++ b/metrics/src/key.rs @@ -1,14 +1,14 @@ use crate::{IntoLabels, Label, ScopedString}; -use std::{ +use core::{ fmt, hash::{Hash, Hasher}, slice::Iter, }; -/// A metric key data. +/// Inner representation of [`Key`]. /// -/// A key data always includes a name, but can optionally include multiple -/// labels used to further describe the metric. +/// While [`Key`] is the type that users will interact with via [`crate::Recorder`], [`KeyData`] is +/// responsible for the actual storage of the name and label data. #[derive(PartialEq, Eq, Hash, Clone, Debug)] pub struct KeyData { name: ScopedString, @@ -16,7 +16,7 @@ pub struct KeyData { } impl KeyData { - /// Creates a `KeyData` from a name. + /// Creates a [`KeyData`] from a name. pub fn from_name(name: N) -> Self where N: Into, @@ -24,7 +24,7 @@ impl KeyData { Self::from_name_and_labels(name, Vec::new()) } - /// Creates a `KeyData` from a name and vector of `Label`s. + /// Creates a [`KeyData`] from a name and vector of [`Label`]s. pub fn from_name_and_labels(name: N, labels: L) -> Self where N: Into, @@ -36,12 +36,12 @@ impl KeyData { } } - /// Creates a `KeyData` from a static name. + /// Creates a [`KeyData`] from a static name. /// - /// This function is const, so it can be used in a static context. + /// This function is `const`, so it can be used in a static context. pub const fn from_static_name(name: &'static str) -> Self { Self { - name: ScopedString::Borrowed(name), + name: ScopedString::const_str(name), labels: Vec::new(), } } @@ -68,12 +68,12 @@ impl KeyData { self } - /// Consumes this `Key`, returning the name and any labels. + /// Consumes this [`Key`], returning the name and any labels. pub fn into_parts(self) -> (ScopedString, Vec