Skip to content

Commit 3425d4c

Browse files
authored
Add enable_logs, before_send_log as top-level options (#4644)
Promote `enable_logs` and `before_send_log` to regular (non-experimental) SDK options. Keep supporting the experimental versions too, for backwards compat. Closes #4641
1 parent c1861a3 commit 3425d4c

File tree

8 files changed

+122
-41
lines changed

8 files changed

+122
-41
lines changed

sentry_sdk/client.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
handle_in_app,
2424
is_gevent,
2525
logger,
26+
get_before_send_log,
27+
has_logs_enabled,
2628
)
2729
from sentry_sdk.serializer import serialize
2830
from sentry_sdk.tracing import trace
@@ -382,7 +384,8 @@ def _capture_envelope(envelope):
382384
)
383385

384386
self.log_batcher = None
385-
if experiments.get("enable_logs", False):
387+
388+
if has_logs_enabled(self.options):
386389
from sentry_sdk._log_batcher import LogBatcher
387390

388391
self.log_batcher = LogBatcher(capture_func=_capture_envelope)
@@ -898,9 +901,8 @@ def capture_event(
898901
return return_value
899902

900903
def _capture_experimental_log(self, log):
901-
# type: (Log) -> None
902-
logs_enabled = self.options["_experiments"].get("enable_logs", False)
903-
if not logs_enabled:
904+
# type: (Optional[Log]) -> None
905+
if not has_logs_enabled(self.options) or log is None:
904906
return
905907

906908
current_scope = sentry_sdk.get_current_scope()
@@ -955,9 +957,10 @@ def _capture_experimental_log(self, log):
955957
f'[Sentry Logs] [{log.get("severity_text")}] {log.get("body")}'
956958
)
957959

958-
before_send_log = self.options["_experiments"].get("before_send_log")
960+
before_send_log = get_before_send_log(self.options)
959961
if before_send_log is not None:
960962
log = before_send_log(log, {})
963+
961964
if log is None:
962965
return
963966

sentry_sdk/consts.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,8 @@ def __init__(
798798
custom_repr=None, # type: Optional[Callable[..., Optional[str]]]
799799
add_full_stack=DEFAULT_ADD_FULL_STACK, # type: bool
800800
max_stack_frames=DEFAULT_MAX_STACK_FRAMES, # type: Optional[int]
801+
enable_logs=False, # type: bool
802+
before_send_log=None, # type: Optional[Callable[[Log, Hint], Optional[Log]]]
801803
):
802804
# type: (...) -> None
803805
"""Initialize the Sentry SDK with the given parameters. All parameters described here can be used in a call to `sentry_sdk.init()`.
@@ -1168,7 +1170,6 @@ def __init__(
11681170
11691171
:param profile_session_sample_rate:
11701172
1171-
11721173
:param enable_tracing:
11731174
11741175
:param propagate_traces:
@@ -1179,6 +1180,14 @@ def __init__(
11791180
11801181
:param instrumenter:
11811182
1183+
:param enable_logs: Set `enable_logs` to True to enable the SDK to emit
1184+
Sentry logs. Defaults to False.
1185+
1186+
:param before_send_log: An optional function to modify or filter out logs
1187+
before they're sent to Sentry. Any modifications to the log in this
1188+
function will be retained. If the function returns None, the log will
1189+
not be sent to Sentry.
1190+
11821191
:param _experiments:
11831192
"""
11841193
pass

sentry_sdk/integrations/logging.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
event_from_exception,
1313
current_stacktrace,
1414
capture_internal_exceptions,
15+
has_logs_enabled,
1516
)
1617
from sentry_sdk.integrations import Integration
1718

@@ -344,7 +345,7 @@ def emit(self, record):
344345
if not client.is_active():
345346
return
346347

347-
if not client.options["_experiments"].get("enable_logs", False):
348+
if not has_logs_enabled(client.options):
348349
return
349350

350351
self._capture_log_from_record(client, record)

sentry_sdk/integrations/loguru.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
_BaseHandler,
99
)
1010
from sentry_sdk.logger import _log_level_to_otel
11+
from sentry_sdk.utils import has_logs_enabled
1112

