Skip to content

Commit ac0772d

Browse files
authored
Merge branch 'main' into feat/otel_0.26_promo
2 parents 04183d1 + 16c0e10 commit ac0772d

File tree

22 files changed

+256
-247
lines changed

22 files changed

+256
-247
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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use opentelemetry::global;
22
use opentelemetry::Key;
33
use opentelemetry::KeyValue;
4+
use opentelemetry_sdk::metrics::reader::DeltaTemporalitySelector;
45
use opentelemetry_sdk::metrics::{
56
Aggregation, Instrument, PeriodicReader, SdkMeterProvider, Stream,
67
};
@@ -44,7 +45,11 @@ fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
4445
}
4546
};
4647

47-
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default().build();
48+
// Build exporter using Delta Temporality.
49+
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default()
50+
.with_temporality_selector(DeltaTemporalitySelector::new())
51+
.build();
52+
4853
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
4954
let provider = SdkMeterProvider::builder()
5055
.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-otlp/src/metric.rs

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use opentelemetry_sdk::{
1414
metrics::{
1515
data::{ResourceMetrics, Temporality},
1616
exporter::PushMetricsExporter,
17-
reader::{DefaultTemporalitySelector, TemporalitySelector},
17+
reader::{DefaultTemporalitySelector, DeltaTemporalitySelector, TemporalitySelector},
1818
InstrumentKind, PeriodicReader, SdkMeterProvider,
1919
},
2020
runtime::Runtime,
@@ -169,7 +169,7 @@ where
169169
///
170170
/// [exporter-docs]: https://github.com/open-telemetry/opentelemetry-specification/blob/a1c13d59bb7d0fb086df2b3e1eaec9df9efef6cc/specification/metrics/sdk_exporters/otlp.md#additional-configuration
171171
pub fn with_delta_temporality(self) -> Self {
172-
self.with_temporality_selector(DeltaTemporalitySelector)
172+
self.with_temporality_selector(DeltaTemporalitySelector::new())
173173
}
174174
}
175175

@@ -237,35 +237,6 @@ impl<RT, EB: Debug> Debug for OtlpMetricPipeline<RT, EB> {
237237
}
238238
}
239239

240-
/// A temporality selector that returns [`Delta`][Temporality::Delta] for all
241-
/// instruments except `UpDownCounter` and `ObservableUpDownCounter`.
242-
///
243-
/// This temporality selector is equivalent to OTLP Metrics Exporter's
244-
/// `Delta` temporality preference (see [its documentation][exporter-docs]).
245-
///
246-
/// [exporter-docs]: https://github.com/open-telemetry/opentelemetry-specification/blob/a1c13d59bb7d0fb086df2b3e1eaec9df9efef6cc/specification/metrics/sdk_exporters/otlp.md#additional-configuration
247-
#[derive(Debug)]
248-
struct DeltaTemporalitySelector;
249-
250-
impl TemporalitySelector for DeltaTemporalitySelector {
251-
#[rustfmt::skip]
252-
fn temporality(&self, kind: InstrumentKind) -> Temporality {
253-
match kind {
254-
InstrumentKind::Counter
255-
| InstrumentKind::Histogram
256-
| InstrumentKind::ObservableCounter
257-
| InstrumentKind::Gauge
258-
| InstrumentKind::ObservableGauge => {
259-
Temporality::Delta
260-
}
261-
InstrumentKind::UpDownCounter
262-
| InstrumentKind::ObservableUpDownCounter => {
263-
Temporality::Cumulative
264-
}
265-
}
266-
}
267-
}
268-
269240
/// An interface for OTLP metrics clients
270241
#[async_trait]
271242
pub trait MetricsClient: fmt::Debug + Send + Sync + 'static {

