Skip to content

Commit 22a1bd1

Browse files
committed
addressed PR comments
1 parent fb7f6c8 commit 22a1bd1

File tree

3 files changed

+41
-33
lines changed

3 files changed

+41
-33
lines changed

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/_utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ def is_agent_observability_enabled() -> bool:
4242

4343

4444
def get_aws_session():
45-
"""Returns a botocore session only if botocore is installed, otherwise None.
45+
"""
46+
Returns a botocore session only if botocore is installed, otherwise None.
47+
If AWS Region is defined in `AWS_REGION` or `AWS_DEFAULT_REGION` environment variables,
48+
then the region is set in the botocore session before returning.
4649
4750
We do this to prevent runtime errors for ADOT customers that do not need
4851
any features that require botocore.

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/aws_opentelemetry_configurator.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@
9595
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"
9696
OTEL_EXPORTER_OTLP_LOGS_HEADERS = "OTEL_EXPORTER_OTLP_LOGS_HEADERS"
9797

98+
XRAY_SERVICE = "xray"
99+
LOGS_SERIVCE = "logs"
98100
AWS_TRACES_OTLP_ENDPOINT_PATTERN = r"https://xray\.([a-z0-9-]+)\.amazonaws\.com/v1/traces$"
99101
AWS_LOGS_OTLP_ENDPOINT_PATTERN = r"https://logs\.([a-z0-9-]+)\.amazonaws\.com/v1/logs$"
100102

