8000 feat(logging): Do not capture errors from `LoggingIntegration` to Sentry by default by antonpirker · Pull Request #4300 · getsentry/sentry-python · GitHub
[go: up one dir, main page]

Skip to content

feat(logging): Do not capture errors from LoggingIntegration to Sentry by default #4300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
1 change: 1 addition & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
- `sentry_sdk.init` now returns `None` instead of a context manager.
- The `sampling_context` argument of `traces_sampler` and `profiles_sampler` now additionally contains all span attributes known at span start.
- 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)
- 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")])`.
- 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:

Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/integrations/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from typing import Optional

DEFAULT_LEVEL = logging.INFO
DEFAULT_EVENT_LEVEL = logging.ERROR
DEFAULT_EVENT_LEVEL = None # None means no events are captured
LOGGING_TO_EVENT_LEVEL = {
logging.NOTSET: "notset",
logging.DEBUG: "debug",
Expand Down
9 changes: 7 additions & 2 deletions tests/integrations/flask/test_flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def index():
try:
raise ValueError("stuff")
except Exception:
logging.exception("stuff happened")
sentry_sdk.capture_exception()
1 / 0

envelopes = capture_envelopes()
Expand Down Expand Up @@ -875,7 +875,12 @@ def index():


def test_request_not_modified_by_reference(sentry_init, capture_events, app):
sentry_init(integrations=[flask_sentry.FlaskIntegration()])
sentry_init(
integrations=[
flask_sentry.FlaskIntegration(),
LoggingIntegration(event_level="ERROR"),
]
)

@app.route("/", methods=["POST"])
def index():
Expand Down
95 changes: 71 additions & 24 deletions tests/integrations/logging/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,71 @@ def reset_level():
logger.setLevel(logging.DEBUG)


@pytest.mark.parametrize("logger", [logger, other_logger])
def test_logging_works_with_many_loggers(sentry_init, capture_events, logger):
sentry_init(integrations=[LoggingIntegration(event_level="ERROR")])
@pytest.mark.parametrize("integrations", [None, [], [LoggingIntegration()]])
@pytest.mark.parametrize(
"kwargs", [{"exc_info": None}, {}, {"exc_info": 0}, {"exc_info": False}]
)
def test 10000 _logging_defaults(integrations, sentry_init, capture_events, kwargs):
sentry_init(integrations=integrations)
events = capture_events()

logger.info("bread")
logger.critical("LOL")
(event,) = events
assert event["level"] == "fatal"
assert not event["logentry"]["params"]
assert event["logentry"]["message"] == "LOL"
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])
logger.error("error")
logger.critical("LOL", **kwargs)

assert len(events) == 0


@pytest.mark.parametrize("integrations", [None, [], [LoggingIntegration()]])
@pytest.mark.parametrize(
"kwargs", [{"exc_info": None}, {}, {"exc_info": 0}, {"exc_info": False}]
)
def test_logging_defaults(integrations, sentry_init, capture_events, kwargs):
sentry_init(integrations=integrations)
def test_logging_basic(sentry_init, capture_events, kwargs):
sentry_init(integrations=[LoggingIntegration(event_level=logging.ERROR)])
events = capture_events()

logger.info("bread")
logger.error("error")
logger.critical("LOL", **kwargs)
(event,) = events
(error_event, critical_event) = events

assert event["level"] == "fatal"
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])
assert error_event["level"] == "error"
assert any(
crumb["message"] == "bread" for crumb in error_event["breadcrumbs"]["values"]
)
assert not any(
crumb["message"] == "LOL" for crumb in event["breadcrumbs"]["values"]
crumb["message"] == "LOL" for crumb in error_event["breadcrumbs"]["values"]
)
assert "threads" not in event
assert "threads" not in error_event

assert critical_event["level"] == "fatal"
assert any(
crumb["message"] == "bread" for crumb in critical_event["breadcrumbs"]["values"]
)
assert not any(
crumb["message"] == "LOL" for crumb in critical_event["breadcrumbs"]["values"]
)
assert "threads" not in critical_event


