2121 AwsMetricAttributesSpanExporterBuilder ,
2222)
2323from amazon .opentelemetry .distro .aws_span_metrics_processor_builder import AwsSpanMetricsProcessorBuilder
24- from amazon .opentelemetry .distro .exporter .otlp .aws .logs .otlp_aws_logs_exporter import OTLPAwsLogExporter
25- from amazon .opentelemetry .distro .exporter .otlp .aws .traces .otlp_aws_span_exporter import OTLPAwsSpanExporter
24+ from amazon .opentelemetry .distro .exporter .otlp .aws .common .aws_auth_session import AwsAuthSession
2625from amazon .opentelemetry .distro .otlp_udp_exporter import OTLPUdpSpanExporter
2726from amazon .opentelemetry .distro .sampler .aws_xray_remote_sampler import AwsXRayRemoteSampler
2827from amazon .opentelemetry .distro .scope_based_exporter import ScopeBasedPeriodicExportingMetricReader
8988SYSTEM_METRICS_INSTRUMENTATION_SCOPE_NAME = "opentelemetry.instrumentation.system_metrics"
9089OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"
9190OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"
91+ OTEL_EXPORTER_OTLP_LOGS_HEADERS = "OTEL_EXPORTER_OTLP_LOGS_HEADERS"
9292
9393AWS_TRACES_OTLP_ENDPOINT_PATTERN = r"https://xray\.([a-z0-9-]+)\.amazonaws\.com/v1/traces$"
9494AWS_LOGS_OTLP_ENDPOINT_PATTERN = r"https://logs\.([a-z0-9-]+)\.amazonaws\.com/v1/logs$"
9595
96+ AWS_OTLP_LOGS_GROUP_HEADER = "x-aws-log-group"
97+ AWS_OTLP_LOGS_STREAM_HEADER = "x-aws-log-stream"
98+
9699# UDP package size is not larger than 64KB
97100LAMBDA_SPAN_EXPORT_BATCH_SIZE = 10
98101
@@ -173,6 +176,11 @@ def _init_logging(
173176 resource : Resource = None ,
174177):
175178
179+ # Provides a default OTLP log exporter when none is specified.
180+ # This is the behavior for the logs exporters for other languages.
181+ if not exporters :
182+ exporters .setdefault ("otlp" , OTLPLogExporter )
183+
176184 provider = LoggerProvider (resource = resource )
177185 set_logger_provider (provider )
178186
@@ -339,17 +347,20 @@ def _customize_sampler(sampler: Sampler) -> Sampler:
339347
340348
341349def _customize_span_exporter (span_exporter : SpanExporter , resource : Resource ) -> SpanExporter :
350+ traces_endpoint = os .environ .get (OTEL_EXPORTER_OTLP_TRACES_ENDPOINT )
342351 if _is_lambda_environment ():
343352 # Override OTLP http default endpoint to UDP
344- if isinstance (span_exporter , OTLPSpanExporter ) and os . getenv ( OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ) is None :
353+ if isinstance (span_exporter , OTLPSpanExporter ) and traces_endpoint is None :
345354 traces_endpoint = os .environ .get (AWS_XRAY_DAEMON_ADDRESS_CONFIG , "127.0.0.1:2000" )
346355 span_exporter = OTLPUdpSpanExporter (endpoint = traces_endpoint )
347356
348- if is_aws_otlp_endpoint (os . environ . get ( OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ) , "xray" ):
349- _logger .info ("Detected using AWS OTLP XRay Endpoint." )
357+ if is_aws_otlp_endpoint (traces_endpoint , "xray" ):
358+ _logger .info ("Detected using AWS OTLP Traces Endpoint." )
350359
351360 if isinstance (span_exporter , OTLPSpanExporter ):
352- span_exporter = OTLPAwsSpanExporter (endpoint = os .getenv (OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ))
361+ span_exporter = OTLPSpanExporter (
362+ endpoint = traces_endpoint , session = AwsAuthSession (traces_endpoint .split ("." )[1 ], "xray" )
363+ )
353364
354365 else :
355366 _logger .warning (
@@ -364,11 +375,18 @@ def _customize_span_exporter(span_exporter: SpanExporter, resource: Resource) ->
364375
365376
366377def _customize_logs_exporter (log_exporter : LogExporter , resource : Resource ) -> LogExporter :
367- if is_aws_otlp_endpoint (os .environ .get (OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ), "logs" ):
378+ logs_endpoint = os .environ .get (OTEL_EXPORTER_OTLP_LOGS_ENDPOINT )
379+
380+ if is_aws_otlp_endpoint (logs_endpoint , "logs" ):
368381 _logger .info ("Detected using AWS OTLP Logs Endpoint." )
369382
370- if isinstance (log_exporter , OTLPLogExporter ):
371- return OTLPAwsLogExporter (endpoint = os .getenv (OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ))
383+ if isinstance (log_exporter , OTLPLogExporter ) and validate_logs_headers ():
384+ return OTLPLogExporter (endpoint = logs_endpoint , session = AwsAuthSession (logs_endpoint .split ("." )[1 ], "logs" ))
385+
386+ _logger .warning (
387+ "Improper configuration see: please export/set "
388+ "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/protobuf and OTEL_LOGS_EXPORTER=otlp"
389+ )
372390
373391 return log_exporter
374392
@@ -504,6 +522,37 @@ def is_aws_otlp_endpoint(otlp_endpoint: str = None, service: str = "xray") -> bo
504522 return bool (re .match (pattern , otlp_endpoint .lower ()))
505523
506524
525+ def validate_logs_headers () -> bool :
526+ """Checks if x-aws-log-group and x-aws-log-stream are present in the headers in order to send logs to
527+ AWS OTLP Logs endpoint."""
528+
529+ logs_headers = os .environ .get (OTEL_EXPORTER_OTLP_LOGS_HEADERS )
530+
531+ if not logs_headers :
532+ _logger .warning (
533+ "Improper configuration: Please configure the environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS "
534+ "to include x-aws-log-group and x-aws-log-stream"
535+ )
536+ return False
537+
538+ filtered_log_headers_count = 0
539+
540+ for pair in logs_headers .split ("," ):
541+ if "=" in pair :
542+ key = pair .split ("=" , 1 )[0 ]
543+ if key == AWS_OTLP_LOGS_GROUP_HEADER or key == AWS_OTLP_LOGS_STREAM_HEADER :
544+ filtered_log_headers_count += 1
545+
546+ if filtered_log_headers_count != 2 :
547+ _logger .warning (
548+ "Improper configuration: Please configure the environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS "
549+ "to have values for x-aws-log-group and x-aws-log-stream"
550+ )
551+ return False
552+
553+ return True
554+
555+
507556def _get_metric_export_interval ():
508557 export_interval_millis = float (os .environ .get (METRIC_EXPORT_INTERVAL_CONFIG , DEFAULT_METRIC_EXPORT_INTERVAL ))
509558 _logger .debug ("Span Metrics export interval: %s" , export_interval_millis )
0 commit comments