Skip to content

Commit e10a190

Browse files
olivermeyerclaude
andcommitted
fix(sentry): disable Sentry logs by default
SentrySettings.enable_logs now defaults to False. On sentry-sdk 2.67.1, the old default sent every INFO+ record from the stdlib logging module and from loguru to Sentry Logs. sentry-sdk 2.68.0 and later ignore enable_logs; capture_sentry_logs=True on LoggingIntegration or LoguruIntegration replaces it. BREAKING CHANGE: {PREFIX}SENTRY_ENABLE_LOGS defaults to false. Log records no longer go to Sentry Logs unless a service opts in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent aff567c commit e10a190

4 files changed

Lines changed: 28 additions & 4 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ set.
169169
| `{PREFIX}SENTRY_PROFILES_SAMPLE_RATE` | `0.1` | Profiler sample rate. |
170170
| `{PREFIX}SENTRY_PROFILE_SESSION_SAMPLE_RATE` | `0.1` | Profile session sample rate. |
171171
| `{PREFIX}SENTRY_PROFILE_LIFECYCLE` | `"trace"` | Profile lifecycle mode: `"trace"` or `"manual"`. |
172-
| `{PREFIX}SENTRY_ENABLE_LOGS` | `true` | Forward log records to Sentry. |
172+
| `{PREFIX}SENTRY_ENABLE_LOGS` | `false` | Send log records to Sentry Logs. Log records can contain credentials and personal data. sentry-sdk 2.68.0 and later ignore this option. With these versions, set `capture_sentry_logs=True` on `LoggingIntegration` or `LoguruIntegration` and pass the integration to `boot(sentry_integrations=...)`. |
173173

174174
#### OpenTelemetry (`{PREFIX}OTEL_`)
175175

‎src/aignostics_foundry_core/AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ This file provides an overview of all modules in `aignostics_foundry_core`, thei
182182

183183
- **Purpose**: Bootstraps Sentry SDK with all project-specific metadata supplied as explicit parameters, making the initialisation reusable across any project without hard-coded constants.
184184
- **Key Features**:
185-
- `SentrySettings(OpaqueSettings)` — uses the active FoundryContext.env_prefix to derive the env prefix (`{ctx.env_prefix}SENTRY_`). Fields: `enabled`, `dsn` (validated HTTPS Sentry URL), `debug`, `send_default_pii`, `include_local_variables` (default `False`; frame locals are not sent), `max_request_body_size` (`"never"` | `"small"` | `"medium"` | `"always"`, default `"never"`; request bodies are not sent), `trace_propagation_targets` (`list[str]` of URL regexes, default `[]`; no outbound request gets `sentry-trace` or `baggage` headers; the env var takes a JSON list), `max_breadcrumbs`, `sample_rate`, `traces_sample_rate`, `profiles_sample_rate`, `profile_session_sample_rate`, `profile_lifecycle`, `enable_logs`
185+
- `SentrySettings(OpaqueSettings)` — uses the active FoundryContext.env_prefix to derive the env prefix (`{ctx.env_prefix}SENTRY_`). Fields: `enabled`, `dsn` (validated HTTPS Sentry URL), `debug`, `send_default_pii`, `include_local_variables` (default `False`; frame locals are not sent), `max_request_body_size` (`"never"` | `"small"` | `"medium"` | `"always"`, default `"never"`; request bodies are not sent), `trace_propagation_targets` (`list[str]` of URL regexes, default `[]`; no outbound request gets `sentry-trace` or `baggage` headers; the env var takes a JSON list), `max_breadcrumbs`, `sample_rate`, `traces_sample_rate`, `profiles_sample_rate`, `profile_session_sample_rate`, `profile_lifecycle`, `enable_logs` (default `False`; no log records go to Sentry Logs; sentry-sdk 2.68.0 and later ignore it and use `capture_sentry_logs=True` on `LoggingIntegration` or `LoguruIntegration`)
186186
- `sentry_initialize(integrations, *, context=None)` — derives all project-specific values (name, version, environment, URLs, runtime flags) from *context* (or the global context); env prefix and env file are read from `ctx.env_prefix` and `ctx.env_file`; initialises Sentry SDK when enabled and DSN present; sets `aignx/base` context; removes the query string and the fragment (`http.query`, `http.fragment` and the query of `url`) from HTTP breadcrumbs and from the span data of transactions, through `before_breadcrumb` and `before_send_transaction` hooks; suppresses noisy loggers; returns `True` on success, `False` otherwise
187187
- `set_sentry_user(user, role_claim)` — maps `sub` → `id`, `org_id` and the optional role claim into Sentry scope; no other claims (no email, name or other personal data); pass `None` to clear context; no-op when `sentry_sdk` is absent
188188
- **Location**: `aignostics_foundry_core/sentry.py`

