From d407cbffbc93532ce76546d5138834b6d5954cf8 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 14 Nov 2024 20:30:15 -0800 Subject: [PATCH] Update Metric-Etw exporter to use 0.27 of api and sdk (#128) --- opentelemetry-etw-metrics/CHANGELOG.md | 5 ++ opentelemetry-etw-metrics/Cargo.toml | 6 +- opentelemetry-etw-metrics/examples/basic.rs | 2 +- opentelemetry-etw-metrics/src/etw/mod.rs | 12 +-- opentelemetry-etw-metrics/src/exporter/mod.rs | 74 +++++++------------ 5 files changed, 37 insertions(+), 62 deletions(-) diff --git a/opentelemetry-etw-metrics/CHANGELOG.md b/opentelemetry-etw-metrics/CHANGELOG.md index c4f53d91..8a7e3fa4 100644 --- a/opentelemetry-etw-metrics/CHANGELOG.md +++ b/opentelemetry-etw-metrics/CHANGELOG.md @@ -2,6 +2,11 @@ ## vNext +- Bump opentelemetry and opentelemetry_sdk versions to 0.27 +- Bump opentelemetry-proto version to 0.27 +- Uses internal logging from `opentelemetry` crate, which routes internal logs + via `tracing`. + ## v0.5.0 ### Changed diff --git a/opentelemetry-etw-metrics/Cargo.toml b/opentelemetry-etw-metrics/Cargo.toml index 6ea69e55..bb176ee9 100644 --- a/opentelemetry-etw-metrics/Cargo.toml +++ b/opentelemetry-etw-metrics/Cargo.toml @@ -11,9 +11,9 @@ license = "Apache-2.0" rust-version = "1.71.1" [dependencies] -opentelemetry = { workspace = true, features = ["metrics"] } -opentelemetry_sdk = { workspace = true, features = ["metrics", "rt-tokio"] } -opentelemetry-proto = { workspace = true, features = ["gen-tonic", "metrics"] } +opentelemetry = { version = "0.27", features = ["metrics"] } +opentelemetry_sdk = { version = "0.27", features = ["metrics", "rt-tokio"] } +opentelemetry-proto = { version = "0.27", features = ["gen-tonic", "metrics"] } async-trait = "0.1" prost = "0.13" tracelogging = "1.2.1" diff --git a/opentelemetry-etw-metrics/examples/basic.rs b/opentelemetry-etw-metrics/examples/basic.rs index 88608aac..79be9402 100644 --- a/opentelemetry-etw-metrics/examples/basic.rs +++ b/opentelemetry-etw-metrics/examples/basic.rs @@ -30,7 +30,7 @@ async fn main() -> Result<(), Box> { .f64_counter("MyFruitCounter") .with_description("test_description") .with_unit("test_unit") - .init(); + .build(); c.add( 1.0, diff --git a/opentelemetry-etw-metrics/src/etw/mod.rs b/opentelemetry-etw-metrics/src/etw/mod.rs index 857828d4..1dfd65e8 100644 --- a/opentelemetry-etw-metrics/src/etw/mod.rs +++ b/opentelemetry-etw-metrics/src/etw/mod.rs @@ -1,4 +1,4 @@ -use opentelemetry::{global, metrics::MetricsError}; +use opentelemetry::otel_warn; use tracelogging as tlg; @@ -27,10 +27,7 @@ pub fn register() { ETW_PROVIDER_REGISTRANT.call_once(|| { let result = unsafe { PROVIDER.register() }; if result != 0 { - global::handle_error(MetricsError::Other(format!( - "Failed to register ETW provider with error code: {}", - result - ))); + otel_warn!(name: "MetricExporter.EtwRegisterFailed", error_code = result); } }); } @@ -51,10 +48,7 @@ pub fn unregister() { if ETW_PROVIDER_REGISTRANT.is_completed() { let result = PROVIDER.unregister(); if result != 0 { - global::handle_error(MetricsError::Other(format!( - "Failed to unregister ETW provider with error code: {}", - result - ))); + otel_warn!(name: "MetricExporter.EtwUnRegisterFailed", error_code = result); } } } diff --git a/opentelemetry-etw-metrics/src/exporter/mod.rs b/opentelemetry-etw-metrics/src/exporter/mod.rs index d450bcea..26a6155c 100644 --- a/opentelemetry-etw-metrics/src/exporter/mod.rs +++ b/opentelemetry-etw-metrics/src/exporter/mod.rs @@ -1,16 +1,13 @@ -use opentelemetry::{ - global, - metrics::{MetricsError, Result}, -}; +use opentelemetry::otel_warn; + use opentelemetry_proto::tonic::collector::metrics::v1::ExportMetricsServiceRequest; use opentelemetry_sdk::metrics::{ data::{ self, ExponentialBucket, ExponentialHistogramDataPoint, Metric, ResourceMetrics, - ScopeMetrics, Temporality, + ScopeMetrics, }, - exporter::PushMetricsExporter, - reader::TemporalitySelector, - InstrumentKind, + exporter::PushMetricExporter, + MetricError, MetricResult, Temporality, }; use prost::Message; @@ -36,21 +33,6 @@ impl Default for MetricsExporter { } } -impl TemporalitySelector for MetricsExporter { - fn temporality(&self, kind: InstrumentKind) -> Temporality { - match kind { - InstrumentKind::Counter - | InstrumentKind::ObservableCounter - | InstrumentKind::ObservableGauge - | InstrumentKind::Histogram - | InstrumentKind::Gauge => Temporality::Delta, - InstrumentKind::UpDownCounter | InstrumentKind::ObservableUpDownCounter => { - Temporality::Cumulative - } - } - } -} - impl Debug for MetricsExporter { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str("ETW metrics exporter") @@ -58,8 +40,8 @@ impl Debug for MetricsExporter { } #[async_trait] -impl PushMetricsExporter for MetricsExporter { - async fn export(&self, metrics: &mut ResourceMetrics) -> Result<()> { +impl PushMetricExporter for MetricsExporter { + async fn export(&self, metrics: &mut ResourceMetrics) -> MetricResult<()> { for scope_metric in &metrics.scope_metrics { for metric in &scope_metric.metrics { let mut resource_metrics = Vec::new(); @@ -296,10 +278,7 @@ impl PushMetricsExporter for MetricsExporter { resource_metrics.push(resource_metric); } } else { - global::handle_error(MetricsError::Other(format!( - "Unsupported aggregation type: {:?}", - data - ))); + otel_warn!(name: "MetricExportFailedDueToUnsupportedMetricType", metric_type = format!("{:?}", data)); } for resource_metric in resource_metrics { @@ -307,14 +286,10 @@ impl PushMetricsExporter for MetricsExporter { let proto_message: ExportMetricsServiceRequest = (&resource_metric).into(); proto_message .encode(&mut byte_array) - .map_err(|err| MetricsError::Other(err.to_string()))?; + .map_err(|err| MetricError::Other(err.to_string()))?; if (byte_array.len()) > etw::MAX_EVENT_SIZE { - global::handle_error(MetricsError::Other(format!( - "Exporting failed due to event size {} exceeding the maximum size of {} bytes", - byte_array.len(), - etw::MAX_EVENT_SIZE - ))); + otel_warn!(name: "MetricExportFailedDueToMaxSizeLimit", size = byte_array.len(), max_size = etw::MAX_EVENT_SIZE); } else { let result = etw::write(&byte_array); // TODO: Better logging/internal metrics needed here for non-failure @@ -322,10 +297,7 @@ impl PushMetricsExporter for MetricsExporter { // better logging solution is implemented // println!("Exported {} bytes to ETW", byte_array.len()); if result != 0 { - global::handle_error(MetricsError::Other(format!( - "Failed to write ETW event with error code: {}", - result - ))); + otel_warn!(name: "MetricExportFailed", error_code = result); } } } @@ -335,15 +307,19 @@ impl PushMetricsExporter for MetricsExporter { Ok(()) } - async fn force_flush(&self) -> Result<()> { + async fn force_flush(&self) -> MetricResult<()> { Ok(()) } - fn shutdown(&self) -> Result<()> { + fn shutdown(&self) -> MetricResult<()> { etw::unregister(); Ok(()) } + + fn temporality(&self) -> Temporality { + Temporality::Delta + } } #[cfg(test)] @@ -374,49 +350,49 @@ mod tests { .u64_histogram("Testu64Histogram") .with_description("u64_histogram_test_description") .with_unit("u64_histogram_test_unit") - .init(); + .build(); let f64_histogram = meter .f64_histogram("TestHistogram") .with_description("f64_histogram_test_description") .with_unit("f64_histogram_test_unit") - .init(); + .build(); let u64_counter = meter .u64_counter("Testu64Counter") .with_description("u64_counter_test_description") .with_unit("u64_counter_test_units") - .init(); + .build(); let f64_counter = meter .f64_counter("Testf64Counter") .with_description("f64_counter_test_description") .with_unit("f64_counter_test_units") - .init(); + .build(); let i64_counter = meter .i64_up_down_counter("Testi64Counter") .with_description("i64_counter_test_description") .with_unit("i64_counter_test_units") - .init(); + .build(); let u64_gauge = meter .u64_gauge("Testu64Gauge") .with_description("u64_gauge_test_description") .with_unit("u64_gauge_test_unit") - .init(); + .build(); let i64_gauge = meter .i64_gauge("Testi64Gauge") .with_description("i64_gauge_test_description") .with_unit("i64_gauge_test_unit") - .init(); + .build(); let f64_gauge = meter .f64_gauge("Testf64Gauge") .with_description("f64_gauge_test_description") .with_unit("f64_gauge_test_unit") - .init(); + .build(); // Create a key that is 1/10th the size of the MAX_EVENT_SIZE let key_size = etw::MAX_EVENT_SIZE / 10;