1213
from typing import TYPE_CHECKING
1314

@@ -151,7 +152,7 @@ def loguru_sentry_logs_handler(message):
151152
if not client.is_active():
152153
return
153154

154-
if not client.options["_experiments"].get("enable_logs", False):
155+
if not has_logs_enabled(client.options):
155156
return
156157

157158
record = message.record

sentry_sdk/utils.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959

6060
from gevent.hub import Hub
6161

62-
from sentry_sdk._types import Event, ExcInfo
62+
from sentry_sdk._types import Event, ExcInfo, Log, Hint
6363

6464
P = ParamSpec("P")
6565
R = TypeVar("R")
@@ -1984,3 +1984,24 @@ def serialize_item(item):
19841984
return json.dumps(serialized, default=str)
19851985
except Exception:
19861986
return str(data)
1987+
1988+
1989+
def has_logs_enabled(options):
1990+
# type: (Optional[dict[str, Any]]) -> bool
1991+
if options is None:
1992+
return False
1993+
1994+
return bool(
1995+
options.get("enable_logs", False)
1996+
or options["_experiments"].get("enable_logs", False)
1997+
)
1998+
1999+
2000+
def get_before_send_log(options):
2001+
# type: (Optional[dict[str, Any]]) -> Optional[Callable[[Log, Hint], Optional[Log]]]
2002+
if options is None:
2003+
return None
2004+
2005+
return options.get("before_send_log") or options["_experiments"].get(
2006+
"before_send_log"
2007+
)

tests/integrations/logging/test_logging.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def test_sentry_logs_warning(sentry_init, capture_envelopes):
304304
"""
305305
The python logger module should create 'warn' sentry logs if the flag is on.
306306
"""
307-
sentry_init(_experiments={"enable_logs": True})
307+
sentry_init(enable_logs=True)
308308
envelopes = capture_envelopes()
309309

310310
python_logger = logging.Logger("test-logger")
@@ -329,7 +329,7 @@ def test_sentry_logs_debug(sentry_init, capture_envelopes):
329329
"""
330330
The python logger module should not create 'debug' sentry logs if the flag is on by default
331331
"""
332-
sentry_init(_experiments={"enable_logs": True})
332+
sentry_init(enable_logs=True)
333333
envelopes = capture_envelopes()
334334

335335
python_logger = logging.Logger("test-logger")
@@ -344,7 +344,7 @@ def test_no_log_infinite_loop(sentry_init, capture_envelopes):
344344
If 'debug' mode is true, and you set a low log level in the logging integration, there should be no infinite loops.
345345
"""
346346
sentry_init(
347-
_experiments={"enable_logs": True},
347+
enable_logs=True,
348348
integrations=[LoggingIntegration(sentry_logs_level=logging.DEBUG)],
349349
debug=True,
350350
)
@@ -361,7 +361,7 @@ def test_logging_errors(sentry_init, capture_envelopes):
361361
"""
362362
The python logger module should be able to log errors without erroring
363363
"""
364-
sentry_init(_experiments={"enable_logs": True})
364+
sentry_init(enable_logs=True)
365365
envelopes = capture_envelopes()
366366

367367
python_logger = logging.Logger("test-logger")
@@ -396,7 +396,7 @@ def test_log_strips_project_root(sentry_init, capture_envelopes):
396396
The python logger should strip project roots from the log record path
397397
"""
398398
sentry_init(
399-
_experiments={"enable_logs": True},
399+
enable_logs=True,
400400
project_root="/custom/test",
401401
)
402402
envelopes = capture_envelopes()
@@ -425,7 +425,7 @@ def test_logger_with_all_attributes(sentry_init, capture_envelopes):
425425
"""
426426
The python logger should be able to log all attributes, including extra data.
427427
"""
428-
sentry_init(_experiments={"enable_logs": True})
428+
sentry_init(enable_logs=True)
429429
envelopes = capture_envelopes()
430430

