@@ -289,11 +289,13 @@ mod tests {
289
289
use opentelemetry:: { logs:: AnyValue , Key } ;
290
290
use opentelemetry_sdk:: error:: { OTelSdkError , OTelSdkResult } ;
291
291
use opentelemetry_sdk:: logs:: { InMemoryLogExporter , LogProcessor } ;
292
+ use opentelemetry_sdk:: logs:: { LogBatch , LogExporter } ;
292
293
use opentelemetry_sdk:: logs:: { SdkLogRecord , SdkLoggerProvider } ;
293
294
use opentelemetry_sdk:: trace:: { Sampler , SdkTracerProvider } ;
294
- use tracing:: error;
295
+ use tracing:: { error, warn } ;
295
296
use tracing_subscriber:: prelude:: __tracing_subscriber_SubscriberExt;
296
- use tracing_subscriber:: Layer ;
297
+ use tracing_subscriber:: util:: SubscriberInitExt ;
298
+ use tracing_subscriber:: { EnvFilter , Layer } ;
297
299
298
300
pub fn attributes_contains ( log_record : & SdkLogRecord , key : & Key , value : & AnyValue ) -> bool {
299
301
log_record
@@ -311,6 +313,69 @@ mod tests {
311
313
}
312
314
313
315
// cargo test --features=testing
316
+
317
+ #[ derive( Clone , Debug , Default ) ]
318
+ struct ReentrantLogExporter ;
319
+
320
+ impl LogExporter for ReentrantLogExporter {
321
+ async fn export ( & self , _batch : LogBatch < ' _ > ) -> OTelSdkResult {
322
+ // This will cause a deadlock as the export itself creates a log
323
+ // while still within the lock of the SimpleLogProcessor.
324
+ warn ! ( name
: "my-event-name" , target
: "reentrant" , event_id =
20 , user_name =
"otel" , user_email =
"[email protected] " ) ;
325
+ Ok ( ( ) )
326
+ }
327
+ }
328
+
329
+ #[ test]
330
+ #[ ignore = "See issue: https://github.com/open-telemetry/opentelemetry-rust/issues/1745" ]
331
+ fn simple_processor_deadlock ( ) {
332
+ let exporter: ReentrantLogExporter = ReentrantLogExporter ;
333
+ let logger_provider = SdkLoggerProvider :: builder ( )
334
+ . with_simple_exporter ( exporter. clone ( ) )
335
+ . build ( ) ;
336
+
337
+ let layer = layer:: OpenTelemetryTracingBridge :: new ( & logger_provider) ;
338
+
339
+ // Setting subscriber as global as that is the only way to test this scenario.
340
+ tracing_subscriber:: registry ( ) . with ( layer) . init ( ) ;
341
+ warn ! ( name
: "my-event-name" , target
: "my-system" , event_id =
20 , user_name =
"otel" , user_email =
"[email protected] " ) ;
342
+ }
343
+
344
+ #[ test]
345
+ #[ ignore = "While this test runs fine, this uses global subscriber and does not play well with other tests." ]
346
+ fn simple_processor_no_deadlock ( ) {
347
+ let exporter: ReentrantLogExporter = ReentrantLogExporter ;
348
+ let logger_provider = SdkLoggerProvider :: builder ( )
349
+ . with_simple_exporter ( exporter. clone ( ) )
350
+ . build ( ) ;
351
+
352
+ let layer = layer:: OpenTelemetryTracingBridge :: new ( & logger_provider) ;
353
+
354
+ // This filter will prevent the deadlock as the reentrant log will be
355
+ // ignored.
356
+ let filter = EnvFilter :: new ( "debug" ) . add_directive ( "reentrant=error" . parse ( ) . unwrap ( ) ) ;
357
+ // Setting subscriber as global as that is the only way to test this scenario.
358
+ tracing_subscriber:: registry ( )
359
+ . with ( filter)
360
+ . with ( layer)
361
+ . init ( ) ;
362
+ warn ! ( name
: "my-event-name" , target
: "my-system" , event_id =
20 , user_name =
"otel" , user_email =
"[email protected] " ) ;
363
+ }
364
+
365
+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
366
+ #[ ignore = "While this test runs fine, this uses global subscriber and does not play well with other tests." ]
367
+ async fn batch_processor_no_deadlock ( ) {
368
+ let exporter: ReentrantLogExporter = ReentrantLogExporter ;
369
+ let logger_provider = SdkLoggerProvider :: builder ( )
370
+ . with_batch_exporter ( exporter. clone ( ) )
371
+ . build ( ) ;
372
+
373
+ let layer = layer:: OpenTelemetryTracingBridge :: new ( & logger_provider) ;
374
+
375
+ tracing_subscriber:: registry ( ) . with ( layer) . init ( ) ;
376
+ warn ! ( name
: "my-event-name" , target
: "my-system" , event_id =
20 , user_name =
"otel" , user_email =
"[email protected] " ) ;
377
+ }
378
+
314
379
#[ test]
315
380
fn tracing_appender_standalone ( ) {
316
381
// Arrange
0 commit comments