Skip to content

Commit 1e69dab

Browse files
authored
feat(logging): Do not capture errors from LoggingIntegration to Sentry by default (#4300)
Fixes #4187
1 parent a610066 commit 1e69dab

File tree

7 files changed

+93
-30
lines changed

7 files changed

+93
-30
lines changed

MIGRATION_GUIDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
2626
- `sentry_sdk.init` now returns `None` instead of a context manager.
2727
- The `sampling_context` argument of `traces_sampler` and `profiles_sampler` now additionally contains all span attributes known at span start.
2828
- We updated how we handle `ExceptionGroup`s. You will now get more data if ExceptionGroups are appearing in chained exceptions. It could happen that after updating the SDK the grouping of issues change because of this. So eventually you will see the same exception in two Sentry issues (one from before the update, one from after the update)
29+
- The integration for Python `logging` module does not send Sentry issues by default 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")])`.
2930
- The integration-specific content of the `sampling_context` argument of `traces_sampler` and `profiles_sampler` now looks different.
3031
- The Celery integration doesn't add the `celery_job` dictionary anymore. Instead, the individual keys are now available as:
3132

sentry_sdk/integrations/logging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from typing import Optional
2424

2525
DEFAULT_LEVEL = logging.INFO
26-
DEFAULT_EVENT_LEVEL = logging.ERROR
26+
DEFAULT_EVENT_LEVEL = None # None means no events are captured
2727
LOGGING_TO_EVENT_LEVEL = {
2828
logging.NOTSET: "notset",
2929
logging.DEBUG: "debug",

tests/integrations/flask/test_flask.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ def index():
285285
try:
286286
raise ValueError("stuff")
287287
except Exception:
288-
logging.exception("stuff happened")
288+
sentry_sdk.capture_exception()
289289
1 / 0
290290

291291
envelopes = capture_envelopes()
@@ -875,7 +875,12 @@ def index():
875875

876876

877877
def test_request_not_modified_by_reference(sentry_init, capture_events, app):
878-
sentry_init(integrations=[flask_sentry.FlaskIntegration()])
878+
sentry_init(
879+
integrations=[
880+
flask_sentry.FlaskIntegration(),
881+
LoggingIntegration(event_level="ERROR"),
882+
]
883+
)
879884

880885
@app.route("/", methods=["POST"])
881886
def index():

tests/integrations/logging/test_logging.py

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,71 @@ def reset_level():
1515
logger.setLevel(logging.DEBUG)
1616

1717

18-
@pytest.mark.parametrize("logger", [logger, other_logger])
19-
def test_logging_works_with_many_loggers(sentry_init, capture_events, logger):
20-
sentry_init(integrations=[LoggingIntegration(event_level="ERROR")])
18+
@pytest.mark.parametrize("integrations", [None, [], [LoggingIntegration()]])
19+
@pytest.mark.parametrize(
20+
"kwargs", [{"exc_info": None}, {}, {"exc_info": 0}, {"exc_info": False}]
21+
)
22+
def test_logging_defaults(integrations, sentry_init, capture_events, kwargs):
23+
sentry_init(integrations=integrations)
2124
events = capture_events()
2225

2326
logger.info("bread")
24-
logger.critical("LOL")
25-
(event,) = events
26-
assert event["level"] == "fatal"
27-
assert not event["logentry"]["params"]
28-
assert event["logentry"]["message"] == "LOL"
29-
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])
27+
logger.error("error")
28+
logger.critical("LOL", **kwargs)
29+
30+
assert len(events) == 0
3031

3132

32-
@pytest.mark.parametrize("integrations", [None, [], [LoggingIntegration()]])
3333
@pytest.mark.parametrize(
3434
"kwargs", [{"exc_info": None}, {}, {"exc_info": 0}, {"exc_info": False}]
3535
)
36-
def test_logging_defaults(integrations, sentry_init, capture_events, kwargs):
37-
sentry_init(integrations=integrations)
36+
def test_logging_basic(sentry_init, capture_events, kwargs):
37+
sentry_init(integrations=[LoggingIntegration(event_level=logging.ERROR)])
3838
events = capture_events()
3939

4040
logger.info("bread")
41+
logger.error("error")
4142
logger.critical("LOL", **kwargs)
42-
(event,) = events
43+
(error_event, critical_event) = events
4344

44-
assert event["level"] == "fatal"
45-
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])
45+
assert error_event["level"] == "error"
46+
assert any(
47+
crumb["message"] == "bread" for crumb in error_event["breadcrumbs"]["values"]
48+
)
4649
assert not any(
47-
crumb["message"] == "LOL" for crumb in event["breadcrumbs"]["values"]
50+
crumb["message"] == "LOL" for crumb in error_event["breadcrumbs"]["values"]
4851
)
49-
assert "threads" not in event
52+
assert "threads" not in error_event
53+
54+
assert critical_event["level"] == "fatal"
55+
assert any(
56+
crumb["message"] == "bread" for crumb in critical_event["breadcrumbs"]["values"]
57+
)
58+
assert not any(
59+
crumb["message"] == "LOL" for crumb in critical_event["breadcrumbs"]["values"]
60+
)
61+
assert "threads" not in critical_event
62+
63+
64+
@pytest.mark.parametrize("logger", [logger, other_logger])
65+
def test_logging_works_with_many_loggers(sentry_init, capture_events, logger):
66+
sentry_init(integrations=[LoggingIntegration(event_level="ERROR")])
67+
events = capture_events()
68+
69+
logger.info("bread")
70+
logger.critical("LOL")
71+
(event,) = events
72+
assert event["level"] == "fatal"
73+
assert not event["logentry"]["params"]
74+
assert event["logentry"]["message"] == "LOL"
75+
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])
5076

