Skip to content

Commit d25bf7d

Browse files
authored
Merge branch 'main' into feature/add-metrics-to-grpc
2 parents cf6e4b3 + 0af9010 commit d25bf7d

12 files changed

Lines changed: 160 additions & 75 deletions

File tree

.changelog/4433.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
`opentelemetry-instrumentation-flask`: wrap wsgi_app call in try/except to prevent active_requests gauge leak

.changelog/4613.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
`opentelemetry-instrumentation-aiokafka`, `opentelemetry-instrumentation-confluent-kafka`, `opentelemetry-instrumentation-kafka-python`: fix malformed RST formatting in module docstrings

.github/workflows/prepare-patch-release.yml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ jobs:
110110
run: .github/scripts/use-cla-approved-github-bot.sh
111111

112112
- name: Backport patch release changelog to main
113+
id: backport_pr
113114
env:
114115
GITHUB_TOKEN: ${{ steps.otelbot-token.outputs.token }}
115116
run: |
@@ -121,11 +122,19 @@ jobs:
121122
git fetch origin $release_branch
122123
123124
# Copy the updated CHANGELOG.md from the release branch
124-
git checkout $release_branch -- CHANGELOG.md
125+
git checkout FETCH_HEAD -- CHANGELOG.md
125126
git commit -m "$message"
126127
127128
git push origin HEAD:$branch
128-
gh pr create --title "$message" \
129-
--body "$body" \
130-
--head $branch \
131-
--base main
129+
pr_url=$(gh pr create --title "$message" \
130+
--body "$body" \
131+
--head $branch \
132+
--base main)
133+
echo "pr_url=$pr_url" >> $GITHUB_OUTPUT
134+
135+
- name: Add Skip Changelog label to backport PR
136+
if: steps.backport_pr.outputs.pr_url != ''
137+
env:
138+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
139+
run: |
140+
gh pr edit ${{ steps.backport_pr.outputs.pr_url }} --add-label "Skip Changelog"

.github/workflows/prepare-release-branch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,4 @@ jobs:
227227
env:
228228
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
229229
run: |
230-
gh pr edit ${{ steps.create_main_pr.outputs.pr_url }} --add-label "prepare-release"
230+
gh pr edit ${{ steps.create_main_pr.outputs.pr_url }} --add-label "prepare-release" --add-label "Skip Changelog"

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
2020
<!-- changelog start -->
2121

22+
## Version 1.42.1/0.63b1 (2026-05-21)
23+
24+
No significant changes.
25+
2226
## Version 1.42.0/0.63b0 (2026-05-19)
2327

2428
### Added