@@ -297,11 +299,10 @@ def _export_unsampled_span_for_agent_observability(trace_provider: TracerProvide
297299
return
298300

299301
traces_endpoint = os.environ.get(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)
300-
if traces_endpoint and _is_aws_otlp_endpoint(traces_endpoint):
301-
endpoint = traces_endpoint.lower()
302-
region = endpoint.split(".")[1]
302+
if traces_endpoint and _is_aws_otlp_endpoint(traces_endpoint, XRAY_SERVICE):
303+
endpoint, region = _extract_endpoint_and_region_from_otlp_endpoint(traces_endpoint)
304+
span_exporter = _create_aws_otlp_exporter(endpoint=endpoint, service=XRAY_SERVICE, region=region)
303305

304-
span_exporter = _create_aws_otlp_exporter(endpoint=endpoint, service="xray", region=region)
305306
trace_provider.add_span_processor(BatchUnsampledSpanProcessor(span_exporter=span_exporter))
306307

307308

@@ -351,7 +352,7 @@ def _custom_import_sampler(sampler_name: str, resource: Resource) -> Sampler:
351352
if sampler_name is None:
352353
sampler_name = "parentbased_always_on"
353354

354-
if sampler_name == "xray":
355+
if sampler_name == XRAY_SERVICE:
355356
# Example env var value
356357
# OTEL_TRACES_SAMPLER_ARG=endpoint=http://localhost:2000,polling_interval=360
357358
sampler_argument_env: str = os.getenv(OTEL_TRACES_SAMPLER_ARG, None)
@@ -397,17 +398,16 @@ def _customize_span_exporter(span_exporter: SpanExporter, resource: Resource) ->
397398
traces_endpoint = os.environ.get(AWS_XRAY_DAEMON_ADDRESS_CONFIG, "127.0.0.1:2000")
398399
span_exporter = OTLPUdpSpanExporter(endpoint=traces_endpoint)
399400

400-
if traces_endpoint and _is_aws_otlp_endpoint(traces_endpoint, "xray"):
401+
if traces_endpoint and _is_aws_otlp_endpoint(traces_endpoint, XRAY_SERVICE):
401402
_logger.info("Detected using AWS OTLP Traces Endpoint.")
402403

403404
if isinstance(span_exporter, OTLPSpanExporter):
404-
endpoint = traces_endpoint.lower()
405-
region = endpoint.split(".")[1]
406-
return _create_aws_otlp_exporter(endpoint=traces_endpoint, service="xray", region=region)
405+
endpoint, region = _extract_endpoint_and_region_from_otlp_endpoint(traces_endpoint)
406+
return _create_aws_otlp_exporter(endpoint=endpoint, service=XRAY_SERVICE, region=region)
407407

408408
_logger.warning(
409409
"Improper configuration see: please export/set "
410-
"OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf and OTEL_TRACES_EXPORTER=otlp"
410+
"OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf ƒnd OTEL_TRACES_EXPORTER=otlp"
411411
)
412412

413413
if not _is_application_signals_enabled():
@@ -439,12 +439,11 @@ def _customize_logs_exporter(log_exporter: LogExporter) -> LogExporter:
439439
_logger.info("Detected using AWS OTLP Logs Endpoint.")
440440

441441
if isinstance(log_exporter, OTLPLogExporter) and _validate_and_fetch_logs_header().is_valid:
442-
endpoint = logs_endpoint.lower()
443-
region = endpoint.split(".")[1]
442+
endpoint, region = _extract_endpoint_and_region_from_otlp_endpoint(logs_endpoint)
444443
# Setting default compression mode to Gzip as this is the behavior in upstream's
445444
# collector otlp http exporter:
446445
# https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter
447-
return _create_aws_otlp_exporter(endpoint=logs_endpoint, service="logs", region=region)
446+
return _create_aws_otlp_exporter(endpoint=endpoint, service="logs", region=region)
448447

449448
_logger.warning(
450449
"Improper configuration see: please export/set "
@@ -513,7 +512,7 @@ def _customize_metric_exporters(
513512
metric_readers.append(scope_based_periodic_exporting_metric_reader)
514513

515514
if is_emf_enabled:
516-
emf_exporter = create_emf_exporter()
515+
emf_exporter = _create_emf_exporter()
517516
if emf_exporter:
518517
metric_readers.append(PeriodicExportingMetricReader(emf_exporter))
519518

@@ -603,17 +602,24 @@ def _is_lambda_environment():
603602
return AWS_LAMBDA_FUNCTION_NAME_CONFIG in os.environ
604603

605604

606-
def _is_aws_otlp_endpoint(otlp_endpoint: Optional[str] = None, service: str = "xray") -> bool:
605+
def _is_aws_otlp_endpoint(otlp_endpoint: Optional[str], service: str) -> bool:
607606
"""Is the given endpoint an AWS OTLP endpoint?"""
608607

609608
if not otlp_endpoint:
610609
return False
611610

612-
pattern = AWS_TRACES_OTLP_ENDPOINT_PATTERN if service == "xray" else AWS_LOGS_OTLP_ENDPOINT_PATTERN
611+
pattern = AWS_TRACES_OTLP_ENDPOINT_PATTERN if service == XRAY_SERVICE else AWS_LOGS_OTLP_ENDPOINT_PATTERN
613612

614613
return bool(re.match(pattern, otlp_endpoint.lower()))
615614

616615

616+
def _extract_endpoint_and_region_from_otlp_endpoint(endpoint: str):
617+
endpoint = endpoint.lower()
618+
region = endpoint.split(".")[1]
619+
620+
return endpoint, region
621+
622+
617623
def _validate_and_fetch_logs_header() -> OtlpLogHeaderSetting:
618624
"""Checks if x-aws-log-group and x-aws-log-stream are present in the headers in order to send logs to
619625
AWS OTLP Logs endpoint."""
@@ -630,7 +636,6 @@ def _validate_and_fetch_logs_header() -> OtlpLogHeaderSetting:
630636
log_group = None
631637
log_stream = None
632638
namespace = None
633-
filtered_log_headers_count = 0
634639

635640
for pair in logs_headers.split(","):
636641
if "=" in pair:
@@ -639,14 +644,12 @@ def _validate_and_fetch_logs_header() -> OtlpLogHeaderSetting:
639644
value = split[1]
640645
if key == AWS_OTLP_LOGS_GROUP_HEADER and value:
641646
log_group = value
642-
filtered_log_headers_count += 1
643647
elif key == AWS_OTLP_LOGS_STREAM_HEADER and value:
644648
log_stream = value
645-
filtered_log_headers_count += 1
646649
elif key == AWS_EMF_METRICS_NAMESPACE and value:
647650
namespace = value
648651

649-
is_valid = filtered_log_headers_count == 2 and log_group is not None and log_stream is not None
652+
is_valid = log_group is not None and log_stream is not None
650653

651654
if not is_valid:
652655
_logger.warning(
@@ -768,7 +771,7 @@ def _check_emf_exporter_enabled() -> bool:
768771
return True
769772

770773

771-
def create_emf_exporter():
774+
def _create_emf_exporter():
772775
"""Create and configure the CloudWatch EMF exporter."""
773776
try:
774777
session = get_aws_session()
@@ -805,14 +808,14 @@ def _create_aws_otlp_exporter(endpoint: str, service: str, region: str):
805808
session = get_aws_session()
806809
# Check if botocore is available before importing the AWS exporter
807810
if not session:
808-
_logger.warning("SigV4 Auth requires botocore to be enabled")
811+
_logger.warning("Sigv4 Auth requires botocore to be enabled")
809812
return None
810813

811814
# pylint: disable=import-outside-toplevel
812815
from amazon.opentelemetry.distro.exporter.otlp.aws.logs.otlp_aws_logs_exporter import OTLPAwsLogExporter
813816
from amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter import OTLPAwsSpanExporter
814817

815-
if service == "xray":
818+
if service == XRAY_SERVICE:
816819
if is_agent_observability_enabled():
817820
# Span exporter needs an instance of logger provider in ai agent
818821
# observability case because we need to split input/output prompts
@@ -825,7 +828,7 @@ def _create_aws_otlp_exporter(endpoint: str, service: str, region: str):
825828

826829
return OTLPAwsSpanExporter(session=session, endpoint=endpoint, aws_region=region)
827830

828-
if service == "logs":
831+
if service == LOGS_SERIVCE:
829832
return OTLPAwsLogExporter(session=session, aws_region=region)
830833

831834
return None

aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelementry_configurator.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
OtlpLogHeaderSetting,
2727
_check_emf_exporter_enabled,
2828
_create_aws_otlp_exporter,
29+
_create_emf_exporter,
2930
_custom_import_sampler,
3031
_customize_log_record_processor,
3132
_customize_logs_exporter,
@@ -42,7 +43,6 @@
4243
_is_defer_to_workers_enabled,
4344
_is_wsgi_master_process,
4445
_validate_and_fetch_logs_header,
45-
create_emf_exporter,
4646
)
4747
from amazon.opentelemetry.distro.aws_opentelemetry_distro import AwsOpenTelemetryDistro
4848
from amazon.opentelemetry.distro.aws_span_metrics_processor import AwsSpanMetricsProcessor
@@ -1056,7 +1056,7 @@ def test_customize_log_record_processor_with_agent_observability(self, _):
10561056
def test_create_emf_exporter(self, mock_get_session, mock_validate):
10571057
# Test when botocore is not installed
10581058
mock_get_session.return_value = None
1059-
result = create_emf_exporter()
1059+
result = _create_emf_exporter()
10601060
self.assertIsNone(result)
10611061

10621062
# Reset mock for subsequent tests
@@ -1074,12 +1074,12 @@ def test_create_emf_exporter(self, mock_get_session, mock_validate):
10741074

10751075
# Test when headers are invalid
10761076
mock_validate.return_value = OtlpLogHeaderSetting(None, None, None, False)
1077-
result = create_emf_exporter()
1077+
result = _create_emf_exporter()
10781078
self.assertIsNone(result)
10791079

10801080
# Test when namespace is missing (should still create exporter with default namespace)
10811081
mock_validate.return_value = OtlpLogHeaderSetting("test-group", "test-stream", None, True)
1082-
result = create_emf_exporter()
1082+
result = _create_emf_exporter()
10831083
self.assertIsNotNone(result)
10841084
self.assertEqual(result, mock_exporter_instance)
10851085
# Verify that the EMF exporter was called with correct parameters
@@ -1092,7 +1092,7 @@ def test_create_emf_exporter(self, mock_get_session, mock_validate):
10921092

10931093
# Test with valid configuration
10941094
mock_validate.return_value = OtlpLogHeaderSetting("test-group", "test-stream", "test-namespace", True)
1095-
result = create_emf_exporter()
1095+
result = _create_emf_exporter()
10961096
self.assertIsNotNone(result)
10971097
self.assertEqual(result, mock_exporter_instance)
10981098
# Verify that the EMF exporter was called with correct parameters
@@ -1105,7 +1105,7 @@ def test_create_emf_exporter(self, mock_get_session, mock_validate):
11051105

11061106
# Test exception handling
11071107
mock_validate.side_effect = Exception("Test exception")
1108-
result = create_emf_exporter()
1108+
result = _create_emf_exporter()
11091109
self.assertIsNone(result)
11101110

11111111
@patch("amazon.opentelemetry.distro.aws_opentelemetry_configurator.get_logger_provider")
@@ -1183,7 +1183,9 @@ def test_customize_metric_exporters_with_emf(self):
11831183
self.assertEqual(len(metric_readers), 0)
11841184

11851185
# Test with EMF enabled but create_emf_exporter returns None
1186-
with patch("amazon.opentelemetry.distro.aws_opentelemetry_configurator.create_emf_exporter", return_value=None):
1186+
with patch(
1187+
"amazon.opentelemetry.distro.aws_opentelemetry_configurator._create_emf_exporter", return_value=None
1188+
):
11871189
_customize_metric_exporters(metric_readers, views, is_emf_enabled=True)
11881190
self.assertEqual(len(metric_readers), 0)
11891191

@@ -1194,7 +1196,7 @@ def test_customize_metric_exporters_with_emf(self):
11941196
mock_emf_exporter._preferred_aggregation = {}
11951197

11961198
with patch(
1197-
"amazon.opentelemetry.distro.aws_opentelemetry_configurator.create_emf_exporter",
1199+
"amazon.opentelemetry.distro.aws_opentelemetry_configurator._create_emf_exporter",
11981200
return_value=mock_emf_exporter,
11991201
):
12001202
_customize_metric_exporters(metric_readers, views, is_emf_enabled=True)

0 commit comments

Comments
 (0)