Skip to content

Commit a45694c

Browse files
Add LogRecord init priority for context's span over old span info
1 parent 5308eee commit a45694c

File tree

2 files changed

+64
-12
lines changed

2 files changed

+64
-12
lines changed

opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,17 @@ def __init__(
189189
attributes: _ExtendedAttributes | None = None,
190190
limits: LogLimits | None = _UnsetLogLimits,
191191
):
192+
# Prioritizes context over trace_id / span_id / trace_flags.
193+
# If context provided and its current span valid, then uses that span info.
194+
# Otherwise, uses provided trace_id etc for backwards compatibility.
195+
if context is not None:
196+
span = get_current_span(context)
197+
span_context = span.get_span_context()
198+
if span_context.is_valid:
199+
trace_id = span_context.trace_id
200+
span_id = span_context.span_id
201+
trace_flags = span_context.trace_flags
202+
192203
super().__init__(
193204
**{
194205
"timestamp": timestamp,

opentelemetry-sdk/tests/logs/test_handler.py

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
)
3131
from opentelemetry.semconv._incubating.attributes import code_attributes
3232
from opentelemetry.semconv.attributes import exception_attributes
33-
from opentelemetry.trace import INVALID_SPAN_CONTEXT
33+
from opentelemetry.trace import (
34+
INVALID_SPAN_CONTEXT,
35+
set_span_in_context,
36+
)
3437

3538

3639
class TestLoggingHandler(unittest.TestCase):
@@ -92,19 +95,26 @@ def test_log_flush_noop(self):
9295

9396
def test_log_record_no_span_context(self):
9497
processor, logger = set_up_test_logging(logging.WARNING)
98+
mock_context = Context()
9599

96-
# Assert emit gets called for warning message
97-
with self.assertLogs(level=logging.WARNING):
98-
logger.warning("Warning message")
100+
with patch(
101+
"opentelemetry.sdk._logs._internal.get_current",
102+
return_value=mock_context,
103+
):
104+
# Assert emit gets called for warning message
105+
with self.assertLogs(level=logging.WARNING):
106+
logger.warning("Warning message")
99107

100-
log_record = processor.get_log_record(0)
108+
log_record = processor.get_log_record(0)
101109

102-
self.assertIsNotNone(log_record)
103-
self.assertEqual(log_record.trace_id, INVALID_SPAN_CONTEXT.trace_id)
104-
self.assertEqual(log_record.span_id, INVALID_SPAN_CONTEXT.span_id)
105-
self.assertEqual(
106-
log_record.trace_flags, INVALID_SPAN_CONTEXT.trace_flags
107-
)
110+
self.assertIsNotNone(log_record)
111+
self.assertEqual(
112+
log_record.trace_id, INVALID_SPAN_CONTEXT.trace_id
113+
)
114+
self.assertEqual(log_record.span_id, INVALID_SPAN_CONTEXT.span_id)
115+
self.assertEqual(
116+
log_record.trace_flags, INVALID_SPAN_CONTEXT.trace_flags
117+
)
108118

109119
def test_log_record_observed_timestamp(self):
110120
processor, logger = set_up_test_logging(logging.WARNING)
@@ -269,7 +279,38 @@ def __str__(self):
269279

270280
def test_log_record_trace_correlation(self):
271281
processor, logger = set_up_test_logging(logging.WARNING)
272-
mock_context = Context()
282+
283+
tracer = trace.TracerProvider().get_tracer(__name__)
284+
with tracer.start_as_current_span("test") as span:
285+
mock_context = set_span_in_context(span)
286+
287+
with patch(
288+
"opentelemetry.sdk._logs._internal.get_current",
289+
return_value=mock_context,
290+
):
291+
with self.assertLogs(level=logging.CRITICAL):
292+
logger.critical("Critical message within span")
293+
294+
log_record = processor.get_log_record(0)
295+
296+
self.assertEqual(
297+
log_record.body, "Critical message within span"
298+
)
299+
self.assertEqual(log_record.severity_text, "CRITICAL")
300+
self.assertEqual(
301+
log_record.severity_number, SeverityNumber.FATAL
302+
)
303+
self.assertEqual(log_record.context, mock_context)
304+
span_context = span.get_span_context()
305+
self.assertEqual(log_record.trace_id, span_context.trace_id)
306+
self.assertEqual(log_record.span_id, span_context.span_id)
307+
self.assertEqual(
308+
log_record.trace_flags, span_context.trace_flags
309+
)
310+
311+
def test_log_record_trace_correlation_backwards_compatibility(self):
312+
processor, logger = set_up_test_logging(logging.WARNING)
313+
mock_context = Context() # no span in context
273314

274315
tracer = trace.TracerProvider().get_tracer(__name__)
275316
with tracer.start_as_current_span("test") as span:

0 commit comments

Comments
 (0)