docs/nitpick-exceptions.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ py-class=
4646
psycopg.AsyncConnection
4747
ObjectProxy
4848
wrapt.proxies.ObjectProxy
49+
_wrappers.ObjectProxy
4950
fastapi.applications.FastAPI
5051
starlette.applications.Starlette
5152
_contextvars.Token

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

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,26 @@ async def consume():
3939
asyncio.run(produce())
4040
asyncio.run(consume())
4141
42-
The _instrument() method accepts the following keyword args:
43-
tracer_provider (TracerProvider) - an optional tracer provider
44-
async_produce_hook (Callable) - a function with extra user-defined logic to be performed before sending the message
45-
this function signature is:
46-
def async_produce_hook(span: Span, args, kwargs)
47-
async_consume_hook (Callable) - a function with extra user-defined logic to be performed after consuming a message
48-
this function signature is:
49-
def async_consume_hook(span: Span, record: kafka.record.ABCRecord, args, kwargs)
50-
for example:
42+
The ``_instrument()`` method accepts the following keyword args:
43+
44+
- **tracer_provider** (TracerProvider) - an optional tracer provider
45+
- **async_produce_hook** (Callable) - a function with extra user-defined logic to be performed before sending the message
46+
47+
Function signature:
48+
49+
.. code:: python
50+
51+
async def async_produce_hook(span: Span, args, kwargs): ...
52+
53+
- **async_consume_hook** (Callable) - a function with extra user-defined logic to be performed after consuming a message
54+
55+
Function signature:
56+
57+
.. code:: python
58+
59+
async def async_consume_hook(span: Span, record: kafka.record.ABCRecord, args, kwargs): ...
60+
61+
For example:
5162
5263
.. code:: python
5364
@@ -79,7 +90,7 @@ async def produce():
7990
asyncio.run(produce())
8091
8192
API
82-
___
93+
---
8394
"""
8495

8596
from __future__ import annotations

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,13 @@ def setUp(self):
323323

324324
self.env_patch.start()
325325

326+
def tearDown(self):
327+
self.env_patch.stop()
328+
super().tearDown()
329+
326330
def subTest(self, msg=..., **params):
327331
sub = super().subTest(msg, **params)
328-
# Reinitialize test state to avoid state pollution
329-
self.setUp()
332+
self.memory_exporter.clear()
330333
return sub
331334

332335
# Helper to assert exemplars presence across specified histogram metric names.

instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,26 @@ def basic_consume_loop(consumer, topics):
4747
4848
basic_consume_loop(consumer, ["my-topic"])
4949
50-
The _instrument method accepts the following keyword args:
51-
tracer_provider (TracerProvider) - an optional tracer provider
50+
The ``_instrument()`` method accepts the following keyword args:
5251
53-
instrument_producer (Callable) - a function with extra user-defined logic to be performed before sending the message
54-
this function signature is:
52+
- **tracer_provider** (TracerProvider) - an optional tracer provider
53+
- **instrument_producer** (Callable) - a function with extra user-defined logic to be performed before sending the message
5554
56-
def instrument_producer(producer: Producer, tracer_provider=None)
55+
Function signature:
5756
58-
instrument_consumer (Callable) - a function with extra user-defined logic to be performed after consuming a message
59-
this function signature is:
57+
.. code:: python
6058
61-
def instrument_consumer(consumer: Consumer, tracer_provider=None)
62-
for example:
59+
def instrument_producer(producer: Producer, tracer_provider=None): ...
60+
61+
- **instrument_consumer** (Callable) - a function with extra user-defined logic to be performed after consuming a message
62+
63+
Function signature:
64+
65+
.. code:: python
66+
67+
def instrument_consumer(consumer: Consumer, tracer_provider=None): ...
68+
69+
For example:
6370
6471
.. code:: python
6572

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

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -405,48 +405,50 @@ def _start_response(status, response_headers, *args, **kwargs):
405405
response_hook(span, status, response_headers)
406406
return start_response(status, response_headers, *args, **kwargs)
407407

408-
result = wsgi_app(wrapped_app_environ, _start_response)
409-
410-
# Note: Streaming response context cleanup is now handled in the Flask teardown function
411-
# (_wrapped_teardown_request) to ensure proper cleanup following Logfire's recommendations
412-
# for OpenTelemetry generator context management
413-
414-
if should_trace:
415-
duration_s = default_timer() - start
416-
# Get the span from wrapped_app_environ and re-create context manually
417-
# to pass to histogram for exemplars generation
418-
span = wrapped_app_environ.get(_ENVIRON_SPAN_KEY)
419-
metrics_context = trace.set_span_in_context(span)
420-
421-
if duration_histogram_old:
422-
duration_attrs_old = otel_wsgi._parse_duration_attrs(
423-
attributes, _StabilityMode.DEFAULT
424-
)
408+
try:
409+
result = wsgi_app(wrapped_app_environ, _start_response)
425410

426-
if request_route:
427-
# http.target to be included in old semantic conventions
428-
duration_attrs_old[HTTP_TARGET] = str(request_route)
429-
duration_histogram_old.record(
430-
max(round(duration_s * 1000), 0),
431-
duration_attrs_old,
432-
context=metrics_context,
433-
)
434-
if duration_histogram_new:
435-
duration_attrs_new = otel_wsgi._parse_duration_attrs(
436-
attributes, _StabilityMode.HTTP
437-
)
411+
# Note: Streaming response context cleanup is now handled in the Flask teardown function
412+
# (_wrapped_teardown_request) to ensure proper cleanup following Logfire's recommendations
413+
# for OpenTelemetry generator context management
414+
415+
if should_trace:
416+
duration_s = default_timer() - start
417+
# Get the span from wrapped_app_environ and re-create context manually
418+
# to pass to histogram for exemplars generation
419+
span = wrapped_app_environ.get(_ENVIRON_SPAN_KEY)
420+
metrics_context = trace.set_span_in_context(span)
421+
422+
if duration_histogram_old:
423+
duration_attrs_old = otel_wsgi._parse_duration_attrs(
424+
attributes, _StabilityMode.DEFAULT
425+
)
426+
427+
if request_route:
428+
# http.target to be included in old semantic conventions
429+
duration_attrs_old[HTTP_TARGET] = str(request_route)
430+
duration_histogram_old.record(
431+
max(round(duration_s * 1000), 0),
432+
duration_attrs_old,
433+
context=metrics_context,
434+
)
435+
if duration_histogram_new:
436+
duration_attrs_new = otel_wsgi._parse_duration_attrs(
437+
attributes, _StabilityMode.HTTP
438+
)
438439

439-
if request_route:
440-
duration_attrs_new[HTTP_ROUTE] = str(request_route)
440+
if request_route:
441+
duration_attrs_new[HTTP_ROUTE] = str(request_route)
441442

442-
duration_histogram_new.record(
443-
max(duration_s, 0),
444-
duration_attrs_new,
445-
context=metrics_context,
446-
)
443+
duration_histogram_new.record(
444+
max(duration_s, 0),
445+
duration_attrs_new,
446+
context=metrics_context,
447+
)
447448

448-
active_requests_counter.add(-1, active_requests_count_attrs)
449-
return result
449+
return result
450+
finally:
451+
active_requests_counter.add(-1, active_requests_count_attrs)
450452

451453
def _should_trace(excluded_urls) -> bool:
452454
return bool(

0 commit comments

Comments
 (0)