diff --git a/sentry_sdk/opentelemetry/span_processor.py b/sentry_sdk/opentelemetry/span_processor.py index abfb712a89..b5279bccb0 100644 --- a/sentry_sdk/opentelemetry/span_processor.py +++ b/sentry_sdk/opentelemetry/span_processor.py @@ -289,8 +289,12 @@ def _span_to_json(self, span): if parent_span_id: span_json["parent_span_id"] = parent_span_id - if span.attributes: - span_json["data"] = dict(span.attributes) + attributes = getattr(span, "attributes", {}) or {} + if attributes: + span_json["data"] = {} + for key, value in attributes.items(): + if not key.startswith("_"): + span_json["data"][key] = value return span_json diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 388cf38cef..92ac4d7671 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -588,10 +588,10 @@ def set_context(self, key, value): def set_flag(self, flag, value): # type: (str, bool) -> None - flag_count = self.get_attribute("flag.count") or 0 + flag_count = self.get_attribute("_flag.count") or 0 if flag_count < _FLAGS_CAPACITY: self.set_attribute(f"flag.evaluation.{flag}", value) - self.set_attribute("flag.count", flag_count + 1) + self.set_attribute("_flag.count", flag_count + 1) # TODO-neel-potel add deprecation diff --git a/tests/integrations/threading/test_threading.py b/tests/integrations/threading/test_threading.py index 4ab742ff1f..8a5dfef62b 100644 --- a/tests/integrations/threading/test_threading.py +++ b/tests/integrations/threading/test_threading.py @@ -9,7 +9,6 @@ import sentry_sdk from sentry_sdk import capture_message from sentry_sdk.integrations.threading import ThreadingIntegration -from sentry_sdk.tracing import _OTEL_VERSION original_start = Thread.start original_run = Thread.run @@ -106,10 +105,7 @@ def double(number): assert len(event["spans"]) == 0 -@pytest.mark.skipif( - sys.version[:3] == "3.8" and (1, 12) <= _OTEL_VERSION < (1, 16), - reason="Fails in CI on 3.8 and specific OTel versions", -) +@pytest.mark.skipif(sys.version[:3] == "3.8", reason="Fails in CI on 3.8") def test_circular_references(sentry_init, request): sentry_init(default_integrations=False, integrations=[ThreadingIntegration()]) diff --git a/tests/opentelemetry/test_span_processor.py b/tests/opentelemetry/test_span_processor.py new file mode 100644 index 0000000000..7d6283d4ea --- /dev/null +++ b/tests/opentelemetry/test_span_processor.py @@ -0,0 +1,19 @@ +import sentry_sdk + + +def test_span_processor_omits_underscore_attributes(sentry_init, capture_events): + sentry_init(traces_sample_rate=1.0) + + events = capture_events() + + with sentry_sdk.start_span(): + with sentry_sdk.start_span() as span: + span.set_attribute("_internal", 47) + span.set_attribute("noninternal", 23) + + assert span._otel_span.attributes["_internal"] == 47 + assert span._otel_span.attributes["noninternal"] == 23 + + outgoing_span = events[0]["spans"][0] + assert "_internal" not in outgoing_span["data"] + assert "noninternal" in outgoing_span["data"] diff --git a/tests/test_feature_flags.py b/tests/test_feature_flags.py index 1b0ed13d49..5c2f1cd352 100644 --- a/tests/test_feature_flags.py +++ b/tests/test_feature_flags.py @@ -259,3 +259,19 @@ def test_flag_limit(sentry_init, capture_events): } ) assert "flag.evaluation.10" not in event["spans"][0]["data"] + + +def test_flag_counter_not_sent(sentry_init, capture_events): + sentry_init(traces_sample_rate=1.0) + + events = capture_events() + + with start_transaction(name="hi"): + with start_span(op="foo", name="bar"): + add_feature_flag("0", True) + add_feature_flag("1", True) + add_feature_flag("2", True) + add_feature_flag("3", True) + + (event,) = events + assert "_flag.count" not in event["spans"][0]["data"]