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
16 changes: 16 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@ 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`:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

GivenLoggingIntegration and LoguruIntegration are both auto-enabling integrations, I wonder if it might be more useful to give an example for opting out rather than opting in.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're auto-enabling for errors, but they won't start capturing logs unless you explicitly opt in. So no logs is default behavior, and if you want logs, you need to explicitly enable that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, status update 🤦🏻‍♀️ but this will change in a later PR. Will leave this as is as it captures the current state and will update it in the follow up PR.


```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.
- Transaction profiling and related code was removed.
Expand Down
5 changes: 0 additions & 5 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,11 +633,6 @@ def _record_lost_event(
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,
Expand Down
8 changes: 0 additions & 8 deletions sentry_sdk/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
16 changes: 1 addition & 15 deletions sentry_sdk/integrations/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
13 changes: 1 addition & 12 deletions sentry_sdk/integrations/loguru.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 0 additions & 36 deletions tests/integrations/logging/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
48 changes: 0 additions & 48 deletions tests/integrations/loguru/test_loguru.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
):
Expand Down
17 changes: 0 additions & 17 deletions tests/test_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
15 changes: 0 additions & 15 deletions tests/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Loading