Skip to content

Commit 56ae8ad

Browse files
authored
upgrade to opentelemetry 0.30 (#54)
1 parent f84e5a7 commit 56ae8ad

File tree

5 files changed

+98
-128
lines changed

5 files changed

+98
-128
lines changed

Cargo.toml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ env_filter = "0.1"
1515

1616
# deps for grpc export
1717
http = { version = "1.2", optional = true }
18-
tonic = { version = "0.12", optional = true }
18+
tonic = { version = "0.13", optional = true }
1919

2020
rand = "0.9.0"
2121

22-
opentelemetry = { version = "0.29", default-features = false, features = ["trace"] }
23-
opentelemetry_sdk = { version = "0.29", default-features = false, features = ["trace"] }
24-
opentelemetry-otlp = { version = "0.29", default-features = false, features = ["trace", "metrics"] }
22+
opentelemetry = { version = "0.30", default-features = false, features = ["trace"] }
23+
opentelemetry_sdk = { version = "0.30", default-features = false, features = ["trace", "experimental_metrics_custom_reader"] }
24+
opentelemetry-otlp = { version = "0.30", default-features = false, features = ["trace", "metrics"] }
2525
futures-util = "0.3"
2626

2727
tracing = "0.1"
2828
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
29-
tracing-opentelemetry = "0.30"
29+
tracing-opentelemetry = "0.31"
3030

3131
thiserror = "2"
3232

@@ -38,15 +38,14 @@ regex = "1.11.1"
3838
[dev-dependencies]
3939
async-trait = "0.1.88"
4040
insta = "1.42.1"
41-
opentelemetry_sdk = { version = "0.29", default-features = false, features = ["testing"] }
41+
opentelemetry_sdk = { version = "0.30", default-features = false, features = ["testing"] }
4242
regex = "1.11.1"
4343
tokio = {version = "1.44.1", features = ["test-util"] }
4444
ulid = "1.2.0"
4545

4646
[features]
4747
default = ["export-http-protobuf"]
4848
serde = ["dep:serde"]
49-
# FIXME might need rustls feature on all of these?
5049
export-grpc = ["opentelemetry-otlp/grpc-tonic", "opentelemetry-otlp/tls", "dep:http", "dep:tonic"]
5150
export-http-protobuf = ["opentelemetry-otlp/http-proto", "opentelemetry-otlp/reqwest-blocking-client", "opentelemetry-otlp/reqwest-rustls"]
5251
export-http-json = ["opentelemetry-otlp/http-json", "opentelemetry-otlp/reqwest-blocking-client", "opentelemetry-otlp/reqwest-rustls"]

src/config.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,13 @@ impl SpanProcessor for BoxedSpanProcessor {
311311
self.0.shutdown()
312312
}
313313

314+
fn shutdown_with_timeout(
315+
&self,
316+
timeout: std::time::Duration,
317+
) -> opentelemetry_sdk::error::OTelSdkResult {
318+
self.0.shutdown_with_timeout(timeout)
319+
}
320+
314321
fn set_resource(&mut self, resource: &opentelemetry_sdk::Resource) {
315322
self.0.set_resource(resource);
316323
}
@@ -354,7 +361,7 @@ impl MetricReader for BoxedMetricReader {
354361
fn collect(
355362
&self,
356363
rm: &mut opentelemetry_sdk::metrics::data::ResourceMetrics,
357-
) -> opentelemetry_sdk::metrics::MetricResult<()> {
364+
) -> opentelemetry_sdk::error::OTelSdkResult {
358365
self.0.collect(rm)
359366
}
360367

@@ -366,6 +373,13 @@ impl MetricReader for BoxedMetricReader {
366373
self.0.shutdown()
367374
}
368375

376+
fn shutdown_with_timeout(
377+
&self,
378+
timeout: std::time::Duration,
379+
) -> opentelemetry_sdk::error::OTelSdkResult {
380+
self.0.shutdown_with_timeout(timeout)
381+
}
382+
369383
fn temporality(
370384
&self,
371385
kind: opentelemetry_sdk::metrics::InstrumentKind,

src/lib.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,6 @@ pub enum ConfigureError {
152152
#[error("Error configuring the global logger: {0}")]
153153
Logging(#[from] log::SetLoggerError),
154154

155-
/// Error configuring the OpenTelemetry metrics.
156-
#[error("Error configuring the OpenTelemetry metrics: {0}")]
157-
Metrics(#[from] opentelemetry_sdk::metrics::MetricError),
158-
159155
/// Error configuring the OpenTelemetry tracer.
160156
#[error("Error configuring the OpenTelemetry tracer: {0}")]
161157
Trace(#[from] opentelemetry_sdk::trace::TraceError),

src/test_utils.rs

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,14 @@ use std::{
1111
time::{self, SystemTime},
1212
};
1313

14-
use async_trait::async_trait;
1514
use opentelemetry::{
16-
Value,
15+
InstrumentationScope, Value,
1716
trace::{SpanId, TraceId},
1817
};
1918
use opentelemetry_sdk::{
19+
Resource,
2020
error::OTelSdkResult,
21-
metrics::{
22-
Temporality,
23-
data::{ResourceMetrics, Sum},
24-
exporter::PushMetricExporter,
25-
},
21+
metrics::data::{AggregatedMetrics, MetricData, ResourceMetrics},
2622
trace::{IdGenerator, SpanData, SpanExporter},
2723
};
2824
use regex::{Captures, Regex};
@@ -127,45 +123,6 @@ impl<Inner: SpanExporter> SpanExporter for DeterministicExporter<Inner> {
127123
}
128124
}
129125

130-
#[async_trait]
131-
impl<Inner: PushMetricExporter> PushMetricExporter for DeterministicExporter<Inner> {
132-
fn export(&self, metrics: &mut ResourceMetrics) -> impl Future<Output = OTelSdkResult> {
133-
async move {
134-
let timestamp_remap = self.timestamp_remap.clone();
135-
for scope in &mut metrics.scope_metrics {
136-
for metric in &mut scope.metrics {
137-
if let Some(sum) = (*metric.data).as_mut().downcast_mut::<Sum<u64>>() {
138-
sum.start_time = timestamp_remap
139-
.lock()
140-
.unwrap()
141-
.remap_timestamp(sum.start_time);
142-
sum.time = timestamp_remap.lock().unwrap().remap_timestamp(sum.time);
143-
144-
for data_point in &mut sum.data_points {
145-
data_point
146-
.attributes
147-
.sort_by_cached_key(|kv| kv.key.to_string());
148-
}
149-
}
150-
}
151-
}
152-
self.exporter.export(metrics).await
153-
}
154-
}
155-
156-
fn force_flush(&self) -> OTelSdkResult {
157-
self.exporter.force_flush()
158-
}
159-
160-
fn shutdown(&self) -> OTelSdkResult {
161-
self.exporter.shutdown()
162-
}
163-
164-
fn temporality(&self) -> Temporality {
165-
self.exporter.temporality()
166-
}
167-
}
168-
169126
impl<Inner> DeterministicExporter<Inner> {
170127
/// Create deterministic exporter, feeding it current file and line.
171128
pub fn new(exporter: Inner, file: &'static str, line_offset: u32) -> Self {
@@ -219,3 +176,47 @@ pub fn remap_timestamps_in_console_output(output: &str) -> Cow<'_, str> {
219176
replaced
220177
})
221178
}
179+
180+
pub fn make_deterministic_resource_metrics(
181+
metrics: Vec<ResourceMetrics>,
182+
) -> Vec<DeterministicResourceMetrics> {
183+
metrics
184+
.into_iter()
185+
.map(|metric| DeterministicResourceMetrics {
186+
resource: metric.resource().clone(),
187+
scope_metrics: metric
188+
.scope_metrics()
189+
.map(|scope_metric| DeterministicScopeMetrics {
190+
scope: scope_metric.scope().clone(),
191+
sum_metrics: scope_metric
192+
.metrics()
193+
.filter_map(|metric| {
194+
if let AggregatedMetrics::U64(MetricData::Sum(sum)) = metric.data() {
195+
Some(sum.data_points().map(|dp| dp.value()).collect())
196+
} else {
197+
None
198+
}
199+
})
200+
.collect(),
201+
})
202+
.collect(),
203+
})
204+
.collect()
205+
}
206+
207+
/// A reproduction of the `ScopeMetrics` type from the otel sdk, narrowed to u64 sum metrics
208+
///
209+
/// This exists because the otel SDK (as of version 0.30) exposes no way to create a `ScopeMetrics`
210+
/// outside of the library.
211+
#[derive(Debug)]
212+
pub struct DeterministicScopeMetrics {
213+
scope: InstrumentationScope,
214+
sum_metrics: Vec<Vec<u64>>,
215+
}
216+
217+
/// Deterministic resource metrics
218+
#[derive(Debug)]
219+
pub struct DeterministicResourceMetrics {
220+
resource: Resource,
221+
scope_metrics: Vec<DeterministicScopeMetrics>,
222+
}

tests/test_basic_exports.rs

Lines changed: 30 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ use logfire::{
2121
#[path = "../src/test_utils.rs"]
2222
mod test_utils;
2323

24-
use test_utils::{DeterministicExporter, DeterministicIdGenerator};
24+
use test_utils::{
25+
DeterministicExporter, DeterministicIdGenerator, make_deterministic_resource_metrics,
26+
};
2527

2628
#[expect(clippy::too_many_lines)]
2729
#[test]
@@ -965,7 +967,7 @@ fn test_basic_span() {
965967
),
966968
value: String(
967969
Owned(
968-
"tests/test_basic_exports.rs:56:13",
970+
"tests/test_basic_exports.rs:58:13",
969971
),
970972
),
971973
},
@@ -1032,7 +1034,7 @@ fn test_basic_span() {
10321034
"code.lineno",
10331035
),
10341036
value: I64(
1035-
694,
1037+
690,
10361038
),
10371039
},
10381040
KeyValue {
@@ -1240,13 +1242,8 @@ impl SharedManualReader {
12401242
}
12411243

12421244
async fn export<E: PushMetricExporter>(&self, exporter: &E) {
1243-
let mut metrics = ResourceMetrics {
1244-
resource: Resource::builder_empty().build(),
1245-
scope_metrics: Vec::new(),
1246-
};
1247-
dbg!(&metrics);
1245+
let mut metrics = ResourceMetrics::default();
12481246
self.reader.collect(&mut metrics).unwrap();
1249-
dbg!(&metrics);
12501247
exporter.export(&mut metrics).await.unwrap();
12511248
}
12521249
}
@@ -1259,7 +1256,7 @@ impl MetricReader for SharedManualReader {
12591256
fn collect(
12601257
&self,
12611258
rm: &mut opentelemetry_sdk::metrics::data::ResourceMetrics,
1262-
) -> opentelemetry_sdk::metrics::MetricResult<()> {
1259+
) -> opentelemetry_sdk::error::OTelSdkResult {
12631260
self.reader.collect(rm)
12641261
}
12651262

@@ -1271,6 +1268,13 @@ impl MetricReader for SharedManualReader {
12711268
self.reader.shutdown()
12721269
}
12731270

1271+
fn shutdown_with_timeout(
1272+
&self,
1273+
timeout: std::time::Duration,
1274+
) -> opentelemetry_sdk::error::OTelSdkResult {
1275+
self.reader.shutdown_with_timeout(timeout)
1276+
}
1277+
12741278
fn temporality(
12751279
&self,
12761280
kind: opentelemetry_sdk::metrics::InstrumentKind,
@@ -1281,11 +1285,7 @@ impl MetricReader for SharedManualReader {
12811285

12821286
#[tokio::test]
12831287
async fn test_basic_metrics() {
1284-
let mut exporter = DeterministicExporter::new(
1285-
InMemoryMetricExporterBuilder::new().build(),
1286-
file!(),
1287-
line!(),
1288-
);
1288+
let mut exporter = InMemoryMetricExporterBuilder::new().build();
12891289

12901290
let reader = SharedManualReader::new(
12911291
ManualReader::builder()
@@ -1323,11 +1323,13 @@ async fn test_basic_metrics() {
13231323

13241324
handler.shutdown().unwrap();
13251325

1326-
let metrics = exporter.inner().get_finished_metrics().unwrap();
1326+
let metrics = exporter.get_finished_metrics().unwrap();
1327+
1328+
let metrics = make_deterministic_resource_metrics(metrics);
13271329

13281330
assert_debug_snapshot!(metrics, @r#"
13291331
[
1330-
ResourceMetrics {
1332+
DeterministicResourceMetrics {
13311333
resource: Resource {
13321334
inner: ResourceInner {
13331335
attrs: {
@@ -1343,43 +1345,22 @@ async fn test_basic_metrics() {
13431345
},
13441346
},
13451347
scope_metrics: [
1346-
ScopeMetrics {
1348+
DeterministicScopeMetrics {
13471349
scope: InstrumentationScope {
13481350
name: "logfire",
13491351
version: None,
13501352
schema_url: None,
13511353
attributes: [],
13521354
},
1353-
metrics: [
1354-
Metric {
1355-
name: "basic_counter",
1356-
description: "",
1357-
unit: "",
1358-
data: Sum {
1359-
data_points: [
1360-
SumDataPoint {
1361-
attributes: [],
1362-
value: 1,
1363-
exemplars: [],
1364-
},
1365-
],
1366-
start_time: SystemTime {
1367-
tv_sec: 0,
1368-
tv_nsec: 0,
1369-
},
1370-
time: SystemTime {
1371-
tv_sec: 1,
1372-
tv_nsec: 0,
1373-
},
1374-
temporality: Delta,
1375-
is_monotonic: true,
1376-
},
1377-
},
1355+
sum_metrics: [
1356+
[
1357+
1,
1358+
],
13781359
],
13791360
},
13801361
],
13811362
},
1382-
ResourceMetrics {
1363+
DeterministicResourceMetrics {
13831364
resource: Resource {
13841365
inner: ResourceInner {
13851366
attrs: {
@@ -1395,38 +1376,17 @@ async fn test_basic_metrics() {
13951376
},
13961377
},
13971378
scope_metrics: [
1398-
ScopeMetrics {
1379+
DeterministicScopeMetrics {
13991380
scope: InstrumentationScope {
14001381
name: "logfire",
14011382
version: None,
14021383
schema_url: None,
14031384
attributes: [],
14041385
},
1405-
metrics: [
1406-
Metric {
1407-
name: "basic_counter",
1408-
description: "",
1409-
unit: "",
1410-
data: Sum {
1411-
data_points: [
1412-
SumDataPoint {
1413-
attributes: [],
1414-
value: 2,
1415-
exemplars: [],
1416-
},
1417-
],
1418-
start_time: SystemTime {
1419-
tv_sec: 1,
1420-
tv_nsec: 0,
1421-
},
1422-
time: SystemTime {
1423-
tv_sec: 2,
1424-
tv_nsec: 0,
1425-
},
1426-
temporality: Delta,
1427-
is_monotonic: true,
1428-
},
1429-
},
1386+
sum_metrics: [
1387+
[
1388+
2,
1389+
],
14301390
],
14311391
},
14321392
],

0 commit comments

Comments
 (0)