Skip to main content
This documentation outlines how to configure logging with the AppSignal for Python integration.
Logging is only available when using collector mode, which is an experimental feature.

Configure logging

🔐 Do not send Personal Identifiable Information (PII) to AppSignal. Filter PII (e.g., names, emails) from logs and use an ID, hash, or pseudonymized identifier instead.

For HIPAA-covered entities, more information about signing a Business Associate Agreement (BAA) can be found in our Business Add-Ons documentation.
You do not need to create a log source to send logs from the AppSignal for Python integration. An “application” log source will be created automatically. When using collector mode, AppSignal automatically instruments Python’s built-in logging module via OpenTelemetry, attaching a handler to the root logger.

Which logs are captured

AppSignal captures logs sent to the root logger and any logger that propagates to it. Propagation is controlled by the propagate attribute on each logger, which defaults to True in Python. Loggers with propagate=False will not have their messages captured by AppSignal. Some libraries and frameworks set this attribute on their own loggers. Django, for example, sets it on django.server, which the Django section shows how to override.

Set the log level

Python’s logging module defaults to the WARNING log level, meaning that INFO and DEBUG log messages won’t be captured. To capture lower-severity messages, set the root logger level:

Send only specific loggers to AppSignal

By default AppSignal captures everything that reaches the root logger. To send a chosen set of loggers instead, disable the automatic instrumentation with the disable_default_instrumentations configuration option and attach the handler yourself:
Pass log_code_attributes=True to record the file, function, and line each log line came from, as the automatic instrumentation does. A handler you attach yourself is not protected against later reconfiguration the way the automatic instrumentation is. For Django, adding it to the logging configuration itself is the most reliable way to attach it.
Disabling the automatic instrumentation is what keeps AppSignal from attaching a handler of its own. Attaching your own handler without disabling it sends every log line that reaches both handlers twice.

Framework setup

Celery

Celery forks worker processes, so AppSignal must be started for each fork. Use the worker_process_init signal to reinitialize AppSignal and configure logging in each worker process. See the Celery instrumentation page for more details on instrumenting Celery tasks.

Django

Django sets propagate=False on its django.server logger, so its messages do not reach the root logger where AppSignal’s handler is attached. Override it in your LOGGING setting:
To send only specific loggers to AppSignal, add the handler to your LOGGING setting rather than attaching it in code, so that it survives Django configuring the logging module:
For previous versions of AppSignal for Python, we recommended adding the OpenTelemetry LoggingHandler to your LOGGING configuration. When upgrading to AppSignal for Python 1.9.0, you should remove the OpenTelemetry LoggingHandler from your configuration, as AppSignal will attach its own handler, causing your handler to emit duplicate lines.

Sending logs with OpenTelemetry

You can also send logs directly using the OpenTelemetry logs API, without going through Python’s logging module:
Passing a dictionary as the body sends a structured log line. Its keys become attributes on the log line in AppSignal, and a message key becomes the log line’s message:

Filtering logs

You can use the ignore_logs configuration option to ignore log lines. See our Ignore Logs guide to learn more.

Need help?

After configuring your Python application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always reach out for assistance. We’ll help get you back on track!