Struct tracing_opentelemetry::MetricsLayer
source · pub struct MetricsLayer { /* private fields */ }
metrics
only.Expand description
A layer that publishes metrics via the OpenTelemetry SDK.
Usage
No configuration is needed for this Layer, as it’s only responsible for
pushing data out to the opentelemetry
family of crates. For example, when
using opentelemetry-otlp
, that crate will provide its own set of
configuration options for setting up the duration metrics will be collected
before exporting to the OpenTelemetry Collector, aggregation of data points,
etc.
use tracing_opentelemetry::MetricsLayer;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::Registry;
// Constructing a BasicController is out-of-scope for the docs here, but there
// are examples in the opentelemetry repository. See:
// https://github.com/open-telemetry/opentelemetry-rust/blob/d4b9befea04bcc7fc19319a6ebf5b5070131c486/examples/basic-otlp/src/main.rs#L35-L52
let opentelemetry_metrics = MetricsLayer::new(controller);
let subscriber = Registry::default().with(opentelemetry_metrics);
tracing::subscriber::set_global_default(subscriber).unwrap();
To publish a new metric, add a key-value pair to your tracing::Event
that
contains following prefixes:
monotonic_counter.
(non-negative numbers): Used when the counter should only ever increasecounter.
: Used when the counter can go up or downvalue.
: Used for discrete data points (i.e., summing them does not make semantic sense)
Examples:
info!(monotonic_counter.foo = 1);
info!(monotonic_counter.bar = 1.1);
info!(counter.baz = 1);
info!(counter.baz = -1);
info!(counter.xyz = 1.1);
info!(value.qux = 1);
info!(value.abc = -1);
info!(value.def = 1.1);
Mixing data types
Floating-point numbers
Do not mix floating point and non-floating point numbers for the same metric. If a floating point number will be used for a given metric, be sure to cast any other usages of that metric to a floating point number.
Do this:
info!(monotonic_counter.foo = 1_f64);
info!(monotonic_counter.foo = 1.1);
This is because all data published for a given metric name must be the same numeric type.
Integers
Positive and negative integers can be mixed freely. The instrumentation
provided by tracing
assumes that all integers are i64
unless explicitly
cast to something else. In the case that an integer is cast to u64
, this
subscriber will handle the conversion internally.
For example:
// The subscriber receives an i64
info!(counter.baz = 1);
// The subscriber receives an i64
info!(counter.baz = -1);
// The subscriber receives a u64, but casts it to i64 internally
info!(counter.baz = 1_u64);
// The subscriber receives a u64, but cannot cast it to i64 because of
// overflow. An error is printed to stderr, and the metric is dropped.
info!(counter.baz = (i64::MAX as u64) + 1)
Implementation Details
MetricsLayer
holds a set of maps, with each map corresponding to a
type of metric supported by OpenTelemetry. These maps are populated lazily.
The first time that a metric is emitted by the instrumentation, a Metric
instance will be created and added to the corresponding map. This means that
any time a metric is emitted by the instrumentation, one map lookup has to
be performed.
In the future, this can be improved by associating each Metric
instance to
its callsite, eliminating the need for any maps.
Implementations§
source§impl MetricsLayer
impl MetricsLayer
Trait Implementations§
source§impl<S> Layer<S> for MetricsLayerwhere
S: Subscriber + for<'span> LookupSpan<'span>,
impl<S> Layer<S> for MetricsLayerwhere S: Subscriber + for<'span> LookupSpan<'span>,
source§fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>)
fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>)
source§fn on_register_dispatch(&self, collector: &Dispatch)
fn on_register_dispatch(&self, collector: &Dispatch)
Subscriber
. Read moresource§fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest
Subscriber::register_callsite
. Read moresource§fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool
fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool
true
if this layer is interested in a span or event with the
given metadata
in the current Context
, similarly to
Subscriber::enabled
. Read moresource§fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)
fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)
Attributes
and Id
.source§fn on_record(&self, _span: &Id, _values: &Record<'_>, _ctx: Context<'_, S>)
fn on_record(&self, _span: &Id, _values: &Record<'_>, _ctx: Context<'_, S>)
Id
recorded the given
values
.source§fn on_follows_from(&self, _span: &Id, _follows: &Id, _ctx: Context<'_, S>)
fn on_follows_from(&self, _span: &Id, _follows: &Id, _ctx: Context<'_, S>)
span
recorded that it
follows from the span with the ID follows
.source§fn event_enabled(&self, _event: &Event<'_>, _ctx: Context<'_, S>) -> bool
fn event_enabled(&self, _event: &Event<'_>, _ctx: Context<'_, S>) -> bool
on_event
, to determine if on_event
should be called.source§fn on_enter(&self, _id: &Id, _ctx: Context<'_, S>)
fn on_enter(&self, _id: &Id, _ctx: Context<'_, S>)
source§fn on_exit(&self, _id: &Id, _ctx: Context<'_, S>)
fn on_exit(&self, _id: &Id, _ctx: Context<'_, S>)
source§fn on_close(&self, _id: Id, _ctx: Context<'_, S>)
fn on_close(&self, _id: Id, _ctx: Context<'_, S>)
source§fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>)
fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>)
source§fn and_then<L>(self, layer: L) -> Layered<L, Self, S>where
L: Layer<S>,
Self: Sized,
fn and_then<L>(self, layer: L) -> Layered<L, Self, S>where L: Layer<S>, Self: Sized,
Layer
, returning a Layered
struct implementing Layer
. Read moresource§fn with_subscriber(self, inner: S) -> Layered<Self, S, S>where
Self: Sized,
fn with_subscriber(self, inner: S) -> Layered<Self, S, S>where Self: Sized,
Layer
with the given Subscriber
, returning a
Layered
struct that implements Subscriber
. Read more