Skip to content

Commit

Permalink
feat: produce measurement with attributes (tokio-rs#43)
Browse files Browse the repository at this point in the history
## Motivation

Support tokio-rs#32
This change will allow user to associate Attributes with metrics from
tracing.

## Solution

1. MetricsLayer is only interested in events that contain fields with
metrics prefixes such as `counter`, so I have utilized the
[tracing_subscriber Filter
trait](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/#per-layer-filtering).
2. Since it's necessary to pass Attributes when outputting Measurements,
it's required to complete the visit for all fields first before invoking
the Metrics API(`Counter:add()`).
`SmallVec` is used to hold Attribute KeyValues, Metrics names, and
Instruments for invocation, aiming to avoid allocations in typical use
cases.
  • Loading branch information
ymgyt authored Aug 8, 2023
1 parent 6bc7dce commit 7bb3e56
Show file tree
Hide file tree
Showing 4 changed files with 661 additions and 79 deletions.
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ rust-version = "1.60.0"
[features]
default = ["tracing-log", "metrics"]
# Enables support for exporting OpenTelemetry metrics
metrics = ["opentelemetry/metrics"]
metrics = ["opentelemetry/metrics", "smallvec"]

[dependencies]
opentelemetry = { version = "0.20.0", default-features = false, features = ["trace"] }
Expand All @@ -35,6 +35,7 @@ once_cell = "1.13.0"
# Fix minimal-versions
async-trait = { version = "0.1.56", optional = true }
thiserror = { version = "1.0.31", optional = true }
smallvec = { version = "1.0", optional = true }

[dev-dependencies]
async-trait = "0.1.56"
Expand All @@ -56,6 +57,10 @@ bench = false
name = "trace"
harness = false

[[bench]]
name = "metrics"
harness = false

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
162 changes: 162 additions & 0 deletions benches/metrics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use criterion::{criterion_group, criterion_main, Criterion};
use opentelemetry::metrics::noop::NoopMeterProvider;
use tracing_opentelemetry::MetricsLayer;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

fn metrics_events(c: &mut Criterion) {
let mut group = c.benchmark_group("otel_metrics_events");
{
let _subscriber = tracing_subscriber::registry().set_default();
group.bench_function("no_metrics_layer", |b| {
b.iter(|| {
tracing::info!(key_1 = "va", "msg");
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_0_attr_0", |b| {
b.iter(|| {
tracing::info!(key_1 = "va", "msg");
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_1_attr_0", |b| {
b.iter(|| {
tracing::info!(monotonic_counter.c1 = 1, "msg");
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_2_attr_0", |b| {
b.iter(|| {
tracing::info!(monotonic_counter.c1 = 1, monotonic_counter.c2 = 1, "msg");
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_4_attr_0", |b| {
b.iter(|| {
tracing::info!(
monotonic_counter.c1 = 1,
monotonic_counter.c2 = 1,
monotonic_counter.c3 = 1,
monotonic_counter.c4 = 1,
"msg"
);
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_8_attr_0", |b| {
b.iter(|| {
tracing::info!(
monotonic_counter.c1 = 1,
monotonic_counter.c2 = 1,
monotonic_counter.c3 = 1,
monotonic_counter.c4 = 1,
monotonic_counter.c5 = 1,
monotonic_counter.c6 = 1,
monotonic_counter.c7 = 1,
monotonic_counter.c8 = 1,
"msg"
);
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_1_attr_1", |b| {
b.iter(|| {
tracing::info!(monotonic_counter.c1 = 1, key_1 = 1_i64, "msg");
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_1_attr_2", |b| {
b.iter(|| {
tracing::info!(
monotonic_counter.c1 = 1,
key_1 = 1_i64,
key_2 = 1_i64,
"msg"
);
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_1_attr_4", |b| {
b.iter(|| {
tracing::info!(
monotonic_counter.c1 = 1,
key_1 = 1_i64,
key_2 = 1_i64,
key_3 = 1_i64,
key_4 = 1_i64,
"msg"
);
})
});
}

{
let _subscriber = tracing_subscriber::registry()
.with(MetricsLayer::new(NoopMeterProvider::new()))
.set_default();
group.bench_function("metrics_events_1_attr_8", |b| {
b.iter(|| {
tracing::info!(
monotonic_counter.c1 = 1,
key_1 = 1_i64,
key_2 = 1_i64,
key_3 = 1_i64,
key_4 = 1_i64,
key_5 = 1_i64,
key_6 = 1_i64,
key_7 = 1_i64,
key_8 = 1_i64,
"msg"
);
})
});
}
group.finish();
}

criterion_group! {
name = benches;
config = Criterion::default();
targets = metrics_events
}
criterion_main!(benches);
Loading

0 comments on commit 7bb3e56

Please sign in to comment.