Skip to content
Merged
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
9 changes: 2 additions & 7 deletions sentry_sdk/integrations/redis/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
_MULTI_KEY_COMMANDS,
_SINGLE_KEY_COMMANDS,
)
from sentry_sdk.scope import should_send_default_pii
from sentry_sdk.traces import Span
from sentry_sdk.utils import SENSITIVE_DATA_SUBSTITUTE, has_data_collection_enabled
from sentry_sdk.utils import SENSITIVE_DATA_SUBSTITUTE

if TYPE_CHECKING:
from typing import Any, Optional, Sequence
Expand All @@ -20,7 +19,6 @@ def _get_safe_command(name: str, args: "Sequence[Any]") -> str:
command_parts = [name]

name_low = name.lower()
send_default_pii = should_send_default_pii()
client_options = sentry_sdk.get_client().options

for i, arg in enumerate(args):
Expand All @@ -35,10 +33,7 @@ def _get_safe_command(name: str, args: "Sequence[Any]") -> str:
if arg_is_the_key:
command_parts.append(repr(arg))
else:
if has_data_collection_enabled(client_options):
if client_options["data_collection"]["database_query_data"]:
Comment thread
cursor[bot] marked this conversation as resolved.
command_parts.append(repr(arg))
elif send_default_pii:
if client_options["data_collection"]["database_query_data"]:
command_parts.append(repr(arg))
else:
command_parts.append(SENSITIVE_DATA_SUBSTITUTE)
Expand Down
167 changes: 3 additions & 164 deletions tests/integrations/redis/test_redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,52 +42,6 @@ def test_basic(sentry_init, capture_events):
}


@pytest.mark.parametrize(
"is_transaction, send_default_pii, expected_first_ten",
[
(False, False, ["GET 'foo'", "SET 'bar' [Filtered]", "SET 'baz' [Filtered]"]),
(True, True, ["GET 'foo'", "SET 'bar' 1", "SET 'baz' 2"]),
],
)
def test_redis_pipeline(
sentry_init,
capture_events,
capture_items,
is_transaction,
send_default_pii,
expected_first_ten,
):
sentry_init(
integrations=[RedisIntegration()],
traces_sample_rate=1.0,
send_default_pii=send_default_pii,
)

connection = FakeRedis()

items = capture_items("span")

with sentry_sdk.start_span(name="custom parent"):
pipeline = connection.pipeline(transaction=is_transaction)
pipeline.get("foo")
pipeline.set("bar", 1)
pipeline.set("baz", 2)
pipeline.execute()

sentry_sdk.flush()

assert len(items) == 2
pipeline_span, parent_span = items[0].payload, items[1].payload

assert parent_span["name"] == "custom parent"
assert parent_span["is_segment"] is True

assert pipeline_span["name"] == "redis.pipeline.execute"
assert pipeline_span["attributes"]["sentry.op"] == "db.redis"
assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis"
assert pipeline_span["attributes"][SPANDATA.DB_SYSTEM_NAME] == "redis"


