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
15 changes: 11 additions & 4 deletions lite_bootstrap/instruments/sentry_instrument.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import dataclasses
import inspect
import logging
import typing

Expand All @@ -17,6 +18,12 @@
import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration

# sentry-sdk 2.25 added the parameter along with Sentry Logs; the declared floor is 2.1,
# where passing it raises TypeError and there is no logs handler to disable anyway.
SENTRY_LOGS_LEVEL_SUPPORTED: typing.Final = (
"sentry_logs_level" in inspect.signature(LoggingIntegration.__init__).parameters
)


# Back-compat alias: this vocabulary moved to logging_factory and was renamed
# STRUCTLOG_META_KEYS. Preserved here for external importers of the old name.
Expand Down Expand Up @@ -110,10 +117,10 @@ def _build_integrations(self) -> list["Integration"]:
if not config.sentry_default_integrations:
self._warn_breadcrumb_level_ignored("sentry_default_integrations is False")
return config.sentry_integrations
return [
*config.sentry_integrations,
LoggingIntegration(level=config.sentry_logging_breadcrumb_level, sentry_logs_level=None),
]
logging_integration_kwargs: dict[str, typing.Any] = {"level": config.sentry_logging_breadcrumb_level}
if SENTRY_LOGS_LEVEL_SUPPORTED:
logging_integration_kwargs["sentry_logs_level"] = None
return [*config.sentry_integrations, LoggingIntegration(**logging_integration_kwargs)]

def bootstrap(self) -> None:
config = self.bootstrap_config
Expand Down
18 changes: 18 additions & 0 deletions tests/instruments/test_sentry_instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import structlog
from sentry_sdk.integrations.logging import LoggingIntegration

from lite_bootstrap.instruments import sentry_instrument
from lite_bootstrap.instruments.logging_instrument import LoggingConfig, LoggingInstrument
from tests.conftest import LoggingMock, SentryTestTransport

Expand Down Expand Up @@ -273,3 +274,20 @@ def test_sentry_does_not_warn_when_the_breadcrumb_level_is_left_at_its_default(
assert [one for one in recwarn if "sentry_logging_breadcrumb_level" in str(one.message)] == []
finally:
instrument.teardown()


@pytest.mark.parametrize("supported", [True, False], ids=["sdk_has_it", "sdk_lacks_it"])
def test_sentry_passes_sentry_logs_level_only_when_the_sdk_accepts_it(
minimal_sentry_config: SentryConfig, monkeypatch: pytest.MonkeyPatch, supported: bool
) -> None:
"""INVARIANT: `sentry_logs_level` reaches only the sentry-sdk versions that accept it.

It arrived in sentry-sdk 2.25 while the declared floor is 2.1, where passing it raises
`TypeError: LoggingIntegration.__init__() got an unexpected keyword argument` at bootstrap.
Below 2.25 there is no Sentry Logs feature, so there is no handler to disable either.
"""
monkeypatch.setattr(sentry_instrument, "SENTRY_LOGS_LEVEL_SUPPORTED", supported)
integrations = SentryInstrument(bootstrap_config=minimal_sentry_config)._build_integrations() # noqa: SLF001

logging_integration = next(one for one in integrations if isinstance(one, LoggingIntegration))
assert (logging_integration._sentry_logs_handler is None) is supported # noqa: SLF001
Loading