Skip to content

Commit 3e5ceb4

Browse files
committed
consolidate log group and log stream config
1 parent 6ce90df commit 3e5ceb4

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,11 +568,35 @@ def _is_aws_otlp_endpoint(otlp_endpoint: str = None, service: str = "xray") -> b
568568
return bool(re.match(pattern, otlp_endpoint.lower()))
569569

570570

571+
def _parse_resource_attributes() -> Dict[str, str]:
572+
"""
573+
Parse OTEL_RESOURCE_ATTRIBUTES environment variable into a dictionary.
574+
575+
Returns:
576+
Dictionary of resource attributes
577+
"""
578+
resource_attributes = {}
579+
resource_attrs_str = os.environ.get("OTEL_RESOURCE_ATTRIBUTES", "")
580+
581+
if not resource_attrs_str:
582+
return resource_attributes
583+
584+
for pair in resource_attrs_str.split(","):
585+
if "=" in pair:
586+
key, value = pair.split("=", 1)
587+
resource_attributes[key.strip()] = value.strip()
588+
589+
return resource_attributes
590+
591+
571592
def _validate_logs_headers() -> OtlpLogHeaderSetting:
572593
"""
573594
Checks if x-aws-log-group and x-aws-log-stream are present in the headers in order to send logs to
574595
AWS OTLP Logs endpoint.
575596
597+
When AGENT_OBSERVABILITY_ENABLED is true and OTEL_EXPORTER_OTLP_LOGS_HEADERS is not explicitly set,
598+
this function will attempt to infer the headers from OTEL_RESOURCE_ATTRIBUTES.
599+
576600
Returns:
577601
LogHeadersResult with log_group, log_stream, namespace and is_valid flag
578602
"""
@@ -582,6 +606,25 @@ def _validate_logs_headers() -> OtlpLogHeaderSetting:
582606
log_stream = None
583607
namespace = None
584608

