Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/5199.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`opentelemetry-sdk`: use context parameter instead of deprecated trace_id/span_id/trace_flags kwargs in EventLogger.emit
28 changes: 24 additions & 4 deletions opentelemetry-sdk/src/opentelemetry/sdk/_events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,34 @@ def emit(self, event: Event) -> None:
if isinstance(self._logger, NoOpLogger):
# Do nothing if SDK is disabled
return
span_context = trace.get_current_span().get_span_context()

# Build a context that carries the event's trace correlation.
# If the Event was constructed with explicit trace_id/span_id,
# wrap them in a NonRecordingSpan so LogRecord picks them up
# from context instead of requiring the deprecated kwargs.
context = event.context
span_context = trace.get_current_span(context).get_span_context()
if (
event.trace_id != span_context.trace_id
or event.span_id != span_context.span_id
or event.trace_flags != span_context.trace_flags
):
context = trace.set_span_in_context(
trace.NonRecordingSpan(
trace.SpanContext(
trace_id=event.trace_id,
span_id=event.span_id,
is_remote=False,
trace_flags=event.trace_flags,
)
),
context,
)

log_record = LogRecord(
timestamp=event.timestamp or time_ns(),
observed_timestamp=None,
trace_id=event.trace_id or span_context.trace_id,
span_id=event.span_id or span_context.span_id,
trace_flags=event.trace_flags or span_context.trace_flags,
context=context,
severity_text=None,
severity_number=event.severity_number or SeverityNumber.INFO,
body=event.body,
Expand Down
61 changes: 46 additions & 15 deletions opentelemetry-sdk/tests/events/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
# pylint: disable=protected-access,no-self-use

import unittest
import warnings
from unittest.mock import Mock, patch

from opentelemetry import trace
from opentelemetry._events import Event
from opentelemetry._logs import SeverityNumber, set_logger_provider
from opentelemetry.sdk._events import EventLoggerProvider
Expand Down Expand Up @@ -112,15 +114,9 @@ def test_event_logger_emit(self, logger_mock, log_record_mock):
"name", "version", "schema_url", {"key": "value"}
)
now = Mock()
trace_id = Mock()
span_id = Mock()
trace_flags = Mock()
event = Event(
name="test_event",
timestamp=now,
trace_id=trace_id,
span_id=span_id,
trace_flags=trace_flags,
body="test body",
severity_number=SeverityNumber.ERROR,
attributes={
Expand All @@ -135,9 +131,7 @@ def test_event_logger_emit(self, logger_mock, log_record_mock):
log_record_mock.assert_called_once_with(
timestamp=now,
observed_timestamp=None,
trace_id=trace_id,
span_id=span_id,
trace_flags=trace_flags,
context=event.context,
severity_text=None,
severity_number=SeverityNumber.ERROR,
body="test body",
Expand All @@ -149,6 +143,49 @@ def test_event_logger_emit(self, logger_mock, log_record_mock):
)
logger_mock_inst.emit.assert_called_once_with(log_record_mock_inst)

@patch("opentelemetry.sdk._logs._internal.LoggerProvider.get_logger")
def test_event_logger_emit_explicit_trace_ids(self, logger_mock):
"""Explicit trace_id/span_id on Event are preserved without deprecation warning."""
logger_provider = LoggerProvider()
logger_mock_inst = Mock()
logger_mock.return_value = logger_mock_inst
event_logger = EventLoggerProvider(logger_provider).get_event_logger(
"name",
)
explicit_trace_id = 0x1234567890ABCDEF1234567890ABCDEF
explicit_span_id = 0x1234567890ABCDEF
explicit_trace_flags = trace.TraceFlags(trace.TraceFlags.SAMPLED)
event = Event(
name="test_event",
timestamp=1000,
trace_id=explicit_trace_id,
span_id=explicit_span_id,
trace_flags=explicit_trace_flags,
body="test body",
)
# Emit should not trigger LogDeprecatedInitWarning
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
event_logger.emit(event)
deprecated_init_warnings = [
w
for w in caught
if "LogRecord" in str(w.message)
and "deprecated" in str(w.message).lower()
and "trace_id" in str(w.message)
]
self.assertEqual(
len(deprecated_init_warnings),
0,
f"Unexpected deprecation warnings: {deprecated_init_warnings}",
)
# Verify the emitted LogRecord has the explicit trace data
logger_mock_inst.emit.assert_called_once()
emitted_record = logger_mock_inst.emit.call_args[0][0]
self.assertEqual(emitted_record.trace_id, explicit_trace_id)
self.assertEqual(emitted_record.span_id, explicit_span_id)
self.assertEqual(emitted_record.trace_flags, explicit_trace_flags)

@patch("opentelemetry.sdk._events.LogRecord")
@patch("opentelemetry.sdk._logs._internal.LoggerProvider.get_logger")
def test_event_logger_emit_sdk_disabled(
Expand All @@ -167,15 +204,9 @@ def test_event_logger_emit_sdk_disabled(
"name", "version", "schema_url", {"key": "value"}
)
now = Mock()
trace_id = Mock()
span_id = Mock()
trace_flags = Mock()
event = Event(
name="test_event",
timestamp=now,
trace_id=trace_id,
span_id=span_id,
trace_flags=trace_flags,
body="test body",
severity_number=SeverityNumber.ERROR,
attributes={
Expand Down
Loading