1515"""OTLP Exporter
1616
1717This module provides a mixin class for OTLP exporters that send telemetry data
18- to an OpenTelemetry Collector via gRPC. It includes a configurable reconnection
18+ to an OTLP-compatible receiver via gRPC. It includes a configurable reconnection
1919logic to handle transient collector outages.
2020
21- Environment Variables:
22- OTEL_EXPORTER_OTLP_RETRY_INTERVAL: Base retry interval in seconds (default: 2.0).
23- OTEL_EXPORTER_OTLP_MAX_RETRIES: Maximum number of retry attempts (default: 20).
24- OTEL_EXPORTER_OTLP_RETRY_TIMEOUT: Total retry timeout in seconds (default: 300).
25- OTEL_EXPORTER_OTLP_RETRY_MAX_DELAY: Maximum delay between retries in seconds (default: 60.0).
26- OTEL_EXPORTER_OTLP_RETRY_FACTOR: Exponential backoff factor (default: 1.5).
27- OTEL_EXPORTER_OTLP_RETRY_JITTER: Jitter factor for retry delay (default: 0.2).
21+
2822"""
2923
3024import random
@@ -358,14 +352,16 @@ def __init__(
358352 )
359353 self ._collector_kwargs = None
360354
361- compression = (
362- environ_to_compression (OTEL_EXPORTER_OTLP_COMPRESSION )
363- if compression is None
364- else compression
365- ) or Compression .NoCompression
366- self ._compression = compression
367-
368- # Initialize the channel and stub using the proper method
355+ self ._compression = (
356+ compression
357+ or environ_to_compression (
358+ environ .get (OTEL_EXPORTER_OTLP_COMPRESSION )
359+ )
360+ or Compression .NoCompression
361+ )
362+ self ._channel = None
363+ self ._client = None
364+ self ._channel_reconnection_enabled = False
369365 self ._initialize_channel_and_stub ()
370366
371367 def _initialize_channel_and_stub (self ):
@@ -378,7 +374,7 @@ def _initialize_channel_and_stub(self):
378374 # Add channel options for better reconnection behavior
379375 # Only add these if we're dealing with reconnection scenarios
380376 channel_options = []
381- if hasattr ( self , " _channel_reconnection_enabled" ) :
377+ if self . _channel_reconnection_enabled :
382378 channel_options = [
383379 ("grpc.keepalive_time_ms" , 30000 ),
384380 ("grpc.keepalive_timeout_ms" , 15000 ),
@@ -391,9 +387,11 @@ def _initialize_channel_and_stub(self):
391387 # Merge reconnection options with existing channel options
392388 current_options = list (self ._channel_options )
393389 # Filter out options that we are about to override
394- reconnection_keys = {opt [ 0 ] for opt in channel_options }
390+ reconnection_keys = {key for key , _ in channel_options }
395391 current_options = [
396- opt for opt in current_options if opt [0 ] not in reconnection_keys
392+ (key , value )
393+ for key , value in current_options
394+ if key not in reconnection_keys
397395 ]
398396 final_options = tuple (current_options + channel_options )
399397
@@ -465,7 +463,7 @@ def _export(
465463 )
466464
467465 # For UNAVAILABLE errors, reinitialize the channel to force reconnection
468- if error .code () == StatusCode .UNAVAILABLE : # type: ignore
466+ if error .code () == StatusCode .UNAVAILABLE and retry_num == 0 : # type: ignore
469467 logger .debug (
470468 "Reinitializing gRPC channel for %s exporter due to UNAVAILABLE error" ,
471469 self ._exporting ,
0 commit comments