Skip to content

Commit fab436c

Browse files
authored
[SigV4] Better Error Handling and More Log Messages (#344)
*Description of changes:* Added better logging messages for using SigV4 and a more graceful way to handle the case where botocore is not installed to avoid this error message: ```AttributeError: 'OtlpAwsSpanExporter' object has no attribute 'boto_aws_request'``` By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
1 parent 1b3f738 commit fab436c

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,18 @@ def _customize_exporter(span_exporter: SpanExporter, resource: Resource) -> Span
319319
traces_endpoint = os.environ.get(AWS_XRAY_DAEMON_ADDRESS_CONFIG, "127.0.0.1:2000")
320320
span_exporter = OTLPUdpSpanExporter(endpoint=traces_endpoint)
321321

322-
if isinstance(span_exporter, OTLPSpanExporter) and is_xray_otlp_endpoint(
323-
os.environ.get(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)
324-
):
325-
span_exporter = OTLPAwsSpanExporter(endpoint=os.getenv(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT))
322+
if is_xray_otlp_endpoint(os.environ.get(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)):
323+
# TODO: Change this url once doc writer has added a section for using SigV4 without collector
324+
_logger.info("Detected using AWS OTLP XRay Endpoint.")
325+
326+
if isinstance(span_exporter, OTLPSpanExporter):
327+
span_exporter = OTLPAwsSpanExporter(endpoint=os.getenv(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT))
328+
329+
else:
330+
_logger.warning(
331+
"Improper configuration see: please export/set "
332+
"OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf and OTEL_TRACES_EXPORTER=otlp"
333+
)
326334

327335
if not _is_application_signals_enabled():
328336
return span_exporter
@@ -456,7 +464,6 @@ def _is_lambda_environment():
456464

457465
def is_xray_otlp_endpoint(otlp_endpoint: str = None) -> bool:
458466
"""Is the given endpoint the XRay OTLP endpoint?"""
459-
460467
if not otlp_endpoint:
461468
return False
462469

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

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def __init__(
3535
):
3636

3737
self._aws_region = None
38-
38+
self._has_required_dependencies = False
3939
# Requires botocore to be installed to sign the headers. However,
4040
# some users might not need to use this exporter. In order not conflict
4141
# with existing behavior, we check for botocore before initializing this exporter.
@@ -52,6 +52,7 @@ def __init__(
5252
# The only usecase for this class would be for ADOT Python Auto Instrumentation and that already validates
5353
# the endpoint to be an XRay OTLP endpoint.
5454
self._aws_region = endpoint.split(".")[1]
55+
self._has_required_dependencies = True
5556

5657
else:
5758
_logger.error(
@@ -74,23 +75,26 @@ def __init__(
7475
# the same except if the endpoint is an XRay OTLP endpoint, we will sign the request
7576
# with SigV4 in headers before sending it to the endpoint. Otherwise, we will skip signing.
7677
def _export(self, serialized_data: bytes):
77-
request = self.boto_aws_request.AWSRequest(
78-
method="POST",
79-
url=self._endpoint,
80-
data=serialized_data,
81-
headers={"Content-Type": "application/x-protobuf"},
82-
)
78+
if self._has_required_dependencies:
79+
request = self.boto_aws_request.AWSRequest(
80+
method="POST",
81+
url=self._endpoint,
82+
data=serialized_data,
83+
headers={"Content-Type": "application/x-protobuf"},
84+
)
8385

84-
credentials = self.boto_session.get_credentials()
86+
credentials = self.boto_session.get_credentials()
8587

86-
if credentials is not None:
87-
signer = self.boto_auth.SigV4Auth(credentials, AWS_SERVICE, self._aws_region)
88+
if credentials is not None:
89+
signer = self.boto_auth.SigV4Auth(credentials, AWS_SERVICE, self._aws_region)
8890

89-
try:
90-
signer.add_auth(request)
91-
self._session.headers.update(dict(request.headers))
91+
try:
92+
signer.add_auth(request)
93+
self._session.headers.update(dict(request.headers))
9294

93-
except Exception as signing_error: # pylint: disable=broad-except
94-
_logger.error("Failed to sign request: %s", signing_error)
95+
except Exception as signing_error: # pylint: disable=broad-except
96+
_logger.error("Failed to sign request: %s", signing_error)
97+
else:
98+
_logger.debug("botocore is not installed. Failed to sign request to export traces to: %s", self._endpoint)
9599

96100
return super()._export(serialized_data)

0 commit comments

Comments
 (0)