431431
python_logger = logging.Logger("test-logger")
@@ -498,7 +498,7 @@ def test_sentry_logs_named_parameters(sentry_init, capture_envelopes):
498498
"""
499499
The python logger module should capture named parameters from dictionary arguments in Sentry logs.
500500
"""
501-
sentry_init(_experiments={"enable_logs": True})
501+
sentry_init(enable_logs=True)
502502
envelopes = capture_envelopes()
503503

504504
python_logger = logging.Logger("test-logger")
@@ -543,7 +543,7 @@ def test_sentry_logs_named_parameters_complex_values(sentry_init, capture_envelo
543543
"""
544544
The python logger module should handle complex values in named parameters using safe_repr.
545545
"""
546-
sentry_init(_experiments={"enable_logs": True})
546+
sentry_init(enable_logs=True)
547547
envelopes = capture_envelopes()
548548

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

tests/integrations/loguru/test_loguru.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def test_sentry_logs_warning(
141141
uninstall_integration("loguru")
142142
request.addfinalizer(logger.remove)
143143

144-
sentry_init(_experiments={"enable_logs": True})
144+
sentry_init(enable_logs=True)
145145
envelopes = capture_envelopes()
146146

147147
logger.warning("this is {} a {}", "just", "template")
@@ -165,7 +165,7 @@ def test_sentry_logs_debug(
165165
uninstall_integration("loguru")
166166
request.addfinalizer(logger.remove)
167167

168-
sentry_init(_experiments={"enable_logs": True})
168+
sentry_init(enable_logs=True)
169169
envelopes = capture_envelopes()
170170

171171
logger.debug("this is %s a template %s", "1", "2")
@@ -182,7 +182,7 @@ def test_sentry_log_levels(
182182

183183
sentry_init(
184184
integrations=[LoguruIntegration(sentry_logs_level=LoggingLevels.SUCCESS)],
185-
_experiments={"enable_logs": True},
185+
enable_logs=True,
186186
)
187187
envelopes = capture_envelopes()
188188

@@ -216,7 +216,7 @@ def test_disable_loguru_logs(
216216

217217
sentry_init(
218218
integrations=[LoguruIntegration(sentry_logs_level=None)],
219-
_experiments={"enable_logs": True},
219+
enable_logs=True,
220220
)
221221
envelopes = capture_envelopes()
222222

@@ -267,7 +267,7 @@ def test_no_log_infinite_loop(
267267
request.addfinalizer(logger.remove)
268268

269269
sentry_init(
270-
_experiments={"enable_logs": True},
270+
enable_logs=True,
271271
integrations=[LoguruIntegration(sentry_logs_level=LoggingLevels.DEBUG)],
272272
debug=True,
273273
)
@@ -284,7 +284,7 @@ def test_logging_errors(sentry_init, capture_envelopes, uninstall_integration, r
284284
uninstall_integration("loguru")
285285
request.addfinalizer(logger.remove)
286286

287-
sentry_init(_experiments={"enable_logs": True})
287+
sentry_init(enable_logs=True)
288288
envelopes = capture_envelopes()
289289

290290
logger.error(Exception("test exc 1"))
@@ -313,7 +313,7 @@ def test_log_strips_project_root(
313313
request.addfinalizer(logger.remove)
314314

315315
sentry_init(
316-
_experiments={"enable_logs": True},
316+
enable_logs=True,
317317
project_root="/custom/test",
318318
)
319319
envelopes = capture_envelopes()
@@ -362,7 +362,7 @@ def test_log_keeps_full_path_if_not_in_project_root(
362362
request.addfinalizer(logger.remove)
363363

364364
sentry_init(
365-
_experiments={"enable_logs": True},
365+
enable_logs=True,
366366
project_root="/custom/test",
367367
)
368368
envelopes = capture_envelopes()
@@ -410,7 +410,7 @@ def test_logger_with_all_attributes(
410410
uninstall_integration("loguru")
411411
request.addfinalizer(logger.remove)
412412

413-
sentry_init(_experiments={"enable_logs": True})
413+
sentry_init(enable_logs=True)
414414
envelopes = capture_envelopes()
415415

416416
logger.warning("log #{}", 1)

0 commit comments

Comments
 (0)