opentelemetry-sdk/benches/metric.rs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use opentelemetry_sdk::{
1010
metrics::{
1111
data::{ResourceMetrics, Temporality},
1212
new_view,
13-
reader::{MetricReader, TemporalitySelector},
13+
reader::{DeltaTemporalitySelector, MetricReader, TemporalitySelector},
1414
Aggregation, Instrument, InstrumentKind, ManualReader, Pipeline, SdkMeterProvider, Stream,
1515
View,
1616
},
@@ -44,28 +44,6 @@ impl MetricReader for SharedReader {
4444
}
4545
}
4646

47-
/// Configure delta temporality for all [InstrumentKind]
48-
///
49-
/// [Temporality::Delta] will be used for all instrument kinds if this
50-
/// [TemporalitySelector] is used.
51-
#[derive(Clone, Default, Debug)]
52-
pub struct DeltaTemporalitySelector {
53-
pub(crate) _private: (),
54-
}
55-
56-
impl DeltaTemporalitySelector {
57-
/// Create a new default temporality selector.
58-
pub fn new() -> Self {
59-
Self::default()
60-
}
61-
}
62-
63-
impl TemporalitySelector for DeltaTemporalitySelector {
64-
fn temporality(&self, _kind: InstrumentKind) -> Temporality {
65-
Temporality::Delta
66-
}
67-
}
68-
6947
// * Summary *
7048

7149
// rustc 1.68.0 (2c8cc3432 2023-03-06)

opentelemetry-sdk/src/logs/log_emitter.rs

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use super::{BatchLogProcessor, LogProcessor, LogRecord, SimpleLogProcessor, TraceContext};
22
use crate::{export::logs::LogExporter, runtime::RuntimeChannel, Resource};
3-
use opentelemetry::otel_warn;
43
use opentelemetry::{
5-
global,
64
logs::{LogError, LogResult},
5+
otel_debug,
76
trace::TraceContextExt,
87
Context, InstrumentationLibrary,
98
};
@@ -126,17 +125,10 @@ impl LoggerProvider {
126125
if errs.is_empty() {
127126
Ok(())
128127
} else {
129-
otel_warn!(
130-
name: "logger_provider_shutdown_error",
131-
error = format!("{:?}", errs)
132-
);
133-
Err(LogError::Other(format!("{:?}", errs).into()))
128+
Err(LogError::Other(format!("{errs:?}").into()))
134129
}
135130
} else {
136-
otel_warn!(
137-
name: "logger_provider_already_shutdown"
138-
);
139-
Err(LogError::Other("logger provider already shut down".into()))
131+
Err(LogError::AlreadyShutdown("LoggerProvider".to_string()))
140132
}
141133
}
142134
}
@@ -154,6 +146,24 @@ impl LoggerProviderInner {
154146
let mut errs = vec![];
155147
for processor in &self.processors {
156148
if let Err(err) = processor.shutdown() {
149+
// Log at debug level because:
150+
// - The error is also returned to the user for handling (if applicable)
151+
// - Or the error occurs during `LoggerProviderInner::Drop` as part of telemetry shutdown,
152+
// which is non-actionable by the user
153+
match err {
154+
// specific handling for mutex poisioning
155+
LogError::MutexPoisoned(_) => {
156+
otel_debug!(
157+
name: "LoggerProvider.Drop.ShutdownMutexPoisoned",
158+
);
159+
}
160+
_ => {
161+
otel_debug!(
162+
name: "LoggerProvider.Drop.ShutdownError",
163+
error = format!("{err}")
164+
);
165+
}
166+
}
157167
errs.push(err);
158168
}
159169
}
@@ -164,10 +174,11 @@ impl LoggerProviderInner {
164174
impl Drop for LoggerProviderInner {
165175
fn drop(&mut self) {
166176
if !self.is_shutdown.load(Ordering::Relaxed) {
167-
let errs = self.shutdown();
168-
if !errs.is_empty() {
169-
global::handle_error(LogError::Other(format!("{:?}", errs).into()));
170-
}
177+
let _ = self.shutdown(); // errors are handled within shutdown
178+
} else {
179+
otel_debug!(
180+
name: "LoggerProvider.Drop.AlreadyShutdown"
181+
);
171182
}
172183
}
173184
}

0 commit comments

Comments
 (0)