From aa69727aa971ad64e91c671411516e9b745d6144 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 12 Aug 2026 15:22:59 +0200 Subject: [PATCH 1/4] chore: Drop enable_logs, enable_metrics options in new major --- MIGRATION_GUIDE.md | 1 + sentry_sdk/client.py | 12 ------------ sentry_sdk/consts.py | 8 -------- tests/test_logs.py | 17 ----------------- tests/test_metrics.py | 15 --------------- 5 files changed, 1 insertion(+), 52 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index b6a0511709..d737138b05 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -45,6 +45,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh - Removed the RedisIntegration `max_data_size` option. - Removed the possibility to supply a specific client to the LaunchDarklyIntegration. - The `enable_tracing` option was removed. Use `traces_sample_rate=1.0` instead. +- The `enable_logs` option was removed. Using Sentry's logging API now works without requiring setting `enable_logs=True`. Automatic capture of logs emitted by the `logging` standard library module or Loguru can be turned on by providing the `capture_sentry_logs=True` option to either `LoggingIntegration` or `LoguruIntegration`. - The deprecated `@ai_track` decorator was removed. - The deprecated `push_scope` and `configure_scope` APIs have been removed. Use `with new_scope():` to push a new scope and `scope = get_current_scope()` to retrieve the current scope instead. - Transaction profiling and related code was removed. diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index bc2b7519f6..ec29ee895b 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -628,23 +628,11 @@ def _record_lost_event( self.session_flusher = SessionFlusher(capture_func=_capture_envelope) - if self.options.get("enable_logs", False) or self.options[ - "_experiments" - ].get("enable_logs", False): - logger.warning( - "The enable_logs option has no effect and will be removed in the next major." - ) - self.log_batcher = LogBatcher( capture_func=_capture_envelope, record_lost_func=_record_lost_event, ) - if self.options.get("enable_metrics", True) is False: - logger.warning( - "The enable_metrics option has no effect and will be removed in the next major." - ) - self.metrics_batcher = MetricsBatcher( capture_func=_capture_envelope, record_lost_func=_record_lost_event, diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 6bae4991b0..ab679529d5 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -74,9 +74,7 @@ class CompressionAlgo(Enum): "transport_num_pools": Optional[int], "transport_http2": Optional[bool], "transport_async": Optional[bool], - "enable_logs": Optional[bool], "before_send_log": Optional[Callable[[Log, Hint], Optional[Log]]], - "enable_metrics": Optional[bool], "before_send_metric": Optional[Callable[[Metric, Hint], Optional[Metric]]], "trace_lifecycle": Optional[Literal["static", "stream"]], "ignore_spans": Optional[IgnoreSpansConfig], @@ -1344,10 +1342,8 @@ def __init__( custom_repr: "Optional[Callable[..., Optional[str]]]" = None, add_full_stack: bool = DEFAULT_ADD_FULL_STACK, max_stack_frames: "Optional[int]" = DEFAULT_MAX_STACK_FRAMES, - enable_logs: bool = False, before_send_log: "Optional[Callable[[Log, Hint], Optional[Log]]]" = None, trace_ignore_status_codes: "AbstractSet[int]" = frozenset(), - enable_metrics: bool = True, before_send_metric: "Optional[Callable[[Metric, Hint], Optional[Metric]]]" = None, before_send_span: "Optional[Callable[[SpanJSON, Hint], Optional[SpanJSON]]]" = None, org_id: "Optional[str]" = None, @@ -1723,10 +1719,6 @@ def __init__( :param spotlight: - - :param enable_logs: Set `enable_logs` to True to enable the SDK to emit - Sentry logs. Defaults to False. - :param before_send_log: An optional function to modify or filter out logs before they're sent to Sentry. Any modifications to the log in this function will be retained. If the function returns None, the log will diff --git a/tests/test_logs.py b/tests/test_logs.py index 6a1714b338..e0c896f4b1 100644 --- a/tests/test_logs.py +++ b/tests/test_logs.py @@ -28,23 +28,6 @@ def test_logs_enabled_by_default(sentry_init, capture_envelopes): assert envelopes -def test_enable_logs_noop(sentry_init, capture_envelopes): - sentry_init(enable_logs=False) - - envelopes = capture_envelopes() - - sentry_sdk.logger.trace("This is a 'trace' log.") - sentry_sdk.logger.debug("This is a 'debug' log...") - sentry_sdk.logger.info("This is a 'info' log...") - sentry_sdk.logger.warning("This is a 'warning' log...") - sentry_sdk.logger.error("This is a 'error' log...") - sentry_sdk.logger.fatal("This is a 'fatal' log...") - - sentry_sdk.flush() - - assert envelopes - - def test_logs_basics(sentry_init, capture_items): sentry_init() items = capture_items("log") diff --git a/tests/test_metrics.py b/tests/test_metrics.py index e07e507ba7..7596176b8a 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -9,21 +9,6 @@ from sentry_sdk.consts import SPANDATA, VERSION -def test_metrics_enable_metrics_noop(sentry_init, capture_envelopes): - # The enable_metrics option has no effect anymore. - sentry_init(enable_metrics=False) - - envelopes = capture_envelopes() - - sentry_sdk.metrics.count("test.counter", 1) - sentry_sdk.metrics.gauge("test.gauge", 42) - sentry_sdk.metrics.distribution("test.distribution", 200) - - sentry_sdk.flush() - - assert envelopes - - def test_metrics_basics(sentry_init, capture_items): sentry_init() items = capture_items("trace_metric") From 2ec82a1e88cd4602bcfb084fee7f742d3ec4bc52 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 12 Aug 2026 15:28:27 +0200 Subject: [PATCH 2/4] . --- MIGRATION_GUIDE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index d737138b05..a2f52b9da0 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -46,6 +46,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh - Removed the possibility to supply a specific client to the LaunchDarklyIntegration. - The `enable_tracing` option was removed. Use `traces_sample_rate=1.0` instead. - The `enable_logs` option was removed. Using Sentry's logging API now works without requiring setting `enable_logs=True`. Automatic capture of logs emitted by the `logging` standard library module or Loguru can be turned on by providing the `capture_sentry_logs=True` option to either `LoggingIntegration` or `LoguruIntegration`. +- The `enable_metrics` option was removed. - The deprecated `@ai_track` decorator was removed. - The deprecated `push_scope` and `configure_scope` APIs have been removed. Use `with new_scope():` to push a new scope and `scope = get_current_scope()` to retrieve the current scope instead. - Transaction profiling and related code was removed. From 6271fb4abfd7232e9728e58220dc99bddd016a5c Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 12 Aug 2026 15:29:13 +0200 Subject: [PATCH 3/4] example --- MIGRATION_GUIDE.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index a2f52b9da0..5899af00d9 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -45,7 +45,21 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh - Removed the RedisIntegration `max_data_size` option. - Removed the possibility to supply a specific client to the LaunchDarklyIntegration. - The `enable_tracing` option was removed. Use `traces_sample_rate=1.0` instead. -- The `enable_logs` option was removed. Using Sentry's logging API now works without requiring setting `enable_logs=True`. Automatic capture of logs emitted by the `logging` standard library module or Loguru can be turned on by providing the `capture_sentry_logs=True` option to either `LoggingIntegration` or `LoguruIntegration`. +- The `enable_logs` option was removed. Using Sentry's logging API now works without requiring setting `enable_logs=True`. Automatic capture of logs emitted by the `logging` standard library module or Loguru can be turned on by providing the `capture_sentry_logs=True` option to either `LoggingIntegration` or `LoguruIntegration`: + + ```python + import sentry_sdk + from sentry_sdk.integrations.logging import LoggingIntegration + from sentry_sdk.integrations.loguru import LoguruIntegration + + sentry_sdk.init( + integrations=[ + LoggingIntegration(capture_sentry_logs=True), + LoguruIntegration(capture_sentry_logs=True), + ] + ) + ``` + - The `enable_metrics` option was removed. - The deprecated `@ai_track` decorator was removed. - The deprecated `push_scope` and `configure_scope` APIs have been removed. Use `with new_scope():` to push a new scope and `scope = get_current_scope()` to retrieve the current scope instead. From 56252a0f9eac5cf3814403c3a753eec2834c2d8f Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Tue, 25 Aug 2026 13:48:59 +0200 Subject: [PATCH 4/4] adapt to current behavior --- sentry_sdk/integrations/logging.py | 16 +------- sentry_sdk/integrations/loguru.py | 13 +----- tests/integrations/logging/test_logging.py | 36 ---------------- tests/integrations/loguru/test_loguru.py | 48 ---------------------- 4 files changed, 2 insertions(+), 111 deletions(-) diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index a677d0c507..e5580441e4 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -403,21 +403,7 @@ def emit(self, record: "LogRecord") -> "Any": if not client.is_active(): return - # TODO: remove this compat hack in the next major. Capture should - # only depend on capture_sentry_logs being True. - compat_logs_enabled = client.options.get( - "enable_logs", False - ) or client.options["_experiments"].get("enable_logs", False) - should_capture_logs = False - if LoggingIntegration.capture_sentry_logs is True: - should_capture_logs = True - elif ( - LoggingIntegration.capture_sentry_logs is _SENTINEL - and compat_logs_enabled - ): - should_capture_logs = True - - if not should_capture_logs: + if LoggingIntegration.capture_sentry_logs is not True: return self._capture_log_from_record(client, record) diff --git a/sentry_sdk/integrations/loguru.py b/sentry_sdk/integrations/loguru.py index d52493973e..e6707fd429 100644 --- a/sentry_sdk/integrations/loguru.py +++ b/sentry_sdk/integrations/loguru.py @@ -158,18 +158,7 @@ def loguru_sentry_logs_handler(message: "Message") -> None: if not client.is_active(): return - # TODO: remove this compat hack in the next major. Capture should - # only depend on capture_sentry_logs being True. - compat_logs_enabled = client.options.get("enable_logs", False) or client.options[ - "_experiments" - ].get("enable_logs", False) - should_capture_logs = False - if LoguruIntegration.capture_sentry_logs is True: - should_capture_logs = True - elif LoguruIntegration.capture_sentry_logs is _SENTINEL and compat_logs_enabled: - should_capture_logs = True - - if not should_capture_logs: + if LoguruIntegration.capture_sentry_logs is not True: return record = message.record diff --git a/tests/integrations/logging/test_logging.py b/tests/integrations/logging/test_logging.py index b9e85a8482..01fd3c282f 100644 --- a/tests/integrations/logging/test_logging.py +++ b/tests/integrations/logging/test_logging.py @@ -262,42 +262,6 @@ def test_sentry_logs_collection_opt_in(sentry_init, capture_items, request): assert log["attributes"]["sentry.severity_text"] == "warn" -def test_sentry_logs_collection_opt_in_compat(sentry_init, capture_items, request): - """Automatic logs capture by Sentry logs needs explicit opt-in via enable_logs.""" - # This should be removed in the next major. - sentry_init(enable_logs=True) - items = capture_items("log") - - python_logger = logging.Logger("test-logger") - python_logger.warning("this is %s a template %s", "1", "2") - - get_client().flush() - - assert len(items) == 1 - - log = items[0].payload - assert log["attributes"]["sentry.message.template"] == "this is %s a template %s" - assert log["attributes"]["sentry.severity_number"] == 13 - assert log["attributes"]["sentry.severity_text"] == "warn" - - -def test_sentry_logs_collection_opt_in_compat_does_not_override_explicit_opt_out( - sentry_init, capture_items, request -): - # This should be removed in the next major. - sentry_init( - enable_logs=True, integrations=[LoggingIntegration(capture_sentry_logs=False)] - ) - items = capture_items("log") - - python_logger = logging.Logger("test-logger") - python_logger.warning("this is %s a template %s", "1", "2") - - get_client().flush() - - assert len(items) == 0 - - def test_ignore_logger(sentry_init, capture_events, request): sentry_init(integrations=[LoggingIntegration()], default_integrations=False) events = capture_events() diff --git a/tests/integrations/loguru/test_loguru.py b/tests/integrations/loguru/test_loguru.py index 2db777d3c3..e82f845c2c 100644 --- a/tests/integrations/loguru/test_loguru.py +++ b/tests/integrations/loguru/test_loguru.py @@ -256,54 +256,6 @@ def test_disable_sentry_logs_by_default( assert len(logs) == 0 -def test_enable_sentry_logs_if_enable_logs_is_true( - sentry_init, capture_items, uninstall_integration, request -): - # This should be removed in the next major. - uninstall_integration("loguru") - request.addfinalizer(logger.remove) - - sentry_init(enable_logs=True) - items = capture_items("log") - - logger.trace("this is a log") - logger.debug("this is a log") - logger.info("this is a log") - logger.success("this is a log") - logger.warning("this is a log") - logger.error("this is a log") - logger.critical("this is a log") - - sentry_sdk.get_client().flush() - logs = [item.payload for item in items] - assert len(logs) == 5 - - -def test_disable_sentry_logs_if_enable_logs_is_true_but_integration_option_is_false( - sentry_init, capture_items, uninstall_integration, request -): - # This should be removed in the next major. - uninstall_integration("loguru") - request.addfinalizer(logger.remove) - - sentry_init( - enable_logs=True, integrations=[LoguruIntegration(capture_sentry_logs=False)] - ) - items = capture_items("log") - - logger.trace("this is a log") - logger.debug("this is a log") - logger.info("this is a log") - logger.success("this is a log") - logger.warning("this is a log") - logger.error("this is a log") - logger.critical("this is a log") - - sentry_sdk.get_client().flush() - logs = [item.payload for item in items] - assert not logs - - def test_disable_sentry_logs_explicitly( sentry_init, capture_items, uninstall_integration, request ):