Skip to content

Commit 817eb4f

Browse files
wrap export call in try block
1 parent cb4abe7 commit 817eb4f

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

src/partial_span_processor/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import datetime
1818
import json
19+
import logging
1920
import threading
2021
import time
2122
from typing import TYPE_CHECKING
@@ -28,7 +29,7 @@
2829
from opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor
2930
from opentelemetry.trace import TraceFlags
3031

31-
from partial_span_processor.peekable_queue import PeekableQueue
32+
from .peekable_queue import PeekableQueue
3233

3334
if TYPE_CHECKING:
3435
from opentelemetry import context as context_api
@@ -40,6 +41,7 @@
4041
DEFAULT_INITIAL_HEARTBEAT_DELAY_MILLIS = 5000
4142
DEFAULT_PROCESS_INTERVAL_MILLIS = 5000
4243

44+
_logger = logging.getLogger(__name__)
4345

4446
def validate_parameters(log_exporter, heartbeat_interval_millis,
4547
initial_heartbeat_delay_millis, process_interval_millis):
@@ -131,7 +133,10 @@ def on_end(self, span: ReadableSpan) -> None:
131133

132134
def export_log(self, span, attributes: dict[str, str]) -> None:
133135
log_data = self.get_log_data(span, attributes)
134-
self.log_exporter.export([log_data])
136+
try:
137+
self.log_exporter.export([log_data])
138+
except Exception:
139+
_logger.exception("Exception while exporting logs.")
135140

136141
def shutdown(self) -> None:
137142
# signal the worker thread to finish and then wait for it

tests/partial_span_processor/test_partial_span_processor.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,73 @@ def test_process_ready_heartbeat_spans(self):
200200
self.assertEqual(logs[0].log_record.attributes["partial.event"],
201201
"heartbeat")
202202

203+
@patch('src.partial_span_processor._logger')
204+
def test_export_log_handles_export_exception(self, mock_logger):
205+
# Create a mock log exporter that raises an exception
206+
failing_exporter = mock.Mock()
207+
failing_exporter.export.side_effect = Exception("Export failed")
208+
209+
# Create processor with failing exporter
210+
processor = PartialSpanProcessor(
211+
log_exporter=failing_exporter,
212+
heartbeat_interval_millis=1000,
213+
initial_heartbeat_delay_millis=1000,
214+
process_interval_millis=1000,
215+
)
216+
217+
try:
218+
span = TestPartialSpanProcessor.create_mock_span()
219+
220+
# This should not raise an exception despite the exporter failing
221+
processor.export_log(span, {"test": "attribute"})
222+
223+
# Verify the exception was logged
224+
mock_logger.exception.assert_called_once_with(
225+
"Exception while exporting logs.")
226+
227+
# Verify export was attempted
228+
failing_exporter.export.assert_called_once()
229+
finally:
230+
processor.shutdown()
231+
232+
@patch('src.partial_span_processor._logger')
233+
def test_export_log_handles_runtime_error(self, mock_logger):
234+
# Create a mock log exporter that raises a RuntimeError
235+
failing_exporter = mock.Mock()
236+
failing_exporter.export.side_effect = RuntimeError(
237+
"Runtime error during export")
238+
239+
processor = PartialSpanProcessor(
240+
log_exporter=failing_exporter,
241+
heartbeat_interval_millis=1000,
242+
initial_heartbeat_delay_millis=1000,
243+
process_interval_millis=1000,
244+
)
245+
246+
try:
247+
span = TestPartialSpanProcessor.create_mock_span()
248+
249+
# This should not raise an exception
250+
processor.export_log(span, {"test": "attribute"})
251+
252+
# Verify the exception was logged
253+
mock_logger.exception.assert_called_once_with(
254+
"Exception while exporting logs.")
255+
finally:
256+
processor.shutdown()
257+
258+
def test_export_log_succeeds_normally(self):
259+
# Test that normal operation still works
260+
span = TestPartialSpanProcessor.create_mock_span()
261+
262+
# This should work normally
263+
self.processor.export_log(span, {"test": "attribute"})
264+
265+
# Verify log was exported successfully
266+
logs = self.log_exporter.get_finished_logs()
267+
self.assertEqual(len(logs), 1)
268+
self.assertEqual(logs[0].log_record.attributes["test"], "attribute")
269+
203270

204271
if __name__ == "__main__":
205272
unittest.main()

0 commit comments

Comments
 (0)