@@ -217,7 +217,6 @@ use crate::trace::ExportResult;
217
217
/// .with_max_queue_size(1024) // Buffer up to 1024 spans.
218
218
/// .with_max_export_batch_size(256) // Export in batches of up to 256 spans.
219
219
/// .with_scheduled_delay(Duration::from_secs(5)) // Export every 5 seconds.
220
- /// .with_max_export_timeout(Duration::from_secs(10)) // Timeout after 10 seconds.
221
220
/// .build(),
222
221
/// )
223
222
/// .build();
@@ -253,7 +252,38 @@ enum BatchMessage {
253
252
SetResource ( Arc < Resource > ) ,
254
253
}
255
254
256
- /// A batch span processor with a dedicated background thread.
255
+ /// The `BatchSpanProcessor` collects finished spans in a buffer and exports them
256
+ /// in batches to the configured `SpanExporter`. This processor is ideal for
257
+ /// high-throughput environments, as it minimizes the overhead of exporting spans
258
+ /// individually. It uses a **dedicated background thread** to manage and export spans
259
+ /// asynchronously, ensuring that the application's main execution flow is not blocked.
260
+ ///
261
+ /// This processor supports the following configurations:
262
+ /// - **Queue size**: Maximum number of spans that can be buffered.
263
+ /// - **Batch size**: Maximum number of spans to include in a single export.
264
+ /// - **Scheduled delay**: Frequency at which the batch is exported.
265
+ ///
266
+ /// When using this processor with the OTLP Exporter, the following exporter
267
+ /// features are supported:
268
+ /// - `grpc-tonic`: Requires `TracerProvider` to be created within a tokio runtime.
269
+ /// - `reqwest-blocking-client`: Works with a regular `main` or `tokio::main`.
270
+ ///
271
+ /// In other words, other clients like `reqwest` and `hyper` are not supported.
272
+ ///
273
+ /// `BatchSpanProcessor` buffers spans in memory and exports them in batches. An
274
+ /// export is triggered when `max_export_batch_size` is reached or every
275
+ /// `scheduled_delay` milliseconds. Users can explicitly trigger an export using
276
+ /// the `force_flush` method. Shutdown also triggers an export of all buffered
277
+ /// spans and is recommended to be called before the application exits to ensure
278
+ /// all buffered spans are exported.
279
+ ///
280
+ /// **Warning**: When using tokio's current-thread runtime, `shutdown()`, which
281
+ /// is a blocking call ,should not be called from your main thread. This can
282
+ /// cause deadlock. Instead, call `shutdown()` from a separate thread or use
283
+ /// tokio's `spawn_blocking`.
284
+ ///
285
+ /// [`shutdown()`]: crate::trace::TracerProvider::shutdown
286
+ /// [`force_flush()`]: crate::trace::TracerProvider::force_flush
257
287
#[ derive( Debug ) ]
258
288
pub struct BatchSpanProcessor {
259
289
span_sender : SyncSender < SpanData > , // Data channel to store spans
@@ -443,20 +473,14 @@ impl BatchSpanProcessor {
443
473
}
444
474
445
475
let count_of_spans = spans. len ( ) ; // Count of spans that will be exported
446
- let result = Self :: export_with_timeout_sync (
447
- config. max_export_timeout ,
448
- exporter,
449
- spans,
450
- last_export_time,
451
- ) ; // This method clears the spans vec after exporting
476
+ let result = Self :: export_batch_sync ( exporter, spans, last_export_time) ; // This method clears the spans vec after exporting
452
477
453
478
current_batch_size. fetch_sub ( count_of_spans, Ordering :: Relaxed ) ;
454
479
result
455
480
}
456
481
457
482
#[ allow( clippy:: vec_box) ]
458
- fn export_with_timeout_sync < E > (
459
- _: Duration , // TODO, enforcing timeout in exporter.
483
+ fn export_batch_sync < E > (
460
484
exporter : & mut E ,
461
485
batch : & mut Vec < SpanData > ,
462
486
last_export_time : & mut Instant ,
@@ -740,6 +764,7 @@ impl BatchConfigBuilder {
740
764
/// Set max_export_timeout for [`BatchConfigBuilder`].
741
765
/// It's the maximum duration to export a batch of data.
742
766
/// The The default value is 30000 milliseconds.
767
+ #[ cfg( feature = "experimental_trace_batch_span_processor_with_async_runtime" ) ]
743
768
pub fn with_max_export_timeout ( mut self , max_export_timeout : Duration ) -> Self {
744
769
self . max_export_timeout = max_export_timeout;
745
770
self
@@ -960,10 +985,11 @@ mod tests {
960
985
let batch = BatchConfigBuilder :: default ( )
961
986
. with_max_export_batch_size ( 10 )
962
987
. with_scheduled_delay ( Duration :: from_millis ( 10 ) )
963
- . with_max_export_timeout ( Duration :: from_millis ( 10 ) )
964
988
. with_max_queue_size ( 10 ) ;
965
989
#[ cfg( feature = "experimental_trace_batch_span_processor_with_async_runtime" ) ]
966
990
let batch = batch. with_max_concurrent_exports ( 10 ) ;
991
+ #[ cfg( feature = "experimental_trace_batch_span_processor_with_async_runtime" ) ]
992
+ let batch = batch. with_max_export_timeout ( Duration :: from_millis ( 10 ) ) ;
967
993
let batch = batch. build ( ) ;
968
994
assert_eq ! ( batch. max_export_batch_size, 10 ) ;
969
995
assert_eq ! ( batch. scheduled_delay, Duration :: from_millis( 10 ) ) ;
@@ -1037,7 +1063,6 @@ mod tests {
1037
1063
. with_max_queue_size ( 10 )
1038
1064
. with_max_export_batch_size ( 10 )
1039
1065
. with_scheduled_delay ( Duration :: from_secs ( 5 ) )
1040
- . with_max_export_timeout ( Duration :: from_secs ( 2 ) )
1041
1066
. build ( ) ;
1042
1067
let processor = BatchSpanProcessor :: new ( exporter, config) ;
1043
1068
@@ -1060,7 +1085,6 @@ mod tests {
1060
1085
. with_max_queue_size ( 10 )
1061
1086
. with_max_export_batch_size ( 10 )
1062
1087
. with_scheduled_delay ( Duration :: from_secs ( 5 ) )
1063
- . with_max_export_timeout ( Duration :: from_secs ( 2 ) )
1064
1088
. build ( ) ;
1065
1089
let processor = BatchSpanProcessor :: new ( exporter, config) ;
1066
1090
@@ -1090,7 +1114,6 @@ mod tests {
1090
1114
. with_max_queue_size ( 10 )
1091
1115
. with_max_export_batch_size ( 10 )
1092
1116
. with_scheduled_delay ( Duration :: from_secs ( 5 ) )
1093
- . with_max_export_timeout ( Duration :: from_secs ( 2 ) )
1094
1117
. build ( ) ;
1095
1118
let processor = BatchSpanProcessor :: new ( exporter, config) ;
1096
1119
@@ -1126,7 +1149,6 @@ mod tests {
1126
1149
let config = BatchConfigBuilder :: default ( )
1127
1150
. with_max_queue_size ( 2 ) // Small queue size to test span dropping
1128
1151
. with_scheduled_delay ( Duration :: from_secs ( 5 ) )
1129
- . with_max_export_timeout ( Duration :: from_secs ( 2 ) )
1130
1152
. build ( ) ;
1131
1153
let processor = BatchSpanProcessor :: new ( exporter, config) ;
1132
1154
0 commit comments