1- use opentelemetry:: global:: { self , set_error_handler , Error as OtelError } ;
1+ use opentelemetry:: global:: { self , Error as OtelError } ;
22use opentelemetry:: KeyValue ;
33use opentelemetry_appender_tracing:: layer;
44use opentelemetry_otlp:: { LogExporter , MetricExporter , WithExportConfig } ;
55use opentelemetry_sdk:: metrics:: PeriodicReader ;
6- use tracing_subscriber:: filter:: { EnvFilter , LevelFilter } ;
6+ use tracing_subscriber:: filter:: EnvFilter ;
77use tracing_subscriber:: fmt;
88use tracing_subscriber:: prelude:: * ;
99
1010use std:: error:: Error ;
11- use tracing:: error;
1211
1312use once_cell:: sync:: Lazy ;
1413use std:: collections:: HashSet ;
@@ -29,27 +28,13 @@ impl ErrorState {
2928
3029 fn mark_as_seen ( & self , err : & OtelError ) -> bool {
3130 let mut seen_errors = self . seen_errors . lock ( ) . unwrap ( ) ;
32- seen_errors. insert ( err. to_string ( ) )
31+ let error_message = err. to_string ( ) ;
32+ !seen_errors. insert ( error_message) // Returns false if already present
3333 }
3434}
3535
3636static GLOBAL_ERROR_STATE : Lazy < Arc < ErrorState > > = Lazy :: new ( || Arc :: new ( ErrorState :: new ( ) ) ) ;
3737
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- }
5338
5439fn init_logger_provider ( ) -> opentelemetry_sdk:: logs:: LoggerProvider {
5540 let exporter = LogExporter :: builder ( )
@@ -77,18 +62,34 @@ fn init_logger_provider() -> opentelemetry_sdk::logs::LoggerProvider {
7762 . add_directive ( "tonic=error" . parse ( ) . unwrap ( ) )
7863 . add_directive ( "reqwest=error" . parse ( ) . unwrap ( ) ) ;
7964
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-
65+ // Filter for logs with "opentelemetry_" target prefix to use eprintln,
66+ // only if they haven't been logged before.
8567 let opentelemetry_filter = tracing_subscriber:: filter:: filter_fn ( |metadata| {
86- metadata. target ( ) . starts_with ( "opentelemetry" )
68+ if metadata. target ( ) . starts_with ( "opentelemetry_" ) {
69+ // Ignore debug level logs
70+ if metadata. level ( ) == & tracing:: Level :: DEBUG {
71+ return false ;
72+ }
73+ let err = OtelError :: Other ( metadata. target ( ) . to_string ( ) ) ; // Convert target to an OtelError variant
74+ if !GLOBAL_ERROR_STATE . mark_as_seen ( & err) {
75+ eprintln ! (
76+ "[{}] - {}: {}" ,
77+ metadata. level( ) ,
78+ metadata. target( ) ,
79+ metadata. fields( )
80+ ) ;
81+ }
82+ false // Prevent these logs from propagating further
83+ } else {
84+ true // Allow other logs to continue
85+ }
8786 } ) ;
8887
89- let fmt_opentelemetry_layer = fmt:: layer ( )
90- . with_filter ( LevelFilter :: DEBUG )
91- . with_filter ( opentelemetry_filter) ;
88+ // Layer for OpenTelemetry internal logs
89+ let fmt_opentelemetry_layer = fmt:: layer ( ) . with_filter ( opentelemetry_filter) ;
90+
91+ // Layer for application logs, excluding OpenTelemetry internal logs
92+ let fmt_application_layer = fmt:: layer ( ) . with_filter ( filter) ;
9293
9394 // Configures the appender tracing layer, filtering out OpenTelemetry internal logs
9495 // to prevent infinite logging loops.
@@ -102,7 +103,7 @@ fn init_logger_provider() -> opentelemetry_sdk::logs::LoggerProvider {
102103
103104 tracing_subscriber:: registry ( )
104105 . with ( fmt_opentelemetry_layer)
105- . with ( fmt :: layer ( ) . with_filter ( filter ) )
106+ . with ( fmt_application_layer )
106107 . with ( otel_layer)
107108 . init ( ) ;
108109 provider
@@ -130,11 +131,6 @@ fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
130131
131132#[ tokio:: main]
132133async 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-
138134 let logger_provider = init_logger_provider ( ) ;
139135
140136 // Initialize the MeterProvider with the stdout Exporter.
0 commit comments