Skip to content

Commit 77c9175

Browse files
jj22eeaws-application-signals-botgithub-actionsliustvemxiamxia
authored
0.10.2 Patch Release (#453)
*Issue #, if available:* *Description of changes:* This PR Cherry-picks: 9b4905f b6fb638 2388f5f 339e83c fc2ef84 2a94c9a a51b226 *Testing:* `git diff other/main --name-only` Result: ``` .github/actions/artifacts_build/action.yml .github/actions/image_scan/action.yml .github/workflows/application-signals-e2e-test.yml .github/workflows/daily_scan.yml .github/workflows/post_release_version_bump.yml .github/workflows/pr_build.yml .github/workflows/pre_release_prepare.yml .github/workflows/release_build.yml ``` By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. --------- Co-authored-by: aws-application-signals-bot <[email protected]> Co-authored-by: github-actions <[email protected]> Co-authored-by: Steve Liu <[email protected]> Co-authored-by: Min Xia <[email protected]> Co-authored-by: Lei Wang <[email protected]>
1 parent 4862354 commit 77c9175

File tree

15 files changed

+1771
-729
lines changed

15 files changed

+1771
-729
lines changed

.github/workflows/daily_scan.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ jobs:
8282
id: high_scan
8383
uses: ./.github/actions/image_scan
8484
with:
85-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.10.0"
85+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.10.1"
8686
severity: 'CRITICAL,HIGH'
8787

8888
- name: Perform low image scan
8989
if: always()
9090
id: low_scan
9191
uses: ./.github/actions/image_scan
9292
with:
93-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.10.0"
93+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.10.1"
9494
severity: 'MEDIUM,LOW,UNKNOWN'
9595

9696
- name: Configure AWS Credentials for emitting metrics

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

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
AwsMetricAttributesSpanExporterBuilder,
2424
)
2525
from amazon.opentelemetry.distro.aws_span_metrics_processor_builder import AwsSpanMetricsProcessorBuilder
26+
from amazon.opentelemetry.distro.exporter.console.logs.compact_console_log_exporter import CompactConsoleLogExporter
2627
from amazon.opentelemetry.distro.otlp_udp_exporter import OTLPUdpSpanExporter
2728
from amazon.opentelemetry.distro.sampler.aws_xray_remote_sampler import AwsXRayRemoteSampler
2829
from amazon.opentelemetry.distro.scope_based_exporter import ScopeBasedPeriodicExportingMetricReader
@@ -46,7 +47,7 @@
4647
)
4748
from opentelemetry.sdk._events import EventLoggerProvider
4849
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
49-
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, LogExporter
50+
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, ConsoleLogExporter, LogExporter
5051
from opentelemetry.sdk.environment_variables import (
5152
_OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED,
5253
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL,
@@ -122,7 +123,14 @@ class OtlpLogHeaderSetting(NamedTuple):
122123
log_group: Optional[str]
123124
log_stream: Optional[str]
124125
namespace: Optional[str]
125-
is_valid: bool
126+
127+
def is_valid(self) -> bool:
128+
"""Check if the log header setting is valid by ensuring both log_group and log_stream are present."""
129+
return self.log_group is not None and self.log_stream is not None
130+
131+
132+
# Singleton cache for OtlpLogHeaderSetting
133+
_otlp_log_header_setting_cache: Optional[OtlpLogHeaderSetting] = None
126134

127135

128136
class AwsOpenTelemetryConfigurator(_OTelSDKConfigurator):
@@ -209,6 +217,9 @@ def _init_logging(
209217
set_logger_provider(provider)
210218

211219
for _, exporter_class in exporters.items():
220+
if exporter_class is ConsoleLogExporter and _is_lambda_environment():
221+
exporter_class = CompactConsoleLogExporter
222+
_logger.debug("Lambda environment detected, using CompactConsoleLogExporter instead of ConsoleLogExporter")
212223
exporter_args = {}
213224
_customize_log_record_processor(
214225
logger_provider=provider, log_exporter=_customize_logs_exporter(exporter_class(**exporter_args))
@@ -440,7 +451,7 @@ def _customize_logs_exporter(log_exporter: LogExporter) -> LogExporter:
440451

441452
if isinstance(log_exporter, OTLPLogExporter):
442453

443-
if _validate_and_fetch_logs_header().is_valid:
454+
if _fetch_logs_header().is_valid():
444455
endpoint, region = _extract_endpoint_and_region_from_otlp_endpoint(logs_endpoint)
445456
# Setting default compression mode to Gzip as this is the behavior in upstream's
446457
# collector otlp http exporter:
@@ -627,18 +638,23 @@ def _extract_endpoint_and_region_from_otlp_endpoint(endpoint: str):
627638
return endpoint, region
628639

629640

630-
def _validate_and_fetch_logs_header() -> OtlpLogHeaderSetting:
631-
"""Checks if x-aws-log-group and x-aws-log-stream are present in the headers in order to send logs to
632-
AWS OTLP Logs endpoint."""
641+
def _fetch_logs_header() -> OtlpLogHeaderSetting:
642+
"""Returns the OTLP log header setting as a singleton instance."""
643+
global _otlp_log_header_setting_cache # pylint: disable=global-statement
644+
645+
if _otlp_log_header_setting_cache is not None:
646+
return _otlp_log_header_setting_cache
633647

634648
logs_headers = os.environ.get(OTEL_EXPORTER_OTLP_LOGS_HEADERS)
635649

636650
if not logs_headers:
637-
_logger.warning(
638-
"Improper configuration: Please configure the environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS "
639-
"to include x-aws-log-group and x-aws-log-stream"
640-
)
641-
return OtlpLogHeaderSetting(None, None, None, False)
651+
if not _is_lambda_environment():
652+
_logger.warning(
653+
"Improper configuration: Please configure the environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS "
654+
"to include x-aws-log-group and x-aws-log-stream"
655+
)
656+
_otlp_log_header_setting_cache = OtlpLogHeaderSetting(None, None, None)
657+
return _otlp_log_header_setting_cache
642658

643659
log_group = None
644660
log_stream = None
@@ -656,9 +672,14 @@ def _validate_and_fetch_logs_header() -> OtlpLogHeaderSetting:
656672
elif key == AWS_EMF_METRICS_NAMESPACE and value:
657673
namespace = value
658674

659-
is_valid = log_group is not None and log_stream is not None
675+
_otlp_log_header_setting_cache = OtlpLogHeaderSetting(log_group, log_stream, namespace)
676+
return _otlp_log_header_setting_cache
677+
660678

661-
return OtlpLogHeaderSetting(log_group, log_stream, namespace, is_valid)
679+
def _clear_logs_header_cache():
680+
"""Clear the singleton cache for OtlpLogHeaderSetting. Used primarily for testing."""
681+
global _otlp_log_header_setting_cache # pylint: disable=global-statement
682+
_otlp_log_header_setting_cache = None
662683

663684

664685
def _get_metric_export_interval():
@@ -773,8 +794,25 @@ def _check_emf_exporter_enabled() -> bool:
773794

774795

775796
def _create_emf_exporter():
776-
"""Create and configure the CloudWatch EMF exporter."""
797+
"""
798+
Create the appropriate EMF exporter based on the environment and configuration.
799+
800+
Returns:
801+
ConsoleEmfExporter for Lambda without log headers log group and stream
802+
AwsCloudWatchEmfExporter for other cases (when conditions are met)
803+
None if CloudWatch exporter cannot be created
804+
"""
777805
try:
806+
log_header_setting = _fetch_logs_header()
807+
808+
# Lambda without valid logs http headers - use Console EMF exporter
809+
if _is_lambda_environment() and not log_header_setting.is_valid():
810+
# pylint: disable=import-outside-toplevel
811+
from amazon.opentelemetry.distro.exporter.aws.metrics.console_emf_exporter import ConsoleEmfExporter
812+
813+
return ConsoleEmfExporter(namespace=log_header_setting.namespace)
814+
815+
# For non-Lambda environment or Lambda with valid headers - use CloudWatch EMF exporter
778816
session = get_aws_session()
779817
# Check if botocore is available before importing the EMF exporter
780818
if not session:
@@ -786,9 +824,7 @@ def _create_emf_exporter():
786824
AwsCloudWatchEmfExporter,
787825
)
788826

789-
log_header_setting = _validate_and_fetch_logs_header()
790-
791-
if not log_header_setting.is_valid:
827+
if not log_header_setting.is_valid():
792828
return None
793829

794830
return AwsCloudWatchEmfExporter(

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import importlib
44
import os
55
import sys
6-
from logging import Logger, getLogger
6+
from logging import ERROR, Logger, getLogger
77

88
from amazon.opentelemetry.distro._utils import get_aws_region, is_agent_observability_enabled
99
from amazon.opentelemetry.distro.aws_opentelemetry_configurator import (
@@ -22,12 +22,17 @@
2222
from opentelemetry import propagate
2323
from opentelemetry.distro import OpenTelemetryDistro
2424
from opentelemetry.environment_variables import OTEL_PROPAGATORS, OTEL_PYTHON_ID_GENERATOR
25+
from opentelemetry.instrumentation.auto_instrumentation import _load
26+
from opentelemetry.instrumentation.logging import LEVELS
27+
from opentelemetry.instrumentation.logging.environment_variables import OTEL_PYTHON_LOG_LEVEL
2528
from opentelemetry.sdk.environment_variables import (
2629
OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION,
2730
OTEL_EXPORTER_OTLP_PROTOCOL,
2831
)
2932

3033
_logger: Logger = getLogger(__name__)
34+
# Suppress configurator warnings from auto-instrumentation
35+
_load._logger.setLevel(LEVELS.get(os.environ.get(OTEL_PYTHON_LOG_LEVEL, "error").lower(), ERROR))
3136

3237

3338
class AwsOpenTelemetryDistro(OpenTelemetryDistro):

0 commit comments

Comments
 (0)