|
15 | 15 | # pylint: disable=protected-access |
16 | 16 | import logging |
17 | 17 | import os |
| 18 | +import random |
18 | 19 | import time |
19 | 20 | import unittest |
20 | 21 | from concurrent.futures import ThreadPoolExecutor |
21 | | -from sys import version_info |
22 | 22 | from typing import Sequence |
23 | 23 | from unittest.mock import Mock, patch |
24 | 24 |
|
|
63 | 63 |
|
64 | 64 |
|
65 | 65 | class TestSimpleLogRecordProcessor(unittest.TestCase): |
| 66 | + @mark.skipif( |
| 67 | + version_info=(3, 13), |
| 68 | + reason="This will fail on 3.13 due to https://github.com/python/cpython/pull/131812 which prevents recursive log messages but was later rolled back.", |
| 69 | + ) |
66 | 70 | def test_simple_log_record_processor_doesnt_enter_recursive_loop(self): |
67 | 71 | class Exporter(LogExporter): |
68 | 72 | def shutdown(self): |
69 | 73 | pass |
70 | 74 |
|
71 | 75 | def export(self, batch: Sequence[LogData]): |
72 | | - raise ValueError("Exception raised !") |
| 76 | + raise ValueError( |
| 77 | + "Exception raised ! {}".format(random.randint(1, 10000)) |
| 78 | + ) |
73 | 79 |
|
74 | 80 | exporter = Exporter() |
75 | 81 | logger_provider = LoggerProvider() |
76 | 82 | logger_provider.add_log_record_processor( |
77 | 83 | SimpleLogRecordProcessor(exporter) |
78 | 84 | ) |
79 | 85 | root_logger = logging.getLogger() |
80 | | - root_logger.addHandler(LoggingHandler(level=logging.NOTSET,logger_provider=logger_provider)) |
| 86 | + # Add the OTLP handler to the root logger like is done in auto instrumentation. |
| 87 | + # This means logs generated from within SimpleLogRecordProcessor.on_emit are sent back to SimpleLogRecordProcessor.on_emit |
| 88 | + handler = LoggingHandler( |
| 89 | + level=logging.DEBUG, logger_provider=logger_provider |
| 90 | + ) |
| 91 | + root_logger.addHandler(handler) |
| 92 | + propagate_false_logger = logging.getLogger( |
| 93 | + "opentelemetry.sdk._logs._internal.export.propagate.false" |
| 94 | + ) |
81 | 95 | # This would cause a max recursion depth exceeded error.. |
82 | | - root_logger.warning("Something is wrong") |
| 96 | + try: |
| 97 | + with self.assertLogs(propagate_false_logger) as cm: |
| 98 | + root_logger.warning("hello!") |
| 99 | + assert ( |
| 100 | + "SimpleLogRecordProcessor.on_emit has entered a recursive loop" |
| 101 | + in cm.output[0] |
| 102 | + ) |
| 103 | + finally: |
| 104 | + root_logger.removeHandler(handler) |
83 | 105 |
|
84 | 106 | def test_simple_log_record_processor_default_level(self): |
85 | 107 | exporter = InMemoryLogExporter() |
@@ -403,39 +425,6 @@ def bulk_emit(num_emit): |
403 | 425 | time.sleep(2) |
404 | 426 | assert len(exporter.get_finished_logs()) == total_expected_logs |
405 | 427 |
|
406 | | - @mark.skipif( |
407 | | - version_info < (3, 10), |
408 | | - reason="assertNoLogs only exists in python 3.10+.", |
409 | | - ) |
410 | | - def test_logging_lib_not_invoked_in_batch_log_record_emit(self): # pylint: disable=no-self-use |
411 | | - # See https://github.com/open-telemetry/opentelemetry-python/issues/4261 |
412 | | - exporter = Mock() |
413 | | - processor = BatchLogRecordProcessor(exporter) |
414 | | - logger_provider = LoggerProvider( |
415 | | - resource=SDKResource.create( |
416 | | - { |
417 | | - "service.name": "shoppingcart", |
418 | | - "service.instance.id": "instance-12", |
419 | | - } |
420 | | - ), |
421 | | - ) |
422 | | - logger_provider.add_log_record_processor(processor) |
423 | | - handler = LoggingHandler( |
424 | | - level=logging.INFO, logger_provider=logger_provider |
425 | | - ) |
426 | | - sdk_logger = logging.getLogger("opentelemetry.sdk") |
427 | | - # Attach OTLP handler to SDK logger |
428 | | - sdk_logger.addHandler(handler) |
429 | | - # If `emit` calls logging.log then this test will throw a maximum recursion depth exceeded exception and fail. |
430 | | - try: |
431 | | - with self.assertNoLogs(sdk_logger, logging.NOTSET): |
432 | | - processor.on_emit(EMPTY_LOG) |
433 | | - processor.shutdown() |
434 | | - with self.assertNoLogs(sdk_logger, logging.NOTSET): |
435 | | - processor.on_emit(EMPTY_LOG) |
436 | | - finally: |
437 | | - sdk_logger.removeHandler(handler) |
438 | | - |
439 | 428 | def test_args(self): |
440 | 429 | exporter = InMemoryLogExporter() |
441 | 430 | log_record_processor = BatchLogRecordProcessor( |
|
0 commit comments