@pytest.mark.parametrize(
"data_collection, expected_first_ten",
[
Expand Down Expand Up @@ -135,38 +89,6 @@ def test_redis_pipeline_data_collection(
assert pipeline_span["attributes"]["sentry.op"] == "db.redis"


def test_sensitive_data(
sentry_init,
capture_events,
capture_items,
):
# fakeredis does not support the AUTH command, so we need to mock it
with mock.patch(
"sentry_sdk.integrations.redis.utils._COMMANDS_INCLUDING_SENSITIVE_DATA",
["get"],
):
sentry_init(
integrations=[RedisIntegration()],
traces_sample_rate=1.0,
send_default_pii=True,
)

connection = FakeRedis()

items = capture_items("span")
with sentry_sdk.start_span(name="custom parent"):
connection.get("this is super secret")
sentry_sdk.flush()

assert len(items) == 2
redis_span, parent_span = items[0].payload, items[1].payload

assert parent_span["name"] == "custom parent"
assert redis_span["name"] == "GET [Filtered]"
assert redis_span["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET [Filtered]"
assert redis_span["attributes"]["sentry.op"] == "db.redis"


def test_pii_data_redacted(
sentry_init,
capture_events,
Expand Down Expand Up @@ -205,7 +127,7 @@ def test_pii_data_redacted(
@pytest.mark.parametrize(
"data_collection, expected_description",
[
({"database_query_data": False}, "SET 'somekey1'"),
({"database_query_data": False}, "SET 'somekey1' [Filtered]"),
({"database_query_data": True}, "SET 'somekey1' 'my secret string1'"),
({}, "SET 'somekey1' 'my secret string1'"),
],
Expand Down Expand Up @@ -246,94 +168,11 @@ def test_data_collection_database_query_data(
assert set_span["attributes"]["sentry.op"] == "db.redis"


@pytest.mark.parametrize(
"data_collection, send_default_pii, expected_description",
[
({"database_query_data": False}, True, "SET 'somekey1'"),
(
{"database_query_data": True},
False,
"SET 'somekey1' 'my secret string1'",
),
],
)
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_database_query_data_takes_precedence_over_send_default_pii(
sentry_init,
capture_events,
capture_items,
data_collection,
send_default_pii,
expected_description,
):
sentry_init(
integrations=[RedisIntegration()],
traces_sample_rate=1.0,
send_default_pii=send_default_pii,
data_collection=data_collection,
)

connection = FakeRedis()

items = capture_items("span")

with sentry_sdk.start_span(name="custom parent"):
connection.set("somekey1", "my secret string1")

sentry_sdk.flush()

assert len(items) == 2
set_span, parent = [item.payload for item in items]

assert parent["name"] == "custom parent"
assert set_span["name"] == expected_description
assert set_span["attributes"][SPANDATA.DB_QUERY_TEXT] == expected_description
assert set_span["attributes"]["sentry.op"] == "db.redis"


def test_pii_data_sent(sentry_init, capture_items):
sentry_init(
integrations=[RedisIntegration()],
traces_sample_rate=1.0,
send_default_pii=True,
)

connection = FakeRedis()

items = capture_items("span")

with sentry_sdk.start_span(name="custom parent"):
connection.set("somekey1", "my secret string1")
connection.set("somekey2", "my secret string2")
connection.get("somekey2")
connection.delete("somekey1", "somekey2")

sentry_sdk.flush()

assert len(items) == 5
set1, set2, get, delete, parent = [item.payload for item in items]

assert parent["name"] == "custom parent"
assert set1["name"] == "SET 'somekey1' 'my secret string1'"
assert (
set1["attributes"][SPANDATA.DB_QUERY_TEXT]
== "SET 'somekey1' 'my secret string1'"
)
assert set1["attributes"]["sentry.op"] == "db.redis"
assert set2["name"] == "SET 'somekey2' 'my secret string2'"
assert (
set2["attributes"][SPANDATA.DB_QUERY_TEXT]
== "SET 'somekey2' 'my secret string2'"
)
assert get["name"] == "GET 'somekey2'"
assert delete["name"] == "DEL 'somekey1' 'somekey2'"


def test_no_data_truncation_by_default(sentry_init, capture_items):
sentry_init(
integrations=[RedisIntegration()],
traces_sample_rate=1.0,
send_default_pii=True,
data_collection={"database_query_data": True},
)

connection = FakeRedis()
Expand Down Expand Up @@ -366,7 +205,7 @@ def test_no_data_truncation_by_default(sentry_init, capture_items):
def test_breadcrumbs(sentry_init, capture_events):
sentry_init(
integrations=[RedisIntegration()],
send_default_pii=True,
data_collection={"database_query_data": True},
)
events = capture_events()

Expand Down
Loading