Skip to content

Commit de54afe

Browse files
authored
Merge branch 'main' into global-error-handler-cleanup-metrics-sdk
2 parents 3aa97cf + a47b429 commit de54afe

File tree

70 files changed

+2687
-1035
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+2687
-1035
lines changed

examples/metrics-advanced/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ publish = false
88
[dependencies]
99
opentelemetry = { path = "../../opentelemetry", features = ["metrics"] }
1010
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["metrics", "rt-tokio"] }
11-
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["metrics"]}
11+
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["metrics"] }
1212
tokio = { workspace = true, features = ["full"] }
1313
serde_json = { workspace = true }

examples/metrics-advanced/src/main.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use opentelemetry::global;
22
use opentelemetry::Key;
33
use opentelemetry::KeyValue;
44
use opentelemetry_sdk::metrics::{
5-
Aggregation, Instrument, PeriodicReader, SdkMeterProvider, Stream,
5+
data::Temporality, Aggregation, Instrument, PeriodicReader, SdkMeterProvider, Stream,
66
};
77
use opentelemetry_sdk::{runtime, Resource};
88
use std::error::Error;
@@ -44,7 +44,11 @@ fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
4444
}
4545
};
4646

47-
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default().build();
47+
// Build exporter using Delta Temporality.
48+
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default()
49+
.with_temporality(Temporality::Delta)
50+
.build();
51+
4852
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
4953
let provider = SdkMeterProvider::builder()
5054
.with_reader(reader)

examples/metrics-basic/src/main.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use std::error::Error;
66
use std::vec;
77

88
fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
9-
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default().build();
9+
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default()
10+
// Build exporter using Delta Temporality (Defaults to Temporality::Cumulative)
11+
// .with_temporality(data::Temporality::Delta)
12+
.build();
1013
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
1114
let provider = SdkMeterProvider::builder()
1215
.with_reader(reader)

opentelemetry-appender-log/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## vNext
44

