spin_telemetry/
metrics.rs1use anyhow::{bail, Result};
2use opentelemetry::global;
3use opentelemetry_sdk::{
4 metrics::{PeriodicReader, SdkMeterProvider},
5 resource::{EnvResourceDetector, ResourceDetector, TelemetryResourceDetector},
6 Resource,
7};
8use tracing::Subscriber;
9use tracing_opentelemetry::MetricsLayer;
10use tracing_subscriber::{registry::LookupSpan, Layer};
11
12use crate::{detector::SpinResourceDetector, env::OtlpProtocol};
13
14pub(crate) fn otel_metrics_layer<S: Subscriber + for<'span> LookupSpan<'span>>(
20 spin_version: String,
21) -> Result<impl Layer<S>> {
22 let resource = Resource::builder()
23 .with_detectors(&[
24 Box::new(SpinResourceDetector::new(spin_version)) as Box<dyn ResourceDetector>,
27 Box::new(EnvResourceDetector::new()),
29 Box::new(TelemetryResourceDetector),
31 ])
32 .build();
33
34 let exporter = match OtlpProtocol::metrics_protocol_from_env() {
39 OtlpProtocol::Grpc => opentelemetry_otlp::MetricExporter::builder()
40 .with_tonic()
41 .build()?,
42 OtlpProtocol::HttpProtobuf => opentelemetry_otlp::MetricExporter::builder()
43 .with_http()
44 .build()?,
45 OtlpProtocol::HttpJson => bail!("http/json OTLP protocol is not supported"),
46 };
47
48 let reader = PeriodicReader::builder(exporter).build();
49 let meter_provider = SdkMeterProvider::builder()
50 .with_reader(reader)
51 .with_resource(resource)
52 .build();
53
54 global::set_meter_provider(meter_provider.clone());
55
56 Ok(MetricsLayer::new(meter_provider))
57}
58
59#[macro_export]
60macro_rules! counter {
69 ($metric:ident $(. $suffixes:ident)* = $metric_value:expr $(, $attrs:ident=$values:expr)*) => {
70 tracing::trace!(counter.$metric $(. $suffixes)* = $metric_value $(, $attrs=$values)*);
71 }
72}
73
74#[macro_export]
75macro_rules! histogram {
84 ($metric:ident $(. $suffixes:ident)* = $metric_value:expr $(, $attrs:ident=$values:expr)*) => {
85 tracing::trace!(histogram.$metric $(. $suffixes)* = $metric_value $(, $attrs=$values)*);
86 }
87}
88
89#[macro_export]
90macro_rules! monotonic_counter {
99 ($metric:ident $(. $suffixes:ident)* = $metric_value:expr $(, $attrs:ident=$values:expr)*) => {
100 tracing::trace!(monotonic_counter.$metric $(. $suffixes)* = $metric_value $(, $attrs=$values)*);
101 }
102}
103
104pub use counter;
105pub use histogram;
106pub use monotonic_counter;