Skip to content

Commit

Permalink
fix: include_tracing_fields arg to control unvetted data in rust_trac…
Browse files Browse the repository at this point in the history
…ing integration
  • Loading branch information
antonpirker authored and matt-codecov committed Nov 14, 2024
1 parent 4bec4a4 commit 9817d2a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 24 deletions.
30 changes: 18 additions & 12 deletions sentry_sdk/integrations/rust_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,21 @@ def __init__(
[Dict[str, Any]], EventTypeMapping
] = default_event_type_mapping,
span_filter: Callable[[Dict[str, Any]], bool] = default_span_filter,
send_sensitive_data: Optional[bool] = None,
include_tracing_fields: Optional[bool] = None,
):
self.origin = origin
self.event_type_mapping = event_type_mapping
self.span_filter = span_filter
self.send_sensitive_data = send_sensitive_data
self.include_tracing_fields = include_tracing_fields

def _include_tracing_fields(self) -> bool:
"""
By default, the values of tracing fields are not included in case they
contain PII. A user may override that by passing `True` for the
`include_tracing_fields` keyword argument of this integration or by
setting `send_default_pii` to `True` in their Sentry client options.
"""
return should_send_default_pii() if self.include_tracing_fields is None else self.include_tracing_fields

def on_event(self, event: str, _span_state: TraceState) -> None:
deserialized_event = json.loads(event)
Expand Down Expand Up @@ -207,7 +216,10 @@ def on_new_span(self, attrs: str, span_id: str) -> TraceState:

fields = metadata.get("fields", [])
for field in fields:
sentry_span.set_data(field, attrs.get(field))
if self._include_tracing_fields():
sentry_span.set_data(field, attrs.get(field))
else:
sentry_span.set_data(field, SENSITIVE_DATA_SUBSTITUTE)

scope.span = sentry_span
return (parent_sentry_span, sentry_span)
Expand All @@ -225,15 +237,9 @@ def on_record(self, span_id: str, values: str, span_state: TraceState) -> None:
return
_parent_sentry_span, sentry_span = span_state

send_sensitive_data = (
should_send_default_pii()
if self.send_sensitive_data is None
else self.send_sensitive_data
)

deserialized_values = json.loads(values)
for key, value in deserialized_values.items():
if send_sensitive_data:
if self._include_tracing_fields():
sentry_span.set_data(key, value)
else:
sentry_span.set_data(key, SENSITIVE_DATA_SUBSTITUTE)
Expand All @@ -259,12 +265,12 @@ def __init__(
[Dict[str, Any]], EventTypeMapping
] = default_event_type_mapping,
span_filter: Callable[[Dict[str, Any]], bool] = default_span_filter,
send_sensitive_data: Optional[bool] = None,
include_tracing_fields: Optional[bool] = None,
):
self.identifier = identifier
origin = f"auto.function.rust_tracing.{identifier}"
self.tracing_layer = RustTracingLayer(
origin, event_type_mapping, span_filter, send_sensitive_data
origin, event_type_mapping, span_filter, include_tracing_fields
)

initializer(self.tracing_layer)
Expand Down
49 changes: 37 additions & 12 deletions tests/integrations/rust_tracing/test_rust_tracing.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from unittest import mock
import pytest

from string import Template
Expand Down Expand Up @@ -66,7 +67,9 @@ def record(self, span_id: int):
def test_on_new_span_on_close(sentry_init, capture_events):
rust_tracing = FakeRustTracing()
integration = RustTracingIntegration(
"test_on_new_span_on_close", rust_tracing.set_layer_impl
"test_on_new_span_on_close",
initializer=rust_tracing.set_layer_impl,
include_tracing_fields=True,
)
sentry_init(integrations=[integration], traces_sample_rate=1.0)

Expand Down Expand Up @@ -105,7 +108,9 @@ def test_on_new_span_on_close(sentry_init, capture_events):
def test_nested_on_new_span_on_close(sentry_init, capture_events):
rust_tracing = FakeRustTracing()
integration = RustTracingIntegration(
"test_nested_on_new_span_on_close", rust_tracing.set_layer_impl
"test_nested_on_new_span_on_close",
initializer=rust_tracing.set_layer_impl,
include_tracing_fields=True,
)
sentry_init(integrations=[integration], traces_sample_rate=1.0)

Expand Down Expand Up @@ -331,7 +336,10 @@ def span_filter(metadata: Dict[str, object]) -> bool:

rust_tracing = FakeRustTracing()
integration = RustTracingIntegration(
"test_span_filter", rust_tracing.set_layer_impl, span_filter=span_filter
"test_span_filter",
initializer=rust_tracing.set_layer_impl,
span_filter=span_filter,
include_tracing_fields=True,
)
sentry_init(integrations=[integration], traces_sample_rate=1.0)

Expand Down Expand Up @@ -365,7 +373,7 @@ def test_record(sentry_init):
integration = RustTracingIntegration(
"test_record",
initializer=rust_tracing.set_layer_impl,
send_sensitive_data=True,
include_tracing_fields=True,
)
sentry_init(integrations=[integration], traces_sample_rate=1.0)

Expand All @@ -391,6 +399,7 @@ def span_filter(metadata: Dict[str, object]) -> bool:
"test_record_in_ignored_span",
rust_tracing.set_layer_impl,
span_filter=span_filter,
include_tracing_fields=True,
)
sentry_init(integrations=[integration], traces_sample_rate=1.0)

Expand All @@ -409,7 +418,7 @@ def span_filter(metadata: Dict[str, object]) -> bool:


@pytest.mark.parametrize(
"send_default_pii, send_sensitive_data, sensitive_data_expected",
"send_default_pii, include_tracing_fields, tracing_fields_expected",
[
(True, True, True),
(True, False, False),
Expand All @@ -419,14 +428,14 @@ def span_filter(metadata: Dict[str, object]) -> bool:
(False, None, False),
],
)
def test_sensitive_data(
sentry_init, send_default_pii, send_sensitive_data, sensitive_data_expected
def test_include_tracing_fields(
sentry_init, send_default_pii, include_tracing_fields, tracing_fields_expected
):
rust_tracing = FakeRustTracing()
integration = RustTracingIntegration(
"test_record",
initializer=rust_tracing.set_layer_impl,
send_sensitive_data=send_sensitive_data,
include_tracing_fields=include_tracing_fields,
)

sentry_init(
Expand All @@ -438,13 +447,29 @@ def test_sensitive_data(
rust_tracing.new_span(RustTracingLevel.Info, 3)

span_before_record = sentry_sdk.get_current_span().to_json()
assert span_before_record["data"]["version"] is None
if tracing_fields_expected:
assert span_before_record["data"]["version"] is None
else:
assert span_before_record["data"]["version"] == "[Filtered]"

rust_tracing.record(3)

span_after_record = sentry_sdk.get_current_span().to_json()

if sensitive_data_expected:
assert span_after_record["data"]["version"] == "memoized"
if tracing_fields_expected:
assert span_after_record["data"] == {
"thread.id": mock.ANY,
"thread.name": mock.ANY,
"use_memoized": True,
"version": "memoized",
"index": 10,
}

else:
assert span_after_record["data"]["version"] == "[Filtered]"
assert span_after_record["data"] == {
"thread.id": mock.ANY,
"thread.name": mock.ANY,
"use_memoized": "[Filtered]",
"version": "[Filtered]",
"index": "[Filtered]",
}

0 comments on commit 9817d2a

Please sign in to comment.