From 46f8f1b7c9c1beb5a9c77000519d67c148bb1666 Mon Sep 17 00:00:00 2001 From: Mladjan Gadzic Date: Mon, 30 Mar 2026 11:25:47 +0200 Subject: [PATCH 1/3] add test that confirms silent deprecation warnings --- .../test_log_record_deprecation.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/partial_span_processor/test_log_record_deprecation.py diff --git a/tests/partial_span_processor/test_log_record_deprecation.py b/tests/partial_span_processor/test_log_record_deprecation.py new file mode 100644 index 0000000..856fe61 --- /dev/null +++ b/tests/partial_span_processor/test_log_record_deprecation.py @@ -0,0 +1,26 @@ +import time +import unittest +import warnings + +from opentelemetry._logs.severity import SeverityNumber +from opentelemetry.sdk._logs import LogRecord +from opentelemetry.trace import TraceFlags + + +class TestLogRecordDeprecation(unittest.TestCase): + def test_trace_id_span_id_trace_flags_params_are_deprecated(self): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + LogRecord( + timestamp=time.time_ns(), + observed_timestamp=time.time_ns(), + trace_id=0x1234567890abcdef1234567890abcdef, + span_id=0x1234567890abcdef, + trace_flags=TraceFlags().get_default(), + severity_text="INFO", + severity_number=SeverityNumber.INFO, + body="test", + ) + self.assertEqual(len(w), 1) + self.assertIn("deprecated", str(w[0].message).lower()) + self.assertIn("context", str(w[0].message).lower()) \ No newline at end of file From 48e3361f4994929b7fda828f1035f67e341c3512 Mon Sep 17 00:00:00 2001 From: Mladjan Gadzic Date: Mon, 30 Mar 2026 12:01:12 +0200 Subject: [PATCH 2/3] replace trade_id, span_id and trace_flags with Context --- src/partial_span_processor/__init__.py | 14 +++--- .../test_log_record_deprecation.py | 47 ++++++++++++------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/partial_span_processor/__init__.py b/src/partial_span_processor/__init__.py index 5c663ec..f72316d 100644 --- a/src/partial_span_processor/__init__.py +++ b/src/partial_span_processor/__init__.py @@ -27,7 +27,7 @@ from opentelemetry.proto.trace.v1 import trace_pb2 from opentelemetry.sdk._logs import LogData, LogRecord from opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor -from opentelemetry.trace import TraceFlags +from opentelemetry.trace import set_span_in_context from .peekable_queue import PeekableQueue @@ -172,20 +172,18 @@ def get_log_data(self, span: Span, attributes: dict[str, str]) -> LogData: traces_dict = json.loads(serialized_traces_data) for resource_span in traces_dict.get("resourceSpans", []): for scope_span in resource_span.get("scopeSpans", []): - for span in scope_span.get("spans", []): - span["traceId"] = f"{span_context.trace_id:032x}" - span["spanId"] = f"{span_context.span_id:016x}" + for span_dict in scope_span.get("spans", []): + span_dict["traceId"] = f"{span_context.trace_id:032x}" + span_dict["spanId"] = f"{span_context.span_id:016x}" if parent: - span["parentSpanId"] = f"{parent.span_id:016x}" + span_dict["parentSpanId"] = f"{parent.span_id:016x}" serialized_traces_data = json.dumps(traces_dict, separators=(",", ":")) log_record = LogRecord( timestamp=time.time_ns(), observed_timestamp=time.time_ns(), - trace_id=span_context.trace_id, - span_id=span_context.span_id, - trace_flags=TraceFlags().get_default(), + context=set_span_in_context(span), severity_text="INFO", severity_number=SeverityNumber.INFO, body=serialized_traces_data, diff --git a/tests/partial_span_processor/test_log_record_deprecation.py b/tests/partial_span_processor/test_log_record_deprecation.py index 856fe61..1a6fd06 100644 --- a/tests/partial_span_processor/test_log_record_deprecation.py +++ b/tests/partial_span_processor/test_log_record_deprecation.py @@ -1,26 +1,39 @@ -import time import unittest import warnings -from opentelemetry._logs.severity import SeverityNumber -from opentelemetry.sdk._logs import LogRecord -from opentelemetry.trace import TraceFlags +from opentelemetry.sdk.resources import Resource +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.trace import SpanContext, TraceFlags + +from src.partial_span_processor import PartialSpanProcessor +from tests.partial_span_processor.in_memory_log_exporter import InMemoryLogExporter class TestLogRecordDeprecation(unittest.TestCase): - def test_trace_id_span_id_trace_flags_params_are_deprecated(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - LogRecord( - timestamp=time.time_ns(), - observed_timestamp=time.time_ns(), + def setUp(self): + self.processor = PartialSpanProcessor( + log_exporter=InMemoryLogExporter(), + heartbeat_interval_millis=1000, + initial_heartbeat_delay_millis=1000, + process_interval_millis=1000, + resource=Resource(attributes={"service.name": "test"}), + ) + + def tearDown(self): + self.processor.shutdown() + + def test_get_log_data_produces_no_deprecation_warnings(self): + tracer = TracerProvider().get_tracer("test") + with tracer.start_as_current_span("test_span") as span: + span._context = SpanContext( trace_id=0x1234567890abcdef1234567890abcdef, span_id=0x1234567890abcdef, - trace_flags=TraceFlags().get_default(), - severity_text="INFO", - severity_number=SeverityNumber.INFO, - body="test", + is_remote=False, + trace_flags=TraceFlags(TraceFlags.SAMPLED), ) - self.assertEqual(len(w), 1) - self.assertIn("deprecated", str(w[0].message).lower()) - self.assertIn("context", str(w[0].message).lower()) \ No newline at end of file + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + self.processor.get_log_data(span, {"partial.event": "heartbeat"}) + + deprecation_warnings = [x for x in w if issubclass(x.category, DeprecationWarning)] + self.assertEqual(len(deprecation_warnings), 0) From 96eb722519faa192a90da1ee0b4b3c1d2858ba9a Mon Sep 17 00:00:00 2001 From: Mladjan Gadzic Date: Mon, 30 Mar 2026 13:19:32 +0200 Subject: [PATCH 3/3] pin otel libs versions to comply with internal versions used --- pyproject.toml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c93ea71..4dd9d87 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,14 +17,14 @@ classifiers = [ ] license = { text = "Apache-2.0" } dependencies = [ - "opentelemetry-api", - "opentelemetry-exporter-otlp", - "opentelemetry-exporter-otlp-proto-common", - "opentelemetry-exporter-otlp-proto-grpc", - "opentelemetry-exporter-otlp-proto-http", - "opentelemetry-proto", - "opentelemetry-sdk", - "opentelemetry-semantic-conventions" + "opentelemetry-api>=1.20.0,<1.38", + "opentelemetry-exporter-otlp>=1.20.0,<1.38", + "opentelemetry-exporter-otlp-proto-common>=1.20.0,<1.38", + "opentelemetry-exporter-otlp-proto-grpc>=1.20.0,<1.38", + "opentelemetry-exporter-otlp-proto-http>=1.20.0,<1.38", + "opentelemetry-proto>=1.20.0,<1.38", + "opentelemetry-sdk>=1.20.0,<1.38", + "opentelemetry-semantic-conventions>=0.41b0,<0.59b0" ] [project.urls]