5177

5278
def test_logging_extra_data(sentry_init, capture_events):
53-
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
79+
sentry_init(
80+
integrations=[LoggingIntegration(event_level=logging.ERROR)],
81+
default_integrations=False,
82+
)
5483
events = capture_events()
5584

5685
logger.info("bread", extra=dict(foo=42))
@@ -67,7 +96,10 @@ def test_logging_extra_data(sentry_init, capture_events):
6796

6897

6998
def test_logging_extra_data_integer_keys(sentry_init, capture_events):
70-
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
99+
sentry_init(
100+
integrations=[LoggingIntegration(event_level=logging.ERROR)],
101+
default_integrations=False,
102+
)
71103
events = capture_events()
72104

73105
logger.critical("integer in extra keys", extra={1: 1})
@@ -85,7 +117,10 @@ def test_logging_extra_data_integer_keys(sentry_init, capture_events):
85117
),
86118
)
87119
def test_logging_stack_trace(sentry_init, capture_events, enable_stack_trace_kwarg):
88-
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
120+
sentry_init(
121+
integrations=[LoggingIntegration(event_level=logging.ERROR)],
122+
default_integrations=False,
123+
)
89124
events = capture_events()
90125

91126
logger.error("first", **enable_stack_trace_kwarg)
@@ -104,7 +139,10 @@ def test_logging_stack_trace(sentry_init, capture_events, enable_stack_trace_kwa
104139

105140

106141
def test_logging_level(sentry_init, capture_events):
107-
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
142+
sentry_init(
143+
integrations=[LoggingIntegration(event_level=logging.ERROR)],
144+
default_integrations=False,
145+
)
108146
events = capture_events()
109147

110148
logger.setLevel(logging.WARNING)
@@ -158,7 +196,10 @@ def test_custom_log_level_names(sentry_init, capture_events):
158196

159197

160198
def test_logging_filters(sentry_init, capture_events):
161-
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
199+
sentry_init(
200+
integrations=[LoggingIntegration(event_level=logging.ERROR)],
201+
default_integrations=False,
202+
)
162203
events = capture_events()
163204

164205
should_log = False
@@ -210,7 +251,10 @@ def test_logging_captured_warnings(sentry_init, capture_events, recwarn):
210251

211252

212253
def test_ignore_logger(sentry_init, capture_events):
213-
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
254+
sentry_init(
255+
integrations=[LoggingIntegration(event_level=logging.ERROR)],
256+
default_integrations=False,
257+
)
214258
events = capture_events()
215259

216260
ignore_logger("testfoo")
@@ -221,7 +265,10 @@ def test_ignore_logger(sentry_init, capture_events):
221265

222266

223267
def test_ignore_logger_wildcard(sentry_init, capture_events):
224-
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
268+
sentry_init(
269+
integrations=[LoggingIntegration(event_level=logging.ERROR)],
270+
default_integrations=False,
271+
)
225272
events = capture_events()
226273

227274
ignore_logger("testfoo.*")

tests/integrations/starlette/test_starlette.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
from sentry_sdk import capture_message, get_baggage, get_traceparent
1515
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
16+
from sentry_sdk.integrations.logging import LoggingIntegration
1617
from sentry_sdk.integrations.starlette import (
1718
StarletteIntegration,
1819
StarletteRequestExtractor,
@@ -943,7 +944,9 @@ def test_active_thread_id(sentry_init, capture_envelopes, teardown_profiling, en
943944

944945

945946
def test_original_request_not_scrubbed(sentry_init, capture_events):
946-
sentry_init(integrations=[StarletteIntegration()])
947+
sentry_init(
948+
integrations=[StarletteIntegration(), LoggingIntegration(event_level="ERROR")]
949+
)
947950

948951
events = capture_events()
949952

tests/test_logs.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,10 @@ def test_logging_errors(sentry_init, capture_envelopes):
331331
"""
332332
The python logger module should be able to log errors without erroring
333333
"""
334-
sentry_init(_experiments={"enable_logs": True})
334+
sentry_init(
335+
_experiments={"enable_logs": True},
336+
integrations=[LoggingIntegration(event_level="ERROR")],
337+
)
335338
envelopes = capture_envelopes()
336339

337340
python_logger = logging.Logger("test-logger")

tests/test_scrubber.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import logging
33

44
from sentry_sdk import capture_exception, capture_event, start_span
5+
from sentry_sdk.integrations.logging import LoggingIntegration
56
from sentry_sdk.utils import event_from_exception
67
from sentry_sdk.scrubber import EventScrubber
78
from tests.conftest import ApproxDict
@@ -119,7 +120,10 @@ def test_stack_var_scrubbing(sentry_init, capture_events):
119120

120121

121122
def test_breadcrumb_extra_scrubbing(sentry_init, capture_events):
122-
sentry_init(max_breadcrumbs=2)
123+
sentry_init(
124+
max_breadcrumbs=2,
125+
integrations=[LoggingIntegration(event_level="ERROR")],
126+
)
123127
events = capture_events()
124128
logger.info("breadcrumb 1", extra=dict(foo=1, password="secret"))
125129
logger.info("breadcrumb 2", extra=dict(bar=2, auth="secret"))

0 commit comments

Comments
 (0)