‎src/aignostics_foundry_core/sentry.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,13 @@ def __init__(self, **kwargs: Any) -> None: # ruff: ignore[any-type]
318318
enable_logs: Annotated[
319319
bool,
320320
Field(
321-
description="Enable Sentry log integration (https://docs.sentry.io/platforms/python/logging/)",
322-
default=True,
321+
description=(
322+
"Send log records to Sentry Logs (https://docs.sentry.io/platforms/python/logs/). "
323+
"Off by default, because log records can contain credentials and personal data. "
324+
"sentry-sdk 2.68.0 and later ignore this option: set capture_sentry_logs=True on "
325+
"LoggingIntegration or LoguruIntegration instead."
326+
),
327+
default=False,
323328
),
324329
]
325330

‎tests/aignostics_foundry_core/sentry_test.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Tests for aignostics_foundry_core.sentry."""
22

33
import json
4+
import logging
45
from collections.abc import Callable, Generator
56
from typing import TYPE_CHECKING, Any
67
from unittest.mock import patch
@@ -11,6 +12,7 @@
1112
import sentry_sdk
1213
from fastapi import FastAPI
1314
from fastapi.testclient import TestClient
15+
from loguru import logger
1416
from pydantic import ValidationError
1517
from sentry_sdk.client import NonRecordingClient
1618
from sentry_sdk.transport import Transport
@@ -59,6 +61,8 @@
5961
_PARTNER_URL = "https://partner.example.org/"
6062
_SENTRY_TRACE_HEADER = "sentry-trace"
6163
_BAGGAGE_HEADER = "baggage"
64+
_APP_LOGGER_NAME = "app"
65+
_LOG_ITEM_TYPE = "log"
6266

6367

6468
class _CapturingTransport(Transport):
@@ -354,6 +358,21 @@ def test_failed_fastapi_request_event_has_request_data_when_always(
354358
(event,) = sentry_capture.items("event")
355359
assert event["request"]["data"][_SECRET_LOCAL_NAME] == _SECRET_LOCAL_VALUE
356360

361+
def test_sentry_logs_not_sent_by_default(
362+
self, sentry_capture: SentryCapture, caplog: pytest.LogCaptureFixture
363+
) -> None:
364+
"""No INFO record from the stdlib logging module or from loguru goes to Sentry Logs at default settings.
365+
366+
The ``app`` logger is set to INFO, so that the record gets to the handlers of the Sentry
367+
logging integration.
368+
"""
369+
caplog.set_level(logging.INFO, logger=_APP_LOGGER_NAME)
370+
sentry_capture.start()
371+
logging.getLogger(_APP_LOGGER_NAME).info("stdlib record for %s", _PROBE_MESSAGE)
372+
logger.info("loguru record for {}", _PROBE_MESSAGE)
373+
374+
assert sentry_capture.items(_LOG_ITEM_TYPE) == []
375+
357376

358377
@pytest.mark.integration
359378
class TestSentryHttpData:

0 commit comments

Comments
 (0)