Skip to content

Commit 1fb67a7

Browse files
wangzleiezhang6811github-actionsliustve
authored
Merge main to release/v0.12.x for v0.12.1 releasing (#467)
*Issue #, if available:* *Description of changes:* 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: Eric Zhang <[email protected]> Co-authored-by: github-actions <[email protected]> Co-authored-by: Eric Zhang <[email protected]> Co-authored-by: Steve Liu <[email protected]>
1 parent df17891 commit 1fb67a7

File tree

6 files changed

+101
-29
lines changed

6 files changed

+101
-29
lines changed

.github/workflows/daily-scan.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ jobs:
9595
id: high_scan
9696
uses: ./.github/actions/image_scan
9797
with:
98-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.11.0"
98+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.12.0"
9999
severity: 'CRITICAL,HIGH'
100100
logout: 'false'
101101

@@ -104,7 +104,7 @@ jobs:
104104
id: low_scan
105105
uses: ./.github/actions/image_scan
106106
with:
107-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.11.0"
107+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.12.0"
108108
severity: 'MEDIUM,LOW,UNKNOWN'
109109
logout: 'false'
110110

.github/workflows/release-build.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ jobs:
2828
- name: Checkout Repo @ SHA - ${{ github.sha }}
2929
uses: actions/checkout@v4
3030

31+
- name: Check main build status
32+
env:
33+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34+
run: |
35+
WORKFLOW_ID=$(gh api repos/${{ github.repository }}/actions/workflows --jq '.workflows[] | select(.name=="Python Instrumentation Main Build") | .id')
36+
LATEST_RUN=$(gh api repos/${{ github.repository }}/actions/workflows/$WORKFLOW_ID/runs --jq '[.workflow_runs[] | select(.head_branch=="${{ github.ref_name }}")] | sort_by(.created_at) | .[-1] | {conclusion, status}')
37+
STATUS=$(echo "$LATEST_RUN" | jq -r '.status')
38+
CONCLUSION=$(echo "$LATEST_RUN" | jq -r '.conclusion')
39+
40+
if [ "$STATUS" = "in_progress" ] || [ "$STATUS" = "queued" ]; then
41+
echo "Main build is still running (status: $STATUS). Cannot proceed with release."
42+
exit 1
43+
elif [ "$CONCLUSION" != "success" ]; then
44+
echo "Latest main build on branch ${{ github.ref_name }} conclusion: $CONCLUSION"
45+
exit 1
46+
fi
47+
echo "Main build succeeded, proceeding with release"
48+
3149
- name: Build Wheel and Image Files
3250
uses: ./.github/actions/artifacts_build
3351
with:

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_instrumentation_patch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def apply_instrumentation_patches() -> None:
6767
from amazon.opentelemetry.distro.patches._starlette_patches import _apply_starlette_instrumentation_patches
6868

6969
# Starlette auto-instrumentation v0.54b includes a strict dependency version check
70-
# This restriction was removed in v1.34.0/0.55b0. Applying temporary patch for Genesis launch
70+
# This restriction was removed in v1.34.0/0.55b0. Applying temporary patch for Bedrock AgentCore launch
7171
# TODO: Remove patch after syncing with upstream v1.34.0 or later
7272
_apply_starlette_instrumentation_patches()
7373

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_starlette_patches.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from logging import Logger, getLogger
55
from typing import Collection
66

7+
from amazon.opentelemetry.distro._utils import is_agent_observability_enabled
8+
79
_logger: Logger = getLogger(__name__)
810

911

@@ -18,6 +20,7 @@ def _apply_starlette_instrumentation_patches() -> None:
1820
"""
1921
try:
2022
# pylint: disable=import-outside-toplevel
23+
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
2124
from opentelemetry.instrumentation.starlette import StarletteInstrumentor
2225

2326
# Patch starlette dependencies version check
@@ -28,6 +31,25 @@ def patched_instrumentation_dependencies(self) -> Collection[str]:
2831
# Apply the patch
2932
StarletteInstrumentor.instrumentation_dependencies = patched_instrumentation_dependencies
3033

34+
# pylint: disable=line-too-long
35+
# Patch to exclude http receive/send ASGI event spans from Bedrock AgentCore,
36+
# this Middleware instrumentation is injected internally by Starlette Instrumentor, see:
37+
# https://github.com/open-telemetry/opentelemetry-python-contrib/blob/51da0a766e5d3cbc746189e10c9573163198cfcd/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py#L573
38+
#
39+
# Issue for tracking a feature to customize this setting within Starlette:
40+
# https://github.com/open-telemetry/opentelemetry-python-contrib/issues/3725
41+
if is_agent_observability_enabled():
42+
original_init = OpenTelemetryMiddleware.__init__
43+
44+
def patched_init(self, app, **kwargs):
45+
original_init(self, app, **kwargs)
46+
if hasattr(self, "exclude_receive_span"):
47+
self.exclude_receive_span = True
48+
if hasattr(self, "exclude_send_span"):
49+
self.exclude_send_span = True
50+
51+
OpenTelemetryMiddleware.__init__ = patched_init
52+
3153
_logger.debug("Successfully patched Starlette instrumentation_dependencies method")
3254
except Exception as exc: # pylint: disable=broad-except
3355
_logger.warning("Failed to apply Starlette instrumentation patches: %s", exc)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
__version__ = "0.12.0"
4+
__version__ = "0.12.0.dev0"

aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_starlette_patches.py

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,63 @@ class TestStarlettePatch(TestCase):
1212
@patch("amazon.opentelemetry.distro.patches._starlette_patches._logger")
1313
def test_starlette_patch_applied_successfully(self, mock_logger):
1414
"""Test that the Starlette instrumentation patch is applied successfully."""
15-
# Create a mock StarletteInstrumentor class
16-
mock_instrumentor_class = MagicMock()
17-
mock_instrumentor_class.__name__ = "StarletteInstrumentor"
18-
19-
# Create a mock module
20-
mock_starlette_module = MagicMock()
21-
mock_starlette_module.StarletteInstrumentor = mock_instrumentor_class
22-
23-
# Mock the import
24-
with patch.dict("sys.modules", {"opentelemetry.instrumentation.starlette": mock_starlette_module}):
25-
# Apply the patch
26-
_apply_starlette_instrumentation_patches()
27-
28-
# Verify the instrumentation_dependencies method was replaced
29-
self.assertTrue(hasattr(mock_instrumentor_class, "instrumentation_dependencies"))
30-
31-
# Test the patched method returns the expected value
32-
mock_instance = MagicMock()
33-
result = mock_instrumentor_class.instrumentation_dependencies(mock_instance)
34-
self.assertEqual(result, ("starlette >= 0.13",))
35-
36-
# Verify logging
37-
mock_logger.debug.assert_called_once_with(
38-
"Successfully patched Starlette instrumentation_dependencies method"
39-
)
15+
for agent_enabled in [True, False]:
16+
with self.subTest(agent_enabled=agent_enabled):
17+
with patch.dict("os.environ", {"AGENT_OBSERVABILITY_ENABLED": "true" if agent_enabled else "false"}):
18+
# Create a mock StarletteInstrumentor class
19+
mock_instrumentor_class = MagicMock()
20+
mock_instrumentor_class.__name__ = "StarletteInstrumentor"
21+
22+
def create_middleware_class():
23+
class MockMiddleware:
24+
def __init__(self, app, **kwargs):
25+
pass
26+
27+
return MockMiddleware
28+
29+
mock_middleware_class = create_middleware_class()
30+
31+
mock_starlette_module = MagicMock()
32+
mock_starlette_module.StarletteInstrumentor = mock_instrumentor_class
33+
34+
mock_asgi_module = MagicMock()
35+
mock_asgi_module.OpenTelemetryMiddleware = mock_middleware_class
36+
37+
with patch.dict(
38+
"sys.modules",
39+
{
40+
"opentelemetry.instrumentation.starlette": mock_starlette_module,
41+
"opentelemetry.instrumentation.asgi": mock_asgi_module,
42+
},
43+
):
44+
# Apply the patch
45+
_apply_starlette_instrumentation_patches()
46+
47+
# Verify the instrumentation_dependencies method was replaced
48+
self.assertTrue(hasattr(mock_instrumentor_class, "instrumentation_dependencies"))
49+
50+
# Test the patched method returns the expected value
51+
mock_instance = MagicMock()
52+
result = mock_instrumentor_class.instrumentation_dependencies(mock_instance)
53+
self.assertEqual(result, ("starlette >= 0.13",))
54+
55+
mock_middleware_instance = MagicMock()
56+
mock_middleware_instance.exclude_receive_span = False
57+
mock_middleware_instance.exclude_send_span = False
58+
mock_middleware_class.__init__(mock_middleware_instance, "app")
59+
60+
# Test middleware patching sets exclude flags
61+
if agent_enabled:
62+
self.assertTrue(mock_middleware_instance.exclude_receive_span)
63+
self.assertTrue(mock_middleware_instance.exclude_send_span)
64+
else:
65+
self.assertFalse(mock_middleware_instance.exclude_receive_span)
66+
self.assertFalse(mock_middleware_instance.exclude_send_span)
67+
68+
# Verify logging
69+
mock_logger.debug.assert_called_with(
70+
"Successfully patched Starlette instrumentation_dependencies method"
71+
)
4072

4173
@patch("amazon.opentelemetry.distro.patches._starlette_patches._logger")
4274
def test_starlette_patch_handles_import_error(self, mock_logger):

0 commit comments

Comments
 (0)