Skip to content

Commit 4a81d41

Browse files
committed
Merge remote-tracking branch 'origin/main' into refactor_final2
2 parents 3d3b34c + b85775c commit 4a81d41

File tree

7 files changed

+51
-13
lines changed

7 files changed

+51
-13
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
and make the control flow more clear ([#4562](https://github.com/open-telemetry/opentelemetry-python/pull/4562/)
1414
[#4535](https://github.com/open-telemetry/opentelemetry-python/pull/4535), and
1515
[#4580](https://github.com/open-telemetry/opentelemetry-python/pull/4580)).
16+
- Remove log messages from `BatchLogRecordProcessor.emit`, this caused the program
17+
to crash at shutdown with a max recursion error ([#4586](https://github.com/open-telemetry/opentelemetry-python/pull/4586)).
18+
- Configurable max retry timeout for grpc exporter
19+
([#4333](https://github.com/open-telemetry/opentelemetry-python/pull/4333))
20+
- opentelemetry-api: allow importlib-metadata 8.7.0
21+
([#4593](https://github.com/open-telemetry/opentelemetry-python/pull/4593))
1622

1723
## Version 1.33.0/0.54b0 (2025-05-09)
1824

@@ -94,8 +100,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
94100
([#4353](https://github.com/open-telemetry/opentelemetry-python/pull/4353))
95101
- sdk: don't log or print warnings when the SDK has been disabled
96102
([#4371](https://github.com/open-telemetry/opentelemetry-python/pull/4371))
97-
- Configurable max retry timeout for grpc exporter
98-
([#4333](https://github.com/open-telemetry/opentelemetry-python/pull/4333))
99103
- Fix span context manager typing by using ParamSpec from typing_extensions
100104
([#4389](https://github.com/open-telemetry/opentelemetry-python/pull/4389))
101105
- Fix serialization of None values in logs body to match 1.31.0+ data model

opentelemetry-api/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ dependencies = [
3030
"Deprecated >= 1.2.6",
3131
# FIXME This should be able to be removed after 3.12 is released if there is a reliable API
3232
# in importlib.metadata.
33-
"importlib-metadata >= 6.0, < 8.7.0",
33+
"importlib-metadata >= 6.0, < 8.8.0",
3434
]
3535
dynamic = [
3636
"version",

opentelemetry-api/test-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
asgiref==3.7.2
22
Deprecated==1.2.14
33
importlib-metadata==8.5.0 ; python_version < "3.9"
4-
importlib-metadata==8.6.1 ; python_version >= "3.9"
4+
importlib-metadata==8.7.0 ; python_version >= "3.9"
55
iniconfig==2.0.0
66
packaging==24.0
77
pluggy==1.5.0

opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,15 @@ def _export(self, batch_strategy: BatchExportStrategy) -> None:
167167
)
168168
detach(token)
169169

170+
# Do not add any logging.log statements to this function, they can be being routed back to this `emit` function,
171+
# resulting in endless recursive calls that crash the program.
172+
# See https://github.com/open-telemetry/opentelemetry-python/issues/4261
170173
def emit(self, data: Telemetry) -> None:
171174
if self._shutdown:
172-
self._logger.info("Shutdown called, ignoring %s.", self._exporting)
173175
return
174176
if self._pid != os.getpid():
175177
self._bsp_reset_once.do_once(self._at_fork_reinit)
176-
177-
if len(self._queue) == self._max_queue_size:
178-
self._logger.warning("Queue full, dropping %s.", self._exporting)
178+
# This will drop a log from the right side if the queue is at _max_queue_length.
179179
self._queue.appendleft(data)
180180
if len(self._queue) >= self._max_export_batch_size:
181181
self._worker_awaken.set()

opentelemetry-sdk/tests/logs/test_export.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
import os
1818
import time
1919
import unittest
20+
from sys import version_info
2021
from unittest.mock import Mock, patch
2122

23+
from pytest import mark
24+
2225
from opentelemetry._logs import SeverityNumber
2326
from opentelemetry.sdk import trace
2427
from opentelemetry.sdk._logs import (
@@ -344,6 +347,39 @@ def test_emit_call_log_record(self):
344347
logger.error("error")
345348
self.assertEqual(log_record_processor.emit.call_count, 1)
346349

350+
@mark.skipif(
351+
version_info < (3, 10),
352+
reason="assertNoLogs only exists in python 3.10+.",
353+
)
354+
def test_logging_lib_not_invoked_in_batch_log_record_emit(self): # pylint: disable=no-self-use
355+
# See https://github.com/open-telemetry/opentelemetry-python/issues/4261
356+
exporter = Mock()
357+
processor = BatchLogRecordProcessor(exporter)
358+
logger_provider = LoggerProvider(
359+
resource=SDKResource.create(
360+
{
361+
"service.name": "shoppingcart",
362+
"service.instance.id": "instance-12",
363+
}
364+
),
365+
)
366+
logger_provider.add_log_record_processor(processor)
367+
handler = LoggingHandler(
368+
level=logging.INFO, logger_provider=logger_provider
369+
)
370+
sdk_logger = logging.getLogger("opentelemetry.sdk")
371+
# Attach OTLP handler to SDK logger
372+
sdk_logger.addHandler(handler)
373+
# If `emit` calls logging.log then this test will throw a maximum recursion depth exceeded exception and fail.
374+
try:
375+
with self.assertNoLogs(sdk_logger, logging.NOTSET):
376+
processor.emit(EMPTY_LOG)
377+
processor.shutdown()
378+
with self.assertNoLogs(sdk_logger, logging.NOTSET):
379+
processor.emit(EMPTY_LOG)
380+
finally:
381+
sdk_logger.removeHandler(handler)
382+
347383
def test_args(self):
348384
exporter = InMemoryLogExporter()
349385
log_record_processor = BatchLogRecordProcessor(

opentelemetry-sdk/tests/shared_internal/test_batch_processor.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def test_telemetry_exported_once_schedule_delay_reached(
9898
exporter.export.assert_called_once_with([telemetry])
9999

100100
def test_telemetry_flushed_before_shutdown_and_dropped_after_shutdown(
101-
self, batch_processor_class, telemetry, caplog
101+
self, batch_processor_class, telemetry
102102
):
103103
exporter = Mock()
104104
batch_processor = batch_processor_class(
@@ -116,9 +116,7 @@ def test_telemetry_flushed_before_shutdown_and_dropped_after_shutdown(
116116
assert batch_processor._batch_processor._shutdown is True
117117

118118
# This should not be flushed.
119-
batch_processor._batch_processor.emit(telemetry)
120-
assert len(caplog.records) == 1
121-
assert "Shutdown called, ignoring" in caplog.text
119+
batch_processor.emit(telemetry)
122120
exporter.export.assert_called_once()
123121

124122
# pylint: disable=no-self-use

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)