55
- Bump MSRV to 1.70 [#2179](https://github.com/open-telemetry/opentelemetry-rust/pull/2179)
6+
- [2193](https://github.com/open-telemetry/opentelemetry-rust/pull/2193) `opentelemetry-appender-log`: Output experimental code attributes
67

78
## v0.26.0
89
Released 2024-Sep-30

opentelemetry-appender-log/Cargo.toml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,26 @@ rust-version = "1.70"
1111
edition = "2021"
1212

1313
[dependencies]
14-
opentelemetry = { version = "0.26", path = "../opentelemetry", features = ["logs"]}
15-
log = { workspace = true, features = ["kv", "std"]}
14+
opentelemetry = { version = "0.26", path = "../opentelemetry", features = [
15+
"logs",
16+
] }
17+
log = { workspace = true, features = ["kv", "std"] }
1618
serde = { workspace = true, optional = true, features = ["std"] }
19+
opentelemetry-semantic-conventions = { path = "../opentelemetry-semantic-conventions", optional = true, features = [
20+
"semconv_experimental",
21+
] }
1722

1823
[features]
1924
logs_level_enabled = ["opentelemetry/logs_level_enabled"]
2025
with-serde = ["log/kv_serde", "serde"]
26+
experimental_metadata_attributes = ["dep:opentelemetry-semantic-conventions"]
2127

2228
[dev-dependencies]
23-
opentelemetry_sdk = { path = "../opentelemetry-sdk", features = [ "testing", "logs_level_enabled" ] }
24-
opentelemetry-stdout = { path = "../opentelemetry-stdout", features = ["logs"]}
29+
opentelemetry_sdk = { path = "../opentelemetry-sdk", features = [
30+
"testing",
31+
"logs_level_enabled",
32+
] }
33+
opentelemetry-stdout = { path = "../opentelemetry-stdout", features = ["logs"] }
2534
log = { workspace = true, features = ["kv_serde"] }
2635
tokio = { workspace = true }
2736
serde = { workspace = true, features = ["std", "derive"] }

opentelemetry-appender-log/src/lib.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ use opentelemetry::{
9999
logs::{AnyValue, LogRecord, Logger, LoggerProvider, Severity},
100100
Key,
101101
};
102+
#[cfg(feature = "experimental_metadata_attributes")]
103+
use opentelemetry_semantic_conventions::attribute::{CODE_FILEPATH, CODE_LINENO, CODE_NAMESPACE};
102104
use std::borrow::Cow;
103105

104106
pub struct OpenTelemetryLogBridge<P, L>
@@ -130,6 +132,28 @@ where
130132
log_record.set_severity_number(severity_of_level(record.level()));
131133
log_record.set_severity_text(record.level().as_str());
132134
log_record.set_body(AnyValue::from(record.args().to_string()));
135+
136+
#[cfg(feature = "experimental_metadata_attributes")]
137+
{
138+
if let Some(filepath) = record.file() {
139+
log_record.add_attribute(
140+
Key::new(CODE_FILEPATH),
141+
AnyValue::from(filepath.to_string()),
142+
);
143+
}
144+
145+
if let Some(line_no) = record.line() {
146+
log_record.add_attribute(Key::new(CODE_LINENO), AnyValue::from(line_no));
147+
}
148+
149+
if let Some(module) = record.module_path() {
150+
log_record.add_attribute(
151+
Key::new(CODE_NAMESPACE),
152+
AnyValue::from(module.to_string()),
153+
);
154+
}
155+
}
156+
133157
log_record.add_attributes(log_attributes(record.key_values()));
134158
log_record.set_target(record.metadata().target().to_string());
135159

@@ -1127,6 +1151,54 @@ mod tests {
11271151
}
11281152
}
11291153

1154+
#[cfg(feature = "experimental_metadata_attributes")]
1155+
#[test]
1156+
fn logbridge_code_attributes() {
1157+
use opentelemetry_semantic_conventions::attribute::{
1158+
CODE_FILEPATH, CODE_LINENO, CODE_NAMESPACE,
1159+
};
1160+
1161+
let exporter = InMemoryLogsExporter::default();
1162+
1163+
let logger_provider = LoggerProvider::builder()
1164+
.with_simple_exporter(exporter.clone())
1165+
.build();
1166+
1167+
let otel_log_appender = OpenTelemetryLogBridge::new(&logger_provider);
1168+
1169+
otel_log_appender.log(
1170+
&log::RecordBuilder::new()
1171+
.level(log::Level::Warn)
1172+
.args(format_args!("WARN"))
1173+
.file(Some("src/main.rs"))
1174+
.module_path(Some("service"))
1175+
.line(Some(101))
1176+
.build(),
1177+
);
1178+
1179+
let logs = exporter.get_emitted_logs().unwrap();
1180+
1181+
let get = |needle: &str| -> Option<AnyValue> {
1182+
logs[0].record.attributes_iter().find_map(|(k, v)| {
1183+
if k.as_str() == needle {
1184+
Some(v.clone())
1185+
} else {
1186+
None
1187+
}
1188+
})
1189+
};
1190+
1191+
assert_eq!(
1192+
Some(AnyValue::String(StringValue::from("src/main.rs"))),
1193+
get(CODE_FILEPATH)
1194+
);
1195+
assert_eq!(
1196+
Some(AnyValue::String(StringValue::from("service"))),
1197+
get(CODE_NAMESPACE)
1198+
);
1199+
assert_eq!(Some(AnyValue::Int(101)), get(CODE_LINENO));
1200+
}
1201+
11301202
#[test]
11311203
fn test_flush() {
11321204
let exporter = InMemoryLogsExporter::default();

opentelemetry-appender-tracing/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ tracing-subscriber = { workspace = true, features = ["registry", "std", "env-fil
2626
tracing-log = "0.2"
2727
async-trait = { workspace = true }
2828
criterion = { workspace = true }
29+
tokio = { workspace = true, features = ["full"]}
2930

3031
[target.'cfg(not(target_os = "windows"))'.dev-dependencies]
3132
pprof = { version = "0.13", features = ["flamegraph", "criterion"] }

opentelemetry-appender-tracing/src/layer.rs

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,20 @@ const fn severity_of_level(level: &Level) -> Severity {
208208
#[cfg(test)]
209209
mod tests {
210210
use crate::layer;
211-
use opentelemetry::logs::Severity;
211+
use async_trait::async_trait;
212+
use opentelemetry::logs::{LogResult, Severity};
212213
use opentelemetry::trace::TracerProvider as _;
213214
use opentelemetry::trace::{TraceContextExt, TraceFlags, Tracer};
214215
use opentelemetry::{logs::AnyValue, Key};
216+
use opentelemetry_sdk::export::logs::{LogBatch, LogExporter};
215217
use opentelemetry_sdk::logs::{LogRecord, LoggerProvider};
216218
use opentelemetry_sdk::testing::logs::InMemoryLogsExporter;
217219
use opentelemetry_sdk::trace;
218220
use opentelemetry_sdk::trace::{Sampler, TracerProvider};
219-
use tracing::error;
221+
use tracing::{error, warn};
220222
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
221-
use tracing_subscriber::Layer;
223+
use tracing_subscriber::util::SubscriberInitExt;
224+
use tracing_subscriber::{EnvFilter, Layer};
222225

223226
pub fn attributes_contains(log_record: &LogRecord, key: &Key, value: &AnyValue) -> bool {
224227
log_record
@@ -238,6 +241,70 @@ mod tests {
238241
}
239242

240243
// cargo test --features=testing
244+
245+
#[derive(Clone, Debug, Default)]
246+
struct ReentrantLogExporter;
247+
248+
#[async_trait]
249+
impl LogExporter for ReentrantLogExporter {
250+
async fn export(&mut self, _batch: LogBatch<'_>) -> LogResult<()> {
251+
// This will cause a deadlock as the export itself creates a log
252+
// while still within the lock of the SimpleLogProcessor.
253+
warn!(name: "my-event-name", target: "reentrant", event_id = 20, user_name = "otel", user_email = "[email protected]");
254+
Ok(())
255+
}
256+
}
257+
258+
#[test]
259+
#[ignore = "See issue: https://github.com/open-telemetry/opentelemetry-rust/issues/1745"]
260+
fn simple_processor_deadlock() {
261+
let exporter: ReentrantLogExporter = ReentrantLogExporter;
262+
let logger_provider = LoggerProvider::builder()
263+
.with_simple_exporter(exporter.clone())
264+
.build();
265+
266+
let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
267+
268+
// Setting subscriber as global as that is the only way to test this scenario.
269+
tracing_subscriber::registry().with(layer).init();
270+
warn!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "[email protected]");
271+
}
272+
273+
#[test]
274+
#[ignore = "While this test runs fine, this uses global subscriber and does not play well with other tests."]
275+
fn simple_processor_no_deadlock() {
276+
let exporter: ReentrantLogExporter = ReentrantLogExporter;
277+
let logger_provider = LoggerProvider::builder()
278+
.with_simple_exporter(exporter.clone())
279+
.build();
280+
281+
let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
282+
283+
// This filter will prevent the deadlock as the reentrant log will be
284+
// ignored.
285+
let filter = EnvFilter::new("debug").add_directive("reentrant=error".parse().unwrap());
286+
// Setting subscriber as global as that is the only way to test this scenario.
287+
tracing_subscriber::registry()
288+
.with(filter)
289+
.with(layer)
290+
.init();
291+
warn!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "[email protected]");
292+
}
293+
294+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
295+
#[ignore = "While this test runs fine, this uses global subscriber and does not play well with other tests."]
296+
async fn batch_processor_no_deadlock() {
297+
let exporter: ReentrantLogExporter = ReentrantLogExporter;
298+
let logger_provider = LoggerProvider::builder()
299+
.with_batch_exporter(exporter.clone(), opentelemetry_sdk::runtime::Tokio)
300+
.build();
301+
302+
let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
303+
304+
tracing_subscriber::registry().with(layer).init();
305+
warn!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "[email protected]");
306+
}
307+
241308
#[test]
242309
fn tracing_appender_standalone() {
243310
// Arrange

opentelemetry-otlp/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ Released 2024-Sep-30
1010
- Update `opentelemetry-http` dependency version to 0.26
1111
- Update `opentelemetry-proto` dependency version to 0.26
1212
- Bump MSRV to 1.71.1 [2140](https://github.com/open-telemetry/opentelemetry-rust/pull/2140)
13+
- **BREAKING**: [#2217](https://github.com/open-telemetry/opentelemetry-rust/pull/2217)
14+
- **Replaced**: The `MetricsExporterBuilder` interface is modified from `with_temporality_selector` to `with_temporality` example can be seen below:
15+
Previous Signature:
16+
```rust
17+
MetricsExporterBuilder::default().with_temporality_selector(DeltaTemporalitySelector::new())
18+
```
19+
Updated Signature:
20+
```rust
21+
MetricsExporterBuilder::default().with_temporality(Temporality::Delta)
22+
```
1323

1424
## v0.25.0
1525

opentelemetry-otlp/src/exporter/http/mod.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ use opentelemetry_proto::transform::trace::tonic::group_spans_by_resource_and_sc
1717
use opentelemetry_sdk::export::logs::LogBatch;
1818
#[cfg(feature = "trace")]
1919
use opentelemetry_sdk::export::trace::SpanData;
20-
#[cfg(feature = "metrics")]
21-
use opentelemetry_sdk::metrics::data::ResourceMetrics;
2220
use prost::Message;
2321
use std::collections::HashMap;
2422
use std::env;
@@ -77,9 +75,7 @@ impl Default for HttpConfig {
7775
///
7876
/// ```
7977
/// # #[cfg(feature="metrics")]
80-
/// use opentelemetry_sdk::metrics::reader::{
81-
/// DefaultTemporalitySelector,
82-
/// };
78+
/// use opentelemetry_sdk::metrics::data::Temporality;
8379
///
8480
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
8581
/// // Create a span exporter you can use to when configuring tracer providers
@@ -91,7 +87,7 @@ impl Default for HttpConfig {
9187
/// let metrics_exporter = opentelemetry_otlp::new_exporter()
9288
/// .http()
9389
/// .build_metrics_exporter(
94-
/// Box::new(DefaultTemporalitySelector::new()),
90+
/// Temporality::default(),
9591
/// )?;
9692
///
9793
/// // Create a log exporter you can use when configuring logger providers
@@ -251,7 +247,7 @@ impl HttpExporterBuilder {
251247
#[cfg(feature = "metrics")]
252248
pub fn build_metrics_exporter(
253249
mut self,
254-
temporality_selector: Box<dyn opentelemetry_sdk::metrics::reader::TemporalitySelector>,
250+
temporality: opentelemetry_sdk::metrics::data::Temporality,
255251
) -> opentelemetry::metrics::Result<crate::MetricsExporter> {
256252
use crate::{
257253
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_HEADERS,
@@ -265,7 +261,7 @@ impl HttpExporterBuilder {
265261
OTEL_EXPORTER_OTLP_METRICS_HEADERS,
266262
)?;
267263

268-
Ok(crate::MetricsExporter::new(client, temporality_selector))
264+
Ok(crate::MetricsExporter::new(client, temporality))
269265
}
270266
}
271267

@@ -341,7 +337,7 @@ impl OtlpHttpClient {
341337
#[cfg(feature = "metrics")]
342338
fn build_metrics_export_body(
343339
&self,
344-
metrics: &mut ResourceMetrics,
340+
metrics: &mut opentelemetry_sdk::metrics::data::ResourceMetrics,
345341
) -> opentelemetry::metrics::Result<(Vec<u8>, &'static str)> {
346342
use opentelemetry_proto::tonic::collector::metrics::v1::ExportMetricsServiceRequest;
347343

0 commit comments

Comments
 (0)