Skip to content

Commit

Permalink
--wip-- [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
MOZGIII committed Sep 11, 2020
1 parent 6ec6f42 commit 2d7081c
Show file tree
Hide file tree
Showing 13 changed files with 246 additions and 118 deletions.
47 changes: 32 additions & 15 deletions metrics-exporter-prometheus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use hyper::{
service::{make_service_fn, service_fn},
{Body, Error as HyperError, Response, Server},
};
use metrics::{Identifier, Key, KeyRef, Label, Recorder, SetRecorderError};
use metrics::{KeyRef, Recorder, SetRecorderError};
use metrics_util::{
parse_quantiles, CompositeKey, Handle, Histogram, MetricKind, Quantile, Registry,
};
Expand Down Expand Up @@ -335,7 +335,7 @@ pub struct PrometheusRecorder {
}

impl PrometheusRecorder {
fn add_description_if_missing(&self, key: &Key, description: Option<&'static str>) {
fn add_description_if_missing(&self, key: &KeyRef, description: Option<&'static str>) {
if let Some(description) = description {
let mut descriptions = self.inner.descriptions.write();
if !descriptions.contains_key(key.name().as_ref()) {
Expand Down Expand Up @@ -494,65 +494,82 @@ impl PrometheusBuilder {
}

impl Recorder for PrometheusRecorder {
fn register_counter(&self, key: Key, description: Option<&'static str>) -> Identifier {
fn register_counter(&self, key: KeyRef, description: Option<&'static str>) {
self.add_description_if_missing(&key, description);
self.inner
.registry()
.get_or_create_identifier(CompositeKey::new(MetricKind::Counter, key), |_| {
Handle::counter()
})
});
}

fn register_gauge(&self, key: Key, description: Option<&'static str>) -> Identifier {
fn register_gauge(&self, key: KeyRef, description: Option<&'static str>) {
self.add_description_if_missing(&key, description);
self.inner
.registry()
.get_or_create_identifier(CompositeKey::new(MetricKind::Gauge, key), |_| {
Handle::gauge()
})
});
}

fn register_histogram(&self, key: Key, description: Option<&'static str>) -> Identifier {
fn register_histogram(&self, key: KeyRef, description: Option<&'static str>) {
self.add_description_if_missing(&key, description);
self.inner
.registry()
.get_or_create_identifier(CompositeKey::new(MetricKind::Histogram, key), |_| {
Handle::histogram()
})
});
}

fn increment_counter(&self, key: KeyRef, value: u64) {
let id = self.register_counter(key.into_owned(), None);
let id = self
.inner
.registry()
.get_or_create_identifier(CompositeKey::new(MetricKind::Counter, key), |_| {
Handle::counter()
});
self.inner
.registry()
.with_handle(id, |h| h.increment_counter(value));
}

fn update_gauge(&self, key: KeyRef, value: f64) {
let id = self.register_gauge(key.into_owned(), None);
let id = self
.inner
.registry()
.get_or_create_identifier(CompositeKey::new(MetricKind::Gauge, key), |_| {
Handle::gauge()
});
self.inner
.registry()
.with_handle(id, |h| h.update_gauge(value));
}

fn record_histogram(&self, key: KeyRef, value: u64) {
let id = self.register_histogram(key.into_owned(), None);
let id = self
.inner
.registry()
.get_or_create_identifier(CompositeKey::new(MetricKind::Histogram, key), |_| {
Handle::histogram()
});
self.inner
.registry()
.with_handle(id, |h| h.record_histogram(value));
}
}

fn key_to_parts(key: Key) -> (String, Vec<String>) {
let (name, labels) = key.into_parts();
fn key_to_parts(key: KeyRef) -> (String, Vec<String>) {
let name = key.name();
let labels = key.labels();
let sanitize = |c| c == '.' || c == '=' || c == '{' || c == '}' || c == '+' || c == '-';
let name = name.replace(sanitize, "_");
let labels = labels
.map(|labels| {
labels
.into_iter()
.map(Label::into_parts)
.map(|(k, v)| {
.map(|label| {
let k = label.key();
let v = label.value();
format!(
"{}=\"{}\"",
k,
Expand Down
26 changes: 13 additions & 13 deletions metrics-exporter-tcp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use std::time::SystemTime;

use bytes::Bytes;
use crossbeam_channel::{bounded, unbounded, Receiver, Sender};
use metrics::{Identifier, Key, KeyRef, Recorder, SetRecorderError};
use metrics::{Identifier, KeyRef, Recorder, SetRecorderError};
use metrics_util::Registry;
use mio::{
net::{TcpListener, TcpStream},
Expand Down Expand Up @@ -87,10 +87,10 @@ enum MetricValue {
}

#[derive(Eq, PartialEq, Hash, Clone)]
struct CompositeKey(MetricKind, Key);
struct CompositeKey(MetricKind, KeyRef);

impl CompositeKey {
pub fn key(&self) -> &Key {
pub fn key(&self) -> &KeyRef {
&self.1
}
}
Expand Down Expand Up @@ -214,7 +214,7 @@ impl TcpBuilder {
}

impl TcpRecorder {
fn register_metric(&self, kind: MetricKind, key: Key) -> Identifier {
fn register_metric(&self, kind: MetricKind, key: KeyRef) -> Identifier {
let ckey = CompositeKey(kind, key);
self.registry.get_or_create_identifier(ckey, |k| k.clone())
}
Expand All @@ -230,30 +230,30 @@ impl TcpRecorder {
}

impl Recorder for TcpRecorder {
fn register_counter(&self, key: Key, _description: Option<&'static str>) -> Identifier {
self.register_metric(MetricKind::Counter, key)
fn register_counter(&self, key: KeyRef, _description: Option<&'static str>) {
self.register_metric(MetricKind::Counter, key);
}

fn register_gauge(&self, key: Key, _description: Option<&'static str>) -> Identifier {
self.register_metric(MetricKind::Gauge, key)
fn register_gauge(&self, key: KeyRef, _description: Option<&'static str>) {
self.register_metric(MetricKind::Gauge, key);
}

fn register_histogram(&self, key: Key, _description: Option<&'static str>) -> Identifier {
self.register_metric(MetricKind::Histogram, key)
fn register_histogram(&self, key: KeyRef, _description: Option<&'static str>) {
self.register_metric(MetricKind::Histogram, key);
}

fn increment_counter(&self, key: KeyRef, value: u64) {
let id = self.register_counter(key.into_owned(), None);
let id = self.register_metric(MetricKind::Counter, key);
self.push_metric(id, MetricValue::Counter(value));
}

fn update_gauge(&self, key: KeyRef, value: f64) {
let id = self.register_gauge(key.into_owned(), None);
let id = self.register_metric(MetricKind::Gauge, key);
self.push_metric(id, MetricValue::Gauge(value));
}

fn record_histogram(&self, key: KeyRef, value: u64) {
let id = self.register_histogram(key.into_owned(), None);
let id = self.register_metric(MetricKind::Histogram, key);
self.push_metric(id, MetricValue::Histogram(value));
}
}
Expand Down
4 changes: 3 additions & 1 deletion metrics-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ fn get_expanded_registration(
{
// Only do this work if there's a recorder installed.
if let Some(recorder) = metrics::try_recorder() {
recorder.#register_ident(#key, #description);
// Registrations are fairly rare, don't attempt to cache here
// and just use and owned ref.
recorder.#register_ident(metrics::KeyRef::Owned(#key), #description);
}
}
}
Expand Down
37 changes: 32 additions & 5 deletions metrics-macros/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn test_get_expanded_registration() {
let expected = concat!(
"{ if let Some ( recorder ) = metrics :: try_recorder ( ) { ",
"recorder . register_mytype ( ",
"metrics :: Key :: from_name ( \"mykeyname\" ) , ",
"metrics :: KeyRef :: Owned ( metrics :: Key :: from_name ( \"mykeyname\" ) ) , ",
"None ",
") ; ",
"} }",
Expand All @@ -38,10 +38,9 @@ fn test_get_expanded_registration() {
assert_eq!(stream.to_string(), expected);
}

/// If there are no dynamic labels - we generate the static invocation.
/// If there are no dynamic labels - generate an invocation with caching.
#[test]
#[ignore]
fn test_get_expanded_callsite() {
fn test_get_expanded_callsite_fast_path() {
let stream = get_expanded_callsite(
"mytype",
"myop",
Expand All @@ -52,8 +51,36 @@ fn test_get_expanded_callsite() {

let expected = concat!(
"{ ",
"static CACHED_KEY : metrics :: OnceKey = metrics :: OnceKey :: new ( ) ; ",
"if let Some ( recorder ) = metrics :: try_recorder ( ) { ",
"recorder . myop_mytype ( metrics :: Key :: from_name ( \"mykeyname\" ) , 1 ) ; ",
"let key = CACHED_KEY . get_or_init ( || { ",
"metrics :: Key :: from_name ( \"mykeyname\" ) ",
"} ) ; ",
"recorder . myop_mytype ( metrics :: KeyRef :: Borrowed ( & key ) , 1 ) ; ",
"} }",
);

assert_eq!(stream.to_string(), expected);
}

/// If there are dynamic labels - generate a direct invocation.
#[test]
fn test_get_expanded_callsite_regular_path() {
let stream = get_expanded_callsite(
"mytype",
"myop",
Key::NotScoped(parse_quote! {"mykeyname"}),
Some(Labels::Existing(parse_quote! { mylabels })),
quote! { 1 },
);

let expected = concat!(
"{ ",
"if let Some ( recorder ) = metrics :: try_recorder ( ) { ",
"recorder . myop_mytype ( ",
"metrics :: KeyRef :: Owned ( metrics :: Key :: from_name_and_labels ( \"mykeyname\" , mylabels ) ) , ",
"1 ",
") ; ",
"} }",
);

Expand Down
13 changes: 7 additions & 6 deletions metrics-tracing-context/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use metrics::{Identifier, Key, KeyRef, Label, Recorder};
use metrics::{Key, KeyRef, Label, Recorder};
use metrics_util::layers::Layer;
use tracing::Span;

Expand Down Expand Up @@ -33,23 +33,24 @@ impl<R> TracingContext<R> {
let mut labels = labels.unwrap_or_default();
self.enhance_labels(&mut labels);
if labels.is_empty() {
KeyRef::Owned(Key::from_name(name))
Key::from_name(name)
} else {
KeyRef::Owned(Key::from_name_and_labels(name, labels))
Key::from_name_and_labels(name, labels)
}
.into()
}
}

impl<R: Recorder> Recorder for TracingContext<R> {
fn register_counter(&self, key: Key, description: Option<&'static str>) -> Identifier {
fn register_counter(&self, key: KeyRef, description: Option<&'static str>) {
self.inner.register_counter(key, description)
}

fn register_gauge(&self, key: Key, description: Option<&'static str>) -> Identifier {
fn register_gauge(&self, key: KeyRef, description: Option<&'static str>) {
self.inner.register_gauge(key, description)
}

fn register_histogram(&self, key: Key, description: Option<&'static str>) -> Identifier {
fn register_histogram(&self, key: KeyRef, description: Option<&'static str>) {
self.inner.register_histogram(key, description)
}

Expand Down
11 changes: 7 additions & 4 deletions metrics-tracing-context/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ fn test_basic_functionality() {
Label::new("user", "ferris"),
Label::new("user.email", "ferris@rust-lang.org"),
],
),
)
.into(),
DebugValue::Counter(1),
)]
)
Expand All @@ -79,7 +80,7 @@ fn test_no_labels() {
snapshot,
vec![(
MetricKind::Counter,
Key::from_name("login_attempts",),
Key::from_name("login_attempts").into(),
DebugValue::Counter(1),
)]
)
Expand Down Expand Up @@ -137,7 +138,8 @@ fn test_multiple_paths_to_the_same_callsite() {
Label::new("path1_specific", "foo"),
Label::new("path1_specific_dynamic", "foo_dynamic"),
],
),
)
.into(),
DebugValue::Counter(1),
),
(
Expand All @@ -149,7 +151,8 @@ fn test_multiple_paths_to_the_same_callsite() {
Label::new("path2_specific", "bar"),
Label::new("path2_specific_dynamic", "bar_dynamic"),
],
),
)
.into(),
DebugValue::Counter(1),
)
]
Expand Down
Loading

0 comments on commit 2d7081c

Please sign in to comment.