diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index a957c67ed8..aba27077f8 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -25,7 +25,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh - The default of `traces_sample_rate` changed to `0`. Meaning: Incoming traces will be continued by default. For example, if your frontend sends a `sentry-trace/baggage` headers pair, your SDK will create Spans and send them to Sentry. (The default used to be `None` meaning by default no Spans where created, no matter what headers the frontend sent to your project.) See also: https://docs.sentry.io/platforms/python/configuration/options/#traces_sample_rate - `sentry_sdk.start_span` now only takes keyword arguments. - `sentry_sdk.start_transaction`/`sentry_sdk.start_span` no longer takes the following arguments: `span`, `parent_sampled`, `trace_id`, `span_id` or `parent_span_id`. -- `sentry_sdk.continue_trace` no longer returns a `Transaction` and is now a context manager. +- `sentry_sdk.continue_trace` no longer returns a `Transaction` and is now a context manager. - Use it to continue an upstream trace with the `sentry-trace` and `baggage` headers. @@ -65,6 +65,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh - Redis: In Redis pipeline spans there is no `span["data"]["redis.commands"]` that contains a dict `{"count": 3, "first_ten": ["cmd1", "cmd2", ...]}` but instead `span["data"]["redis.commands.count"]` (containing `3`) and `span["data"]["redis.commands.first_ten"]` (containing `["cmd1", "cmd2", ...]`). - clickhouse-driver: The query is now available under the `db.query.text` span attribute (only if `send_default_pii` is `True`). - Logging: By default, the SDK won't capture Sentry issues anymore when calling `logging.error()`, `logging.critical()` or `logging.exception()`. If you want to preserve the old behavior use `sentry_sdk.init(integrations=[LoggingIntegration(event_level="ERROR")])`. +- Logging: Logger `extra` is now added to events in `event["contexts"]["logging"]` instead of `event["extra"]`. - The integration-specific content of the `sampling_context` argument of `traces_sampler` and `profiles_sampler` now looks different. - The Celery integration doesn't add the `celery_job` dictionary anymore. Instead, the individual keys are now available as: diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index 5d03be1139..5c8c4a1575 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -279,7 +279,8 @@ def _emit(self, record: LogRecord) -> None: "params": params, } - event["extra"] = self._extra_from_record(record) + event.setdefault("contexts", {}) + event["contexts"]["logging"] = self._extra_from_record(record) sentry_sdk.capture_event(event, hint=hint) diff --git a/tests/integrations/logging/test_logging.py b/tests/integrations/logging/test_logging.py index 67ea96cd28..d586eb4120 100644 --- a/tests/integrations/logging/test_logging.py +++ b/tests/integrations/logging/test_logging.py @@ -92,7 +92,7 @@ def test_logging_extra_data(sentry_init, capture_events): (event,) = events assert event["level"] == "fatal" - assert event["extra"] == {"bar": 69} + assert event["contexts"]["logging"] == {"bar": 69} assert any( crumb["message"] == "bread" and crumb["data"] == {"foo": 42} for crumb in event["breadcrumbs"]["values"] @@ -110,7 +110,7 @@ def test_logging_extra_data_integer_keys(sentry_init, capture_events): (event,) = events - assert event["extra"] == {"1": 1} + assert event["contexts"]["logging"] == {"1": 1} @pytest.mark.parametrize( diff --git a/tests/test_scrubber.py b/tests/test_scrubber.py index cc99411778..e1da23bb28 100644 --- a/tests/test_scrubber.py +++ b/tests/test_scrubber.py @@ -1,7 +1,7 @@ import sys import logging -from sentry_sdk import capture_exception, capture_event, start_span +from sentry_sdk import capture_exception, capture_event, start_span, set_extra from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.utils import event_from_exception from sentry_sdk.scrubber import EventScrubber @@ -119,38 +119,24 @@ def test_stack_var_scrubbing(sentry_init, capture_events): } -def test_breadcrumb_extra_scrubbing(sentry_init, capture_events): +def test_extra_scrubbing(sentry_init, capture_events): sentry_init( max_breadcrumbs=2, integrations=[LoggingIntegration(event_level="ERROR")], ) events = capture_events() - logger.info("breadcrumb 1", extra=dict(foo=1, password="secret")) - logger.info("breadcrumb 2", extra=dict(bar=2, auth="secret")) - logger.info("breadcrumb 3", extra=dict(foobar=3, password="secret")) - logger.critical("whoops", extra=dict(bar=69, auth="secret")) + + set_extra("bar", 69) + set_extra("auth", "secret") + try: + 1 / 0 + except ZeroDivisionError as e: + capture_exception(e) (event,) = events assert event["extra"]["bar"] == 69 assert event["extra"]["auth"] == "[Filtered]" - assert event["breadcrumbs"]["values"][0]["data"] == { - "bar": 2, - "auth": "[Filtered]", - } - assert event["breadcrumbs"]["values"][1]["data"] == { - "foobar": 3, - "password": "[Filtered]", - } - - assert event["_meta"]["extra"]["auth"] == {"": {"rem": [["!config", "s"]]}} - assert event["_meta"]["breadcrumbs"] == { - "": {"len": 3}, - "values": { - "0": {"data": {"auth": {"": {"rem": [["!config", "s"]]}}}}, - "1": {"data": {"password": {"": {"rem": [["!config", "s"]]}}}}, - }, - } def test_span_data_scrubbing(sentry_init, capture_events):