609+
# If logs headers are not explicitly set and agent observability is enabled,
610+
# try to infer from OTEL_RESOURCE_ATTRIBUTES
611+
if not logs_headers and is_agent_observability_enabled():
612+
resource_attrs = _parse_resource_attributes()
613+
614+
# Extract log group and stream from resource attributes
615+
log_group_names = resource_attrs.get("aws.log.group.names", "")
616+
log_stream_names = resource_attrs.get("aws.log.stream.names", "")
617+
618+
if log_group_names and log_stream_names:
619+
# Construct the headers string
620+
inferred_headers = []
621+
inferred_headers.append(f"{AWS_OTLP_LOGS_GROUP_HEADER}={log_group_names}")
622+
inferred_headers.append(f"{AWS_OTLP_LOGS_STREAM_HEADER}={log_stream_names}")
623+
624+
# Use the inferred headers
625+
logs_headers = ",".join(inferred_headers)
626+
_logger.info("Inferred OTEL_EXPORTER_OTLP_LOGS_HEADERS from OTEL_RESOURCE_ATTRIBUTES: %s", logs_headers)
627+
585628
if not logs_headers:
586629
_logger.warning(
587630
"Improper configuration: Please configure the environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS "

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

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,82 @@ def customize_exporter_test(
703703
for key in config.keys():
704704
os.environ.pop(key, None)
705705

706+
def test_validate_logs_headers_infers_from_resource_attributes(self):
707+
"""Test that _validate_logs_headers can infer headers from OTEL_RESOURCE_ATTRIBUTES"""
708+
from amazon.opentelemetry.distro.aws_opentelemetry_configurator import (
709+
_validate_logs_headers,
710+
_parse_resource_attributes,
711+
)
712+
713+
# Test _parse_resource_attributes function
714+
os.environ["OTEL_RESOURCE_ATTRIBUTES"] = (
715+
"service.name=TestService,aws.log.group.names=/aws/genesis/TestAgent,aws.log.stream.names=test-stream"
716+
)
717+
attrs = _parse_resource_attributes()
718+
self.assertEqual(attrs["service.name"], "TestService")
719+
self.assertEqual(attrs["aws.log.group.names"], "/aws/genesis/TestAgent")
720+
self.assertEqual(attrs["aws.log.stream.names"], "test-stream")
721+
722+
# Test inference when AGENT_OBSERVABILITY_ENABLED is true and OTEL_EXPORTER_OTLP_LOGS_HEADERS is not set
723+
os.environ["AGENT_OBSERVABILITY_ENABLED"] = "true"
724+
os.environ["OTEL_RESOURCE_ATTRIBUTES"] = (
725+
"service.name=TestService,aws.log.group.names=/aws/genesis/TestAgent,aws.log.stream.names=test-stream"
726+
)
727+
os.environ.pop("OTEL_EXPORTER_OTLP_LOGS_HEADERS", None)
728+
729+
result = _validate_logs_headers()
730+
self.assertTrue(result.is_valid)
731+
self.assertEqual(result.log_group, "/aws/genesis/TestAgent")
732+
self.assertEqual(result.log_stream, "test-stream")
733+
734+
# Clean up
735+
os.environ.pop("AGENT_OBSERVABILITY_ENABLED", None)
736+
os.environ.pop("OTEL_RESOURCE_ATTRIBUTES", None)
737+
738+
def test_validate_logs_headers_explicit_takes_priority(self):
739+
"""Test that explicit OTEL_EXPORTER_OTLP_LOGS_HEADERS takes priority over inference"""
740+
from amazon.opentelemetry.distro.aws_opentelemetry_configurator import _validate_logs_headers
741+
742+
# Set both explicit headers and resource attributes
743+
os.environ["AGENT_OBSERVABILITY_ENABLED"] = "true"
744+
os.environ["OTEL_RESOURCE_ATTRIBUTES"] = (
745+
"aws.log.group.names=/aws/genesis/InferredAgent,aws.log.stream.names=inferred-stream"
746+
)
747+
os.environ["OTEL_EXPORTER_OTLP_LOGS_HEADERS"] = (
748+
"x-aws-log-group=/aws/genesis/ExplicitAgent,x-aws-log-stream=explicit-stream"
749+
)
750+
751+
result = _validate_logs_headers()
752+
self.assertTrue(result.is_valid)
753+
# Should use explicit headers, not inferred ones
754+
self.assertEqual(result.log_group, "/aws/genesis/ExplicitAgent")
755+
self.assertEqual(result.log_stream, "explicit-stream")
756+
757+
# Clean up
758+
os.environ.pop("AGENT_OBSERVABILITY_ENABLED", None)
759+
os.environ.pop("OTEL_RESOURCE_ATTRIBUTES", None)
760+
os.environ.pop("OTEL_EXPORTER_OTLP_LOGS_HEADERS", None)
761+
762+
def test_validate_logs_headers_no_inference_when_agent_observability_disabled(self):
763+
"""Test that no inference happens when AGENT_OBSERVABILITY_ENABLED is false"""
764+
from amazon.opentelemetry.distro.aws_opentelemetry_configurator import _validate_logs_headers
765+
766+
# Set resource attributes but keep agent observability disabled
767+
os.environ["AGENT_OBSERVABILITY_ENABLED"] = "false"
768+
os.environ["OTEL_RESOURCE_ATTRIBUTES"] = (
769+
"aws.log.group.names=/aws/genesis/TestAgent,aws.log.stream.names=test-stream"
770+
)
771+
os.environ.pop("OTEL_EXPORTER_OTLP_LOGS_HEADERS", None)
772+
773+
result = _validate_logs_headers()
774+
self.assertFalse(result.is_valid)
775+
self.assertIsNone(result.log_group)
776+
self.assertIsNone(result.log_stream)
777+
778+
# Clean up
779+
os.environ.pop("AGENT_OBSERVABILITY_ENABLED", None)
780+
os.environ.pop("OTEL_RESOURCE_ATTRIBUTES", None)
781+
706782

707783
def validate_distro_environ():
708784
tc: TestCase = TestCase()

0 commit comments

Comments
 (0)