Skip to content

Commit e9bbecb

Browse files
authored
Merge branch 'main' into tnorth/fix
2 parents 72da2fb + fd21563 commit e9bbecb

File tree

29 files changed

+757
-274
lines changed

29 files changed

+757
-274
lines changed

.github/ISSUE_TEMPLATE/bug_report.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,11 @@ body:
6464
options:
6565
- "No"
6666
- "Yes"
67+
68+
- type: dropdown
69+
attributes:
70+
label: Tip
71+
description: This element is static, used to render a helpful sub-heading for end-users and community members to help prioritize issues. Please leave as is.
72+
options:
73+
- <sub>[React](https://github.blog/news-insights/product-news/add-reactions-to-pull-requests-issues-and-comments/) with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding `+1` or `me too`, to help us triage it. Learn more [here](https://opentelemetry.io/community/end-user/issue-participation/).</sub>
74+
default: 0

.github/ISSUE_TEMPLATE/feature_request.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,11 @@ body:
4848
options:
4949
- "No"
5050
- "Yes"
51+
52+
- type: dropdown
53+
attributes:
54+
label: Tip
55+
description: This element is static, used to render a helpful sub-heading for end-users and community members to help prioritize issues. Please leave as is.
56+
options:
57+
- <sub>[React](https://github.blog/news-insights/product-news/add-reactions-to-pull-requests-issues-and-comments/) with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding `+1` or `me too`, to help us triage it. Learn more [here](https://opentelemetry.io/community/end-user/issue-participation/).</sub>
58+
default: 0

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
### Fixed
1515

16+
- `opentelemetry-instrumentation-fastapi`: Fix middleware ordering to cover all exception handling use cases.
17+
([#3664](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3664))
18+
- `opentelemetry-instrumentation-asgi`: Make all user hooks failsafe and record exceptions in hooks.
19+
([#3664](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3664))
1620
- `opentelemetry-instrumentation-fastapi`: Fix memory leak in `uninstrument_app()` by properly removing apps from the tracking set
17-
([#3688](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3688)
21+
([#3688](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3688))
1822
- `opentelemetry-instrumentation-tornado` Fix server (request) duration metric calculation
1923
([#3679](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3679))
24+
- `opentelemetry-instrumentation-tornado`: Fix to properly skip all server telemetry when URL excluded.
25+
([#3680](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3680))
2026
- `opentelemetry-instrumentation`: Avoid calls to `context.detach` with `None` token.
2127
([#3673](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3673))
28+
- `opentelemetry-instrumentation-starlette`/`opentelemetry-instrumentation-fastapi`: Fixes a crash when host-based routing is used
29+
([#3507](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3507))
30+
- Fix documentation order of sections and headers for Django, Flask, MySQL, mysqlclient, psycopg, psycopg2, pymysql, sqlalchemy instrumentations.
31+
([#3719](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3719))
2232

2333
### Added
2434

@@ -28,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2838
([#3666](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3666))
2939
- `opentelemetry-sdk-extension-aws` Add AWS X-Ray Remote Sampler with initial Rules Poller implementation
3040
([#3366](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3366))
41+
- `opentelemetry-instrumentation`: add support for `OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH` to inform opentelemetry-instrument about gevent monkeypatching
42+
([#3699](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3699))
3143

3244
## Version 1.36.0/0.57b0 (2025-07-29)
3345

instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/main.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@
44
from openai import OpenAI
55

66
# NOTE: OpenTelemetry Python Logs and Events APIs are in beta
7-
from opentelemetry import _events, _logs, trace
7+
from opentelemetry import _events, _logs, metrics, trace
88
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import (
99
OTLPLogExporter,
1010
)
11+
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import (
12+
OTLPMetricExporter,
13+
)
1114
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
1215
OTLPSpanExporter,
1316
)
1417
from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor
1518
from opentelemetry.sdk._events import EventLoggerProvider
1619
from opentelemetry.sdk._logs import LoggerProvider
1720
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
21+
from opentelemetry.sdk.metrics import MeterProvider
22+
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
1823
from opentelemetry.sdk.trace import TracerProvider
1924
from opentelemetry.sdk.trace.export import BatchSpanProcessor
2025

@@ -31,6 +36,17 @@
3136
)
3237
_events.set_event_logger_provider(EventLoggerProvider())
3338

39+
# configure metrics
40+
metrics.set_meter_provider(
41+
MeterProvider(
42+
metric_readers=[
43+
PeriodicExportingMetricReader(
44+
OTLPMetricExporter(),
45+
),
46+
]
47+
)
48+
)
49+
3450
# instrument OpenAI
3551
OpenAIInstrumentor().instrument()
3652

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
openai~=1.57.3
22

3-
opentelemetry-sdk~=1.30.0
4-
opentelemetry-exporter-otlp-proto-grpc~=1.30.0
3+
opentelemetry-sdk~=1.36.0
4+
opentelemetry-exporter-otlp-proto-grpc~=1.36.0
55
opentelemetry-instrumentation-openai-v2~=2.1b0
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
openai~=1.57.3
22

3-
opentelemetry-sdk~=1.30.0
4-
opentelemetry-exporter-otlp-proto-grpc~=1.30.0
5-
opentelemetry-distro~=0.51b0
3+
opentelemetry-sdk~=1.36.0
4+
opentelemetry-exporter-otlp-proto-grpc~=1.36.0
5+
opentelemetry-distro~=0.57b0
66
opentelemetry-instrumentation-openai-v2~=2.1b0

instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/events.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
# type: ignore[reportUnknownDeprecated]
16+
1517
"""
1618
Factories for event types described in
1719
https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md#system-event.

instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
# type: ignore[reportUnknownDeprecated]
16+
1517
from __future__ import annotations
1618

1719
import re

instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ def client_response_hook(span: Span, scope: Scope, message: dict[str, Any]):
268268
HTTP_SERVER_REQUEST_DURATION,
269269
)
270270
from opentelemetry.semconv.trace import SpanAttributes
271-
from opentelemetry.trace import set_span_in_context
271+
from opentelemetry.trace import Span, set_span_in_context
272272
from opentelemetry.util.http import (
273273
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS,
274274
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST,
@@ -646,9 +646,23 @@ def __init__(
646646
self.default_span_details = (
647647
default_span_details or get_default_span_details
648648
)
649-
self.server_request_hook = server_request_hook
650-
self.client_request_hook = client_request_hook
651-
self.client_response_hook = client_response_hook
649+
650+
def failsafe(func):
651+
if func is None:
652+
return None
653+
654+
@wraps(func)
655+
def wrapper(span: Span, *args, **kwargs):
656+
try:
657+
func(span, *args, **kwargs)
658+
except Exception as exc: # pylint: disable=broad-exception-caught
659+
span.record_exception(exc)
660+
661+
return wrapper
662+
663+
self.server_request_hook = failsafe(server_request_hook)
664+
self.client_request_hook = failsafe(client_request_hook)
665+
self.client_response_hook = failsafe(client_response_hook)
652666
self.content_length_header = None
653667
self._sem_conv_opt_in_mode = sem_conv_opt_in_mode
654668

instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,17 @@ async def error_asgi(scope, receive, send):
277277
await send({"type": "http.response.body", "body": b"*"})
278278

279279

280+
class UnhandledException(Exception):
281+
pass
282+
283+
284+
def failing_hook(msg):
285+
def hook(*_):
286+
raise UnhandledException(msg)
287+
288+
return hook
289+
290+
280291
# pylint: disable=too-many-public-methods
281292
class TestAsgiApplication(AsyncAsgiTestBase):
282293
def setUp(self):
@@ -481,6 +492,12 @@ def validate_outputs(
481492
span.instrumentation_scope.name,
482493
"opentelemetry.instrumentation.asgi",
483494
)
495+
if "events" in expected:
496+
self.assertEqual(len(span.events), len(expected["events"]))
497+
for event, expected in zip(span.events, expected["events"]):
498+
self.assertEqual(event.name, expected["name"])
499+
for name, value in expected["attributes"].items():
500+
self.assertEqual(event.attributes[name], value)
484501

485502
async def test_basic_asgi_call(self):
486503
"""Test that spans are emitted as expected."""
@@ -1206,6 +1223,40 @@ def update_expected_hook_results(expected):
12061223
outputs, modifiers=[update_expected_hook_results]
12071224
)
12081225

1226+
async def test_hook_exceptions(self):
1227+
def exception_event(msg):
1228+
return {
1229+
"name": "exception",
1230+
"attributes": {
1231+
"exception.type": f"{__name__}.UnhandledException",
1232+
"exception.message": msg,
1233+
},
1234+
}
1235+
1236+
def update_expected_hook_results(expected):
1237+
for entry in expected:
1238+
if entry["kind"] == trace_api.SpanKind.SERVER:
1239+
entry["events"] = [exception_event("server request")]
1240+
elif entry["name"] == "GET / http receive":
1241+
entry["events"] = [exception_event("client request")]
1242+
elif entry["name"] == "GET / http send":
1243+
entry["events"] = [exception_event("client response")]
1244+
1245+
return expected
1246+
1247+
app = otel_asgi.OpenTelemetryMiddleware(
1248+
simple_asgi,
1249+
server_request_hook=failing_hook("server request"),
1250+
client_request_hook=failing_hook("client request"),
1251+
client_response_hook=failing_hook("client response"),
1252+
)
1253+
self.seed_app(app)
1254+
await self.send_default_request()
1255+
outputs = await self.get_all_output()
1256+
self.validate_outputs(
1257+
outputs, modifiers=[update_expected_hook_results]
1258+
)
1259+
12091260
async def test_asgi_metrics(self):
12101261
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
12111262
self.seed_app(app)

0 commit comments

Comments
 (0)