Skip to content

Commit 30b1eba

Browse files
authored
Merge branch 'main' into add-lambda-layer-default-region
2 parents affcc1b + 46c9248 commit 30b1eba

21 files changed

+4579
-319
lines changed

.github/workflows/release-lambda.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212
default: 'us-east-1, us-east-2, us-west-1, us-west-2, ap-south-1, ap-northeast-3, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-north-1, sa-east-1, af-south-1, ap-east-1, ap-south-2, ap-southeast-3, ap-southeast-4, eu-central-2, eu-south-1, eu-south-2, il-central-1, me-central-1, me-south-1, ap-southeast-5, ap-southeast-7, mx-central-1, ca-west-1, cn-north-1, cn-northwest-1'
1313

1414
env:
15-
COMMERCIAL_REGIONS: us-east-1, us-east-2, us-west-1, us-west-2, ap-south-1, ap-northeast-3, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-north-1, sa-east-1
15+
COMMERCIAL_REGIONS: us-east-1, us-east-2, us-west-1, us-west-2, ap-south-1, ap-northeast-3, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-north-1, sa-east-1, ap-southeast-5, ap-southeast-7, mx-central-1, ca-west-1, cn-north-1, cn-northwest-1
1616
LAYER_NAME: AWSOpenTelemetryDistroPython
1717

1818
permissions:

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,32 @@ def is_installed(req: str) -> bool:
3535
def is_agent_observability_enabled() -> bool:
3636
"""Is the Agentic AI monitoring flag set to true?"""
3737
return os.environ.get(AGENT_OBSERVABILITY_ENABLED, "false").lower() == "true"
38+
39+
40+
def get_aws_region() -> str:
41+
"""Get AWS region using botocore session.
42+
43+
botocore automatically checks in the following priority order:
44+
1. AWS_REGION environment variable
45+
2. AWS_DEFAULT_REGION environment variable
46+
3. AWS CLI config file (~/.aws/config)
47+
4. EC2 instance metadata service
48+
49+
Returns:
50+
The AWS region if found, None otherwise.
51+
"""
52+
if is_installed("botocore"):
53+
try:
54+
from botocore import session # pylint: disable=import-outside-toplevel
55+
56+
botocore_session = session.Session()
57+
if botocore_session.region_name:
58+
return botocore_session.region_name
59+
except (ImportError, AttributeError):
60+
# botocore failed to determine region
61+
pass
62+
63+
_logger.warning(
64+
"AWS region not found. Please set AWS_REGION environment variable or configure AWS CLI with 'aws configure'."
65+
)
66+
return None

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@
102102
# UDP package size is not larger than 64KB
103103
LAMBDA_SPAN_EXPORT_BATCH_SIZE = 10
104104

105+
OTEL_TRACES_EXPORTER = "OTEL_TRACES_EXPORTER"
106+
OTEL_LOGS_EXPORTER = "OTEL_LOGS_EXPORTER"
107+
OTEL_METRICS_EXPORTER = "OTEL_METRICS_EXPORTER"
108+
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT"
109+
OTEL_TRACES_SAMPLER = "OTEL_TRACES_SAMPLER"
110+
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS = "OTEL_PYTHON_DISABLED_INSTRUMENTATIONS"
111+
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED = "OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED"
112+
105113
_logger: Logger = getLogger(__name__)
106114

107115

@@ -265,6 +273,17 @@ def _export_unsampled_span_for_lambda(trace_provider: TracerProvider, resource:
265273
)
266274

267275

276+
def _export_unsampled_span_for_agent_observability(trace_provider: TracerProvider, resource: Resource = None):
277+
if not is_agent_observability_enabled():
278+
return
279+
280+
traces_endpoint = os.environ.get(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)
281+
282+
span_exporter = OTLPAwsSpanExporter(endpoint=traces_endpoint, logger_provider=get_logger_provider())
283+
284+
trace_provider.add_span_processor(BatchUnsampledSpanProcessor(span_exporter=span_exporter))
285+
286+
268287
def _is_defer_to_workers_enabled():
269288
return os.environ.get(OTEL_AWS_PYTHON_DEFER_TO_WORKERS_ENABLED_CONFIG, "false").strip().lower() == "true"
270289

