Skip to content

Commit 04183d1

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

File tree

16 files changed

+205
-15
lines changed

16 files changed

+205
-15
lines changed

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-sdk/src/metrics/meter.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::{borrow::Cow, sync::Arc};
44
use opentelemetry::{
55
global,
66
metrics::{
7-
noop::{NoopAsyncInstrument, NoopSyncInstrument},
87
AsyncInstrumentBuilder, Counter, Gauge, Histogram, HistogramBuilder, InstrumentBuilder,
98
InstrumentProvider, MetricsError, ObservableCounter, ObservableGauge,
109
ObservableUpDownCounter, Result, UpDownCounter,
@@ -18,6 +17,8 @@ use crate::metrics::{
1817
pipeline::{Pipelines, Resolver},
1918
};
2019

20+
use super::noop::{NoopAsyncInstrument, NoopSyncInstrument};
21+
2122
// maximum length of instrument name
2223
const INSTRUMENT_NAME_MAX_LENGTH: usize = 255;
2324
// maximum length of instrument unit name

opentelemetry-sdk/src/metrics/meter_provider.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ use std::{
99

1010
use opentelemetry::{
1111
global,
12-
metrics::{noop::NoopMeter, Meter, MeterProvider, MetricsError, Result},
12+
metrics::{Meter, MeterProvider, MetricsError, Result},
1313
KeyValue,
1414
};
1515

1616
use crate::{instrumentation::Scope, Resource};
1717

18-
use super::{meter::SdkMeter, pipeline::Pipelines, reader::MetricReader, view::View};
18+
use super::{
19+
meter::SdkMeter, noop::NoopMeter, pipeline::Pipelines, reader::MetricReader, view::View,
20+
};
1921

2022
/// Handles the creation and coordination of [Meter]s.
2123
///

opentelemetry-sdk/src/metrics/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub(crate) mod internal;
4747
pub(crate) mod manual_reader;
4848
pub(crate) mod meter;
4949
mod meter_provider;
50+
pub(crate) mod noop;
5051
pub(crate) mod periodic_reader;
5152
pub(crate) mod pipeline;
5253
pub mod reader;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use opentelemetry::{
2+
metrics::{
3+
AsyncInstrument, InstrumentProvider, SyncCounter, SyncGauge, SyncHistogram,
4+
SyncUpDownCounter,
5+
},
6+
KeyValue,
7+
};
8+
9+
/// A no-op instance of a `Meter`
10+
#[derive(Debug, Default)]
11+
pub(crate) struct NoopMeter {
12+
_private: (),
13+
}
14+
15+
impl NoopMeter {
16+
/// Create a new no-op meter core.
17+
pub(crate) fn new() -> Self {
18+
NoopMeter { _private: () }
19+
}
20+
}
21+
22+
impl InstrumentProvider for NoopMeter {}
23+
24+
/// A no-op sync instrument
25+
#[derive(Debug, Default)]
26+
pub(crate) struct NoopSyncInstrument {
27+
_private: (),
28+
}
29+
30+
impl NoopSyncInstrument {
31+
/// Create a new no-op sync instrument
32+
pub(crate) fn new() -> Self {
33+
NoopSyncInstrument { _private: () }
34+
}
35+
}
36+
37+
impl<T> SyncCounter<T> for NoopSyncInstrument {
38+
fn add(&self, _value: T, _attributes: &[KeyValue]) {
39+
// Ignored
40+
}
41+
}
42+
43+
impl<T> SyncUpDownCounter<T> for NoopSyncInstrument {
44+
fn add(&self, _value: T, _attributes: &[KeyValue]) {
45+
// Ignored
46+
}
47+
}
48+
49+
impl<T> SyncHistogram<T> for NoopSyncInstrument {
50+
fn record(&self, _value: T, _attributes: &[KeyValue]) {
51+
// Ignored
52+
}
53+
}
54+
55+
impl<T> SyncGauge<T> for NoopSyncInstrument {
56+
fn record(&self, _value: T, _attributes: &[KeyValue]) {
57+
// Ignored
58+
}
59+
}
60+
61+
/// A no-op async instrument.
62+
#[derive(Debug, Default)]
63+
pub(crate) struct NoopAsyncInstrument {
64+
_private: (),
65+
}
66+
67+
impl NoopAsyncInstrument {
68+
/// Create a new no-op async instrument
69+
pub(crate) fn new() -> Self {
70+
NoopAsyncInstrument { _private: () }
71+
}
72+
}
73+
74+
impl<T> AsyncInstrument<T> for NoopAsyncInstrument {
75+
fn observe(&self, _value: T, _attributes: &[KeyValue]) {
76+
// Ignored
77+
}
78+
}

opentelemetry/src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub enum Value {
227227
}
228228

229229
/// Wrapper for string-like values
230-
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
230+
#[derive(Clone, PartialEq, Eq, Hash)]
231231
pub struct StringValue(OtelString);
232232

233233
impl fmt::Debug for StringValue {

opentelemetry/src/global/internal_logging.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,20 @@ macro_rules! otel_info {
2323
{
2424
tracing::info!( name: $name, target: env!("CARGO_PKG_NAME"), "");
2525
}
26+
#[cfg(not(feature = "internal-logs"))]
27+
{
28+
let _ = $name; // Compiler will optimize this out as it's unused.
29+
}
2630
};
2731
(name: $name:expr, $($key:ident = $value:expr),+ $(,)?) => {
2832
#[cfg(feature = "internal-logs")]
2933
{
3034
tracing::info!(name: $name, target: env!("CARGO_PKG_NAME"), $($key = $value),+, "");
3135
}
36+
#[cfg(not(feature = "internal-logs"))]
37+
{
38+
let _ = ($name, $($value),+); // Compiler will optimize this out as it's unused.
39+
}
3240
};
3341
}
3442

@@ -50,12 +58,20 @@ macro_rules! otel_warn {
5058
{
5159
tracing::warn!(name: $name, target: env!("CARGO_PKG_NAME"), "");
5260
}
61+
#[cfg(not(feature = "internal-logs"))]
62+
{
63+
let _ = $name; // Compiler will optimize this out as it's unused.
64+
}
5365
};
5466
(name: $name:expr, $($key:ident = $value:expr),+ $(,)?) => {
5567
#[cfg(feature = "internal-logs")]
5668
{
5769
tracing::warn!(name: $name, target: env!("CARGO_PKG_NAME"), $($key = $value),+, "");
5870
}
71+
#[cfg(not(feature = "internal-logs"))]
72+
{
73+
let _ = ($name, $($value),+); // Compiler will optimize this out as it's unused.
74+
}
5975
};
6076
}
6177

@@ -77,12 +93,20 @@ macro_rules! otel_debug {
7793
{
7894
tracing::debug!(name: $name, target: env!("CARGO_PKG_NAME"),"");
7995
}
96+
#[cfg(not(feature = "internal-logs"))]
97+
{
98+
let _ = $name; // Compiler will optimize this out as it's unused.
99+
}
80100
};
81101
(name: $name:expr, $($key:ident = $value:expr),+ $(,)?) => {
82102
#[cfg(feature = "internal-logs")]
83103
{
84104
tracing::debug!(name: $name, target: env!("CARGO_PKG_NAME"), $($key = $value),+, "");
85105
}
106+
#[cfg(not(feature = "internal-logs"))]
107+
{
108+
let _ = ($name, $($value),+); // Compiler will optimize this out as it's unused.
109+
}
86110
};
87111
}
88112

@@ -104,11 +128,19 @@ macro_rules! otel_error {
104128
{
105129
tracing::error!(name: $name, target: env!("CARGO_PKG_NAME"), "");
106130
}
131+
#[cfg(not(feature = "internal-logs"))]
132+
{
133+
let _ = $name; // Compiler will optimize this out as it's unused.
134+
}
107135
};
108136
(name: $name:expr, $($key:ident = $value:expr),+ $(,)?) => {
109137
#[cfg(feature = "internal-logs")]
110138
{
111139
tracing::error!(name: $name, target: env!("CARGO_PKG_NAME"), $($key = $value),+, "");
112140
}
141+
#[cfg(not(feature = "internal-logs"))]
142+
{
143+
let _ = ($name, $($value),+); // Compiler will optimize this out as it's unused.
144+
}
113145
};
114146
}

opentelemetry/src/global/metrics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type GlobalMeterProvider = Arc<dyn MeterProvider + Send + Sync>;
77

88
/// The global `MeterProvider` singleton.
99
static GLOBAL_METER_PROVIDER: Lazy<RwLock<GlobalMeterProvider>> =
10-
Lazy::new(|| RwLock::new(Arc::new(metrics::noop::NoopMeterProvider::new())));
10+
Lazy::new(|| RwLock::new(Arc::new(crate::metrics::noop::NoopMeterProvider::new())));
1111

1212
/// Sets the given [`MeterProvider`] instance as the current global meter
1313
/// provider.

opentelemetry/src/metrics/instruments/counter.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub trait SyncCounter<T> {
1010

1111
/// An instrument that records increasing values.
1212
#[derive(Clone)]
13+
#[non_exhaustive]
1314
pub struct Counter<T>(Arc<dyn SyncCounter<T> + Send + Sync>);
1415

1516
impl<T> fmt::Debug for Counter<T>
@@ -35,6 +36,7 @@ impl<T> Counter<T> {
3536

3637
/// An async instrument that records increasing values.
3738
#[derive(Clone)]
39+
#[non_exhaustive]
3840
pub struct ObservableCounter<T>(Arc<dyn AsyncInstrument<T>>);
3941

4042
impl<T> ObservableCounter<T> {

0 commit comments

Comments
 (0)