Logging

Learn about logging with Python.

The logging integration adds support for the logging framework from Python's standard library. Depending on your settings, logs can be captured as Sentry logs, as error events, or as breadcrumbs, or a combination of those.

Install sentry-sdk from PyPI:

Copied
pip install "sentry-sdk"

To capture log records as Sentry logs, set enable_logs to True. The logging integration is a default integration, so it will be enabled automatically when you initialize the Sentry SDK.

Copied
import sentry_sdk

sentry_sdk.init(
    dsn="___PUBLIC_DSN___",
    # Add data like request headers and IP for users, if applicable;
    # see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
    send_default_pii=True,
    enable_logs=True,
)

Copied
import logging

def main():
    sentry_sdk.init(...)  # same as above
    logging.info("Logging some info")
    logging.error("Logging an error")

main()

This will capture both logs and send them to Sentry Logs. Additionally, an error event will be created from the ERROR-level log. In addition to that, a breadcrumb will be created from the INFO-level log.

As long as enable_logs is True, logs with a level of INFO and higher will be captured as Sentry logs if the log level set in the logging module is INFO or below. The threshold can be configured via the sentry_logs_level option.

Additionally, the logging integration will create an error event from all ERROR-level logs. This feature is configurable via the event_level integration option.

INFO and above logs will also be captured as breadcrumbs. Use the level integration option to adjust the threshold.

Copied
import logging

import sentry_sdk

sentry_sdk.init(
    ...,
    enable_logs=True,
)

# The following will be captured as Sentry logs:
logging.info("I'm an INFO log")
logging.error("I'm an ERROR log", extra={"bar": 43})
logging.exception("I'm an exception log")

# DEBUG-level logs won't be captured by default
logging.debug("I'm a DEBUG log")
  • All of the above logs except for the DEBUG level message will be sent to Sentry as logs.
  • An error event with the message "I'm an ERROR log" will be created.
  • "I'm an INFO log" will be attached as a breadcrumb to that event.
  • bar will end up in the extra attributes of that event.
  • "I'm an exception log" will send the current exception from sys.exc_info() with the stack trace to Sentry. If there's no exception, the current stack will be attached.
  • The debug message "I'm a DEBUG log" will not be captured by Sentry. See the sentry_logs_level option to adjust which levels should be sent to Sentry as logs, and the level option to do adjust the level for capturing breadcrumbs.

When sending log records as Sentry logs, any fields provided in the extra dictionary are automatically promoted to top-level attributes on the log entry. This makes them searchable and filterable in the Sentry UI.

Copied
import logging
import sentry_sdk

sentry_sdk.init(
    # ...
    enable_logs=True,
)

logger = logging.getLogger(__name__)

# Extra fields become top-level searchable attributes
logger.error(
    "Payment processing failed", 
    extra={
        "user_id": 12345,
        "transaction_id": "txn_abc123", 
        "payment_method": "credit_card",
        "amount": 99.99
    }
)

In this example, user_id, transaction_id, payment_method, and amount will appear as separate, searchable attributes in the Sentry logs interface, not nested within an extra object. You can filter and query logs using these attributes directly, such as user_id:12345 or payment_method:credit_card.

To change the default behavior of the logging integration, instantiate the integration manually and pass it to Sentry's init function:

Copied
import logging
import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration

# The SDK will honor the level set by the logging library, which is WARNING by default.
# If we want to capture records with lower severity, we need to configure
# the logger level first.
logging.basicConfig(level=logging.INFO)

sentry_sdk.init(
    # ...
    integrations=[
        LoggingIntegration(
            sentry_logs_level=logging.INFO,  # Capture INFO and above as logs
            level=logging.INFO,              # Capture INFO and above as breadcrumbs
            event_level=logging.ERROR,       # Send ERROR records as events
        ),
    ],
)

You can pass the following keyword arguments to LoggingIntegration():

  • sentry_logs_level (default INFO): The Sentry Python SDK will capture records with a level higher than or equal to sentry_logs_level as Sentry structured logs as long as the enable_logs option is True.

    Copied
    sentry_sdk.init(
        # ...
        enable_logs=True,
    )
    
  • level (default INFO): The Sentry Python SDK will record log records with a level higher than or equal to level as breadcrumbs. Inversely, the SDK completely ignores any log record with a level lower than this one. If a value of None occurs, the SDK won't send log records as breadcrumbs.

  • event_level (default ERROR): The Sentry Python SDK will report log records with a level higher than or equal to event_level as events as long as the logger itself is set to output records of those log levels (see note below). If a value of None occurs, the SDK won't send log records as events.

Sometimes a logger is extremely noisy and spams you with pointless errors. You can ignore that logger by calling ignore_logger:

Copied
from sentry_sdk.integrations.logging import ignore_logger

ignore_logger("a.spammy.logger")

logger = logging.getLogger("a.spammy.logger")
logger.error("hi")  # no error sent to sentry

You can also use before-send and before-breadcrumb to ignore only certain messages. See Filtering Events for more information.

Instead of using LoggingIntegration, you can use two regular logging logging.Handler subclasses that the integration exports.

Usually, you don't need this. You can use this together with default_integrations=False if you want to opt into what the Sentry Python SDK captures. However, correctly setting up logging is difficult. Also, an opt-in approach to capture data will miss errors you may not think of on your own.

See the API documentation for more information.

Logs not appearing in Sentry

First, make sure you have the enable_logs=True option in your sentry_sdk.init() and you're on the latest version of the SDK.

The SDK will honor the configured level of each logger (set with logger.setLevel(level) or logging.basicConfig(level=level)). That means that you will not see any INFO or DEBUG events from a logger with the level set to WARNING, regardless of how you configure the integration. If not set explicitly, the logging level defaults to WARNING.

Some frameworks, such as uvicorn, may reset or override your logging configuration. To ensure your log level is applied and logs at or above the configured level are picked up by the SDK, you can use the force=True flag when configuring your log level. For example logger.setLevel(level, force=True) and logging.basicConfig(level=level, force=True).

Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").