@@ -408,9 +427,14 @@ def _customize_span_processors(provider: TracerProvider, resource: Resource) ->
408427
if _is_lambda_environment():
409428
provider.add_span_processor(AwsLambdaSpanProcessor())
410429

430+
# We always send 100% spans to Genesis platform for agent observability because
431+
# AI applications typically have low throughput traffic patterns and require
432+
# comprehensive monitoring to catch subtle failure modes like hallucinations
433+
# and quality degradation that sampling could miss.
411434
# Add session.id baggage attribute to span attributes to support AI Agent use cases
412435
# enabling session ID tracking in spans.
413436
if is_agent_observability_enabled():
437+
_export_unsampled_span_for_agent_observability(provider, resource)
414438

415439
def session_id_predicate(baggage_key: str) -> bool:
416440
return baggage_key == "session.id"

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44
import sys
55
from logging import Logger, getLogger
66

7+
from amazon.opentelemetry.distro._utils import get_aws_region, is_agent_observability_enabled
8+
from amazon.opentelemetry.distro.aws_opentelemetry_configurator import (
9+
APPLICATION_SIGNALS_ENABLED_CONFIG,
10+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
11+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
12+
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT,
13+
OTEL_LOGS_EXPORTER,
14+
OTEL_METRICS_EXPORTER,
15+
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,
16+
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED,
17+
OTEL_TRACES_EXPORTER,
18+
OTEL_TRACES_SAMPLER,
19+
)
720
from amazon.opentelemetry.distro.patches._instrumentation_patch import apply_instrumentation_patches
821
from opentelemetry.distro import OpenTelemetryDistro
922
from opentelemetry.environment_variables import OTEL_PROPAGATORS, OTEL_PYTHON_ID_GENERATOR
@@ -65,5 +78,44 @@ def _configure(self, **kwargs):
6578
OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, "base2_exponential_bucket_histogram"
6679
)
6780

81+
if is_agent_observability_enabled():
82+
# "otlp" is already native OTel default, but we set them here to be explicit
83+
# about intended configuration for agent observability
84+
os.environ.setdefault(OTEL_TRACES_EXPORTER, "otlp")
85+
os.environ.setdefault(OTEL_LOGS_EXPORTER, "otlp")
86+
os.environ.setdefault(OTEL_METRICS_EXPORTER, "awsemf")
87+
88+
# Set GenAI capture content default
89+
os.environ.setdefault(OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, "true")
90+
91+
# Set OTLP endpoints with AWS region if not already set
92+
region = get_aws_region()
93+
if region:
94+
os.environ.setdefault(
95+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, f"https://xray.{region}.amazonaws.com/v1/traces"
96+
)
97+
os.environ.setdefault(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, f"https://logs.{region}.amazonaws.com/v1/logs")
98+
else:
99+
_logger.warning(
100+
"AWS region could not be determined. OTLP endpoints will not be automatically configured. "
101+
"Please set AWS_REGION environment variable or configure OTLP endpoints manually."
102+
)
103+
104+
# Set sampler default
105+
os.environ.setdefault(OTEL_TRACES_SAMPLER, "parentbased_always_on")
106+
107+
# Set disabled instrumentations default
108+
os.environ.setdefault(
109+
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,
110+
"http,sqlalchemy,psycopg2,pymysql,sqlite3,aiopg,asyncpg,mysql_connector,"
111+
"botocore,boto3,urllib3,requests,starlette",
112+
)
113+
114+
# Set logging auto instrumentation default
115+
os.environ.setdefault(OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED, "true")
116+
117+
# Disable AWS Application Signals by default
118+
os.environ.setdefault(APPLICATION_SIGNALS_ENABLED_CONFIG, "false")
119+
68120
if kwargs.get("apply_patches", True):
69121
apply_instrumentation_patches()

0 commit comments

Comments
 (0)