@pytest.mark.parametrize("logger", [logger, other_logger])
def test_logging_works_with_many_loggers(sentry_init, capture_events, logger):
sentry_init(integrations=[LoggingIntegration(event_level="ERROR")])
events = capture_events()

logger.info("bread")
logger.critical("LOL")
(event,) = events
assert event["level"] == "fatal"
assert not event["logentry"]["params"]
assert event["logentry"]["message"] == "LOL"
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])


def test_logging_extra_data(sentry_init, capture_events):
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
sentry_init(
integrations=[LoggingIntegration(event_level=logging.ERROR)],
default_integrations=False,
)
events = capture_events()

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


def test_logging_extra_data_integer_keys(sentry_init, capture_events):
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
sentry_init(
integrations=[LoggingIntegration(event_level=logging.ERROR)],
default_integrations=False,
)
events = capture_events()

logger.critical("integer in extra keys", extra={1: 1})
Expand All @@ -85,7 +117,10 @@ def test_logging_extra_data_integer_keys(sentry_init, capture_events):
),
)
def test_logging_stack_trace(sentry_init, capture_events, enable_stack_trace_kwarg):
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
sentry_init(
integrations=[LoggingIntegration(event_level=logging.ERROR)],
default_integrations=False,
)
events = capture_events()

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


def test_logging_level(sentry_init, capture_events):
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
sentry_init(
integrations=[LoggingIntegration(event_level=logging.ERROR)],
default_integrations=False,
)
events = capture_events()

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


def test_logging_filters(sentry_init, capture_events):
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
sentry_init(
integrations=[LoggingIntegration(event_level=logging.ERROR)],
default_integrations=False,
)
events = capture_events()

should_log = False
Expand Down Expand Up @@ -210,7 +251,10 @@ def test_logging_captured_warnings(sentry_init, capture_events, recwarn):


def test_ignore_logger(sentry_init, capture_events):
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
sentry_init(
integrations=[LoggingIntegration(event_level=logging.ERROR)],
default_integrations=False,
)
events = capture_events()

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


def test_ignore_logger_wildcard(sentry_init, capture_events):
sentry_init(integrations=[LoggingIntegration()], default_integrations=False)
sentry_init(
integrations=[LoggingIntegration(event_level=logging.ERROR)],
default_integrations=False,
)
events = capture_events()

ignore_logger("testfoo.*")
Expand Down
5 changes: 4 additions & 1 deletion tests/integrations/starlette/test_starlette.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from sentry_sdk import capture_message, get_baggage, get_traceparent
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
from sentry_sdk.integrations.logging import LoggingIntegration
from sentry_sdk.integrations.starlette import (
StarletteIntegration,
StarletteRequestExtractor,
Expand Down Expand Up @@ -943,7 +944,9 @@ def test_active_thread_id(sentry_init, capture_envelopes, teardown_profiling, en


def test_original_request_not_scrubbed(sentry_init, capture_events):
sentry_init(integrations=[StarletteIntegration()])
sentry_init(
integrations=[Starlet F438 teIntegration(), LoggingIntegration(event_level="ERROR")]
)

events = capture_events()

Expand Down
5 changes: 4 additions & 1 deletion tests/test_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,10 @@ def test_logging_errors(sentry_init, capture_envelopes):
"""
The python logger module should be able to log errors without erroring
"""
sentry_init(_experiments={"enable_logs": True})
sentry_init(
_experiments={"enable_logs": True},
integrations=[LoggingIntegration(event_level="ERROR")],
)
envelopes = capture_envelopes()

python_logger = logging.Logger("test-logger")
Expand Down
6 changes: 5 additions & 1 deletion tests/test_scrubber.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging

from sentry_sdk import capture_exception, capture_event, start_span
from sentry_sdk.integrations.logging import LoggingIntegration
from sentry_sdk.utils import event_from_exception
from sentry_sdk.scrubber import EventScrubber
from tests.conftest import ApproxDict
Expand Down Expand Up @@ -119,7 +120,10 @@ def test_stack_var_scrubbing(sentry_init, capture_events):


def test_breadcrumb_extra_scrubbing(sentry_init, capture_events):
sentry_init(max_breadcrumbs=2)
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"))
Expand Down
Loading
0