Skip to content

Commit 91f44ff

Browse files
authored
Remove Global Error handler. (#2260)
1 parent eca53b2 commit 91f44ff

File tree

4 files changed

+43
-121
lines changed

4 files changed

+43
-121
lines changed

examples/self-diagnostics/src/main.rs

+36-79
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,18 @@
1-
use opentelemetry::global::{self, set_error_handler, Error as OtelError};
1+
use opentelemetry::global::{self, Error as OtelError};
22
use opentelemetry::KeyValue;
33
use opentelemetry_appender_tracing::layer;
44
use opentelemetry_otlp::{LogExporter, MetricExporter, WithExportConfig};
55
use opentelemetry_sdk::metrics::PeriodicReader;
6-
use tracing_subscriber::filter::{EnvFilter, LevelFilter};
7-
use tracing_subscriber::fmt;
86
use tracing_subscriber::prelude::*;
97

108
use std::error::Error;
11-
use tracing::error;
129

1310
use once_cell::sync::Lazy;
1411
use std::collections::HashSet;
1512
use std::sync::{Arc, Mutex};
1613

1714
use std::sync::mpsc::channel;
1815

19-
struct ErrorState {
20-
seen_errors: Mutex<HashSet<String>>,
21-
}
22-
23-
impl ErrorState {
24-
fn new() -> Self {
25-
ErrorState {
26-
seen_errors: Mutex::new(HashSet::new()),
27-
}
28-
}
29-
30-
fn mark_as_seen(&self, err: &OtelError) -> bool {
31-
let mut seen_errors = self.seen_errors.lock().unwrap();
32-
seen_errors.insert(err.to_string())
33-
}
34-
}
35-
36-
static GLOBAL_ERROR_STATE: Lazy<Arc<ErrorState>> = Lazy::new(|| Arc::new(ErrorState::new()));
37-
38-
fn custom_error_handler(err: OtelError) {
39-
if GLOBAL_ERROR_STATE.mark_as_seen(&err) {
40-
// log error not already seen
41-
match err {
42-
OtelError::Metric(err) => error!("OpenTelemetry metrics error occurred: {}", err),
43-
OtelError::Trace(err) => error!("OpenTelemetry trace error occurred: {}", err),
44-
OtelError::Log(err) => error!("OpenTelemetry log error occurred: {}", err),
45-
OtelError::Propagation(err) => {
46-
error!("OpenTelemetry propagation error occurred: {}", err)
47-
}
48-
OtelError::Other(err_msg) => error!("OpenTelemetry error occurred: {}", err_msg),
49-
_ => error!("OpenTelemetry error occurred: {:?}", err),
50-
}
51-
}
52-
}
53-
5416
fn init_logger_provider() -> opentelemetry_sdk::logs::LoggerProvider {
5517
let exporter = LogExporter::builder()
5618
.with_http()
@@ -64,46 +26,46 @@ fn init_logger_provider() -> opentelemetry_sdk::logs::LoggerProvider {
6426

6527
let cloned_provider = provider.clone();
6628

67-
// Add a tracing filter to filter events from crates used by opentelemetry-otlp.
68-
// The filter levels are set as follows:
69-
// - Allow `info` level and above by default.
70-
// - Restrict `hyper`, `tonic`, and `reqwest` to `error` level logs only.
71-
// This ensures events generated from these crates within the OTLP Exporter are not looped back,
72-
// thus preventing infinite event generation.
73-
// Note: This will also drop events from these crates used outside the OTLP Exporter.
74-
// For more details, see: https://github.com/open-telemetry/opentelemetry-rust/issues/761
75-
let filter = EnvFilter::new("info")
76-
.add_directive("hyper=error".parse().unwrap())
77-
.add_directive("tonic=error".parse().unwrap())
78-
.add_directive("reqwest=error".parse().unwrap());
79-
80-
// Configuring the formatting layer specifically for OpenTelemetry internal logs.
81-
// These logs starts with "opentelemetry" prefix in target. This allows specific logs
82-
// from the OpenTelemetry-related components to be filtered and handled separately
83-
// from the application logs
84-
85-
let opentelemetry_filter = tracing_subscriber::filter::filter_fn(|metadata| {
86-
metadata.target().starts_with("opentelemetry")
29+
// Specialized filter to process
30+
// - ERROR logs from specific targets
31+
// - ERROR logs generated internally.
32+
let internal_and_dependency_filter = tracing_subscriber::filter::filter_fn(|metadata| {
33+
let target = metadata.target();
34+
35+
// Only allow ERROR logs from specific targets
36+
(target.starts_with("hyper")
37+
|| target.starts_with("hyper_util")
38+
|| target.starts_with("hyper")
39+
|| target.starts_with("tonic")
40+
|| target.starts_with("tower")
41+
|| target.starts_with("reqwest")
42+
|| target.starts_with("opentelemetry"))
43+
&& metadata.level() == &tracing::Level::ERROR
8744
});
88-
89-
let fmt_opentelemetry_layer = fmt::layer()
90-
.with_filter(LevelFilter::DEBUG)
91-
.with_filter(opentelemetry_filter);
92-
93-
// Configures the appender tracing layer, filtering out OpenTelemetry internal logs
94-
// to prevent infinite logging loops.
95-
96-
let non_opentelemetry_filter = tracing_subscriber::filter::filter_fn(|metadata| {
97-
!metadata.target().starts_with("opentelemetry")
45+
// Configure fmt::Layer to print detailed log information, including structured fields
46+
let fmt_internal_and_dependency_layer =
47+
tracing_subscriber::fmt::layer().with_filter(internal_and_dependency_filter.clone());
48+
49+
// Application filter to exclude specific targets entirely, regardless of level
50+
let application_filter = tracing_subscriber::filter::filter_fn(|metadata| {
51+
let target = metadata.target();
52+
53+
// Exclude logs from specific targets for the application layer
54+
!(target.starts_with("hyper")
55+
|| target.starts_with("hyper_util")
56+
|| target.starts_with("hyper")
57+
|| target.starts_with("tonic")
58+
|| target.starts_with("tower")
59+
|| target.starts_with("reqwest")
60+
|| target.starts_with("opentelemetry"))
9861
});
9962

100-
let otel_layer = layer::OpenTelemetryTracingBridge::new(&cloned_provider)
101-
.with_filter(non_opentelemetry_filter.clone());
63+
let application_layer = layer::OpenTelemetryTracingBridge::new(&cloned_provider)
64+
.with_filter(application_filter.clone());
10265

10366
tracing_subscriber::registry()
104-
.with(fmt_opentelemetry_layer)
105-
.with(fmt::layer().with_filter(filter))
106-
.with(otel_layer)
67+
.with(fmt_internal_and_dependency_layer)
68+
.with(application_layer)
10769
.init();
10870
provider
10971
}
@@ -130,11 +92,6 @@ fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
13092

13193
#[tokio::main]
13294
async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
133-
// Set the custom error handler
134-
if let Err(err) = set_error_handler(custom_error_handler) {
135-
eprintln!("Failed to set custom error handler: {}", err);
136-
}
137-
13895
let logger_provider = init_logger_provider();
13996

14097
// Initialize the MeterProvider with the stdout Exporter.

opentelemetry/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ let counter = meter.u64_counter("my_counter").build();
3333
- Replaced `global::meter_with_version` with `global::meter_with_scope`
3434
- Added `global::tracer_with_scope`
3535

36+
- **Breaking change**: [#2260](https://github.com/open-telemetry/opentelemetry-rust/pull/2260)
37+
- Removed `global::set_error_handler` and `global::handle_error`.
38+
- `global::handle_error` usage inside the opentelemetry crates has been replaced with `global::otel_info`, `otel_warn`, `otel_debug` and `otel_error` macros based on the severity of the internal logs.
39+
- The default behavior of `global::handle_error` was to log the error using `eprintln!`. With otel macro, the internal logs get emitted via `tracing` macros of matching severity. Users now need to configure the `tracing` layer to capture these logs.
40+
- Refer to this PR description for migration guide. Also refer to [self-diagnostics](https://github.com/open-telemetry/opentelemetry-rust/tree/main/examples/self-diagnostics) example on how to configure the tracing layer for internal logs.
41+
3642
## v0.26.0
3743
Released 2024-Sep-30
3844

-41
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::sync::PoisonError;
2-
use std::sync::RwLock;
32

43
#[cfg(feature = "logs")]
54
use crate::logs::LogError;
@@ -8,9 +7,6 @@ use crate::metrics::MetricError;
87
use crate::propagation::PropagationError;
98
#[cfg(feature = "trace")]
109
use crate::trace::TraceError;
11-
use once_cell::sync::Lazy;
12-
13-
static GLOBAL_ERROR_HANDLER: Lazy<RwLock<Option<ErrorHandler>>> = Lazy::new(|| RwLock::new(None));
1410

1511
/// Wrapper for error from both tracing and metrics part of open telemetry.
1612
#[derive(thiserror::Error, Debug)]
@@ -47,40 +43,3 @@ impl<T> From<PoisonError<T>> for Error {
4743
Error::Other(err.to_string())
4844
}
4945
}
50-
51-
struct ErrorHandler(Box<dyn Fn(Error) + Send + Sync>);
52-
53-
/// Handle error using the globally configured error handler.
54-
///
55-
/// Writes to stderr if unset.
56-
pub fn handle_error<T: Into<Error>>(err: T) {
57-
match GLOBAL_ERROR_HANDLER.read() {
58-
Ok(handler) if handler.is_some() => (handler.as_ref().unwrap().0)(err.into()),
59-
_ => match err.into() {
60-
#[cfg(feature = "metrics")]
61-
#[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
62-
Error::Metric(err) => eprintln!("OpenTelemetry metrics error occurred. {}", err),
63-
#[cfg(feature = "trace")]
64-
#[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
65-
Error::Trace(err) => eprintln!("OpenTelemetry trace error occurred. {}", err),
66-
#[cfg(feature = "logs")]
67-
#[cfg_attr(docsrs, doc(cfg(feature = "logs")))]
68-
Error::Log(err) => eprintln!("OpenTelemetry log error occurred. {}", err),
69-
Error::Propagation(err) => {
70-
eprintln!("OpenTelemetry propagation error occurred. {}", err)
71-
}
72-
Error::Other(err_msg) => eprintln!("OpenTelemetry error occurred. {}", err_msg),
73-
},
74-
}
75-
}
76-
77-
/// Set global error handler.
78-
pub fn set_error_handler<F>(f: F) -> std::result::Result<(), Error>
79-
where
80-
F: Fn(Error) + Send + Sync + 'static,
81-
{
82-
GLOBAL_ERROR_HANDLER
83-
.write()
84-
.map(|mut handler| *handler = Some(ErrorHandler(Box::new(f))))
85-
.map_err(Into::into)
86-
}

opentelemetry/src/global/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ mod metrics;
138138
mod propagation;
139139
#[cfg(feature = "trace")]
140140
mod trace;
141+
pub use error_handler::Error;
141142

142-
pub use error_handler::{handle_error, set_error_handler, Error};
143143
#[cfg(feature = "metrics")]
144144
#[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
145145
pub use metrics::*;

0 commit comments

Comments
 (0)