Django Datadog Logger
Django Datadog Logger integration package.
- Free software: MIT license
- Documentation: https://django-datadog-logger.readthedocs.io.
Quick start
Set up request id tracking (in front) and logging middlewares (at the end):
MIDDLEWARE = [
"django_datadog_logger.middleware.request_id.RequestIdMiddleware",
# ...
"django_datadog_logger.middleware.error_log.ErrorLoggingMiddleware",
"django_datadog_logger.middleware.request_log.RequestLoggingMiddleware",
]
Configure LOGGERS in your Django settings file:
API_LOG_ROOT = env.str("API_LOG_ROOT")
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"console": {"format": "{levelname} {message}", "style": "{"},
"json": {"()": "django_datadog_logger.formatters.datadog.DatadogJSONFormatter"},
},
"handlers": {
"console": {"level": "INFO", "class": "logging.StreamHandler", "formatter": "console"},
"application": {
"level": API_LOG_APPLICATION_LEVEL,
"class": "logging.FileHandler",
"filename": os.path.join(API_LOG_ROOT, "api.application.log"),
"formatter": "json",
},
"state": {
"level": API_LOG_STATE_LEVEL,
"class": "logging.FileHandler",
"filename": os.path.join(API_LOG_ROOT, "api.state.log"),
"formatter": "json",
},
"request": {
"level": API_LOG_REQUEST_LEVEL,
"class": "logging.FileHandler",
"filename": os.path.join(API_LOG_ROOT, "api.request.log"),
"formatter": "json",
},
"session": {
"level": API_LOG_SESSION_LEVEL,
"class": "logging.FileHandler",
"filename": os.path.join(API_LOG_ROOT, "api.session.log"),
"formatter": "json",
},
"error": {
"level": API_LOG_ERROR_LEVEL,
"class": "logging.FileHandler",
"filename": os.path.join(API_LOG_ROOT, "api.error.log"),
"formatter": "json",
},
},
"loggers": {
"": {"handlers": ["console", "error"], "level": "DEBUG", "propagate": True},
"ddtrace": {"handlers": ["error"], "level": "ERROR", "propagate": False},
"django.db.backends": {"handlers": ["error"], "level": "ERROR", "propagate": False},
"twilio": {"handlers": ["error"], "level": "ERROR", "propagate": False},
"my_project": {"handlers": ["application"], "level": "INFO", "propagate": False},
"my_project.throttling": {"handlers": ["application"], "level": "DEBUG", "propagate": False},
"my_project.vehicles.viewsets.state": {"handlers": ["state"], "level": "INFO", "propagate": False},
"my_project.accounts.session": {"handlers": ["session"], "level": "DEBUG", "propagate": False},
"my_project.session": {"handlers": ["session"], "level": "DEBUG", "propagate": False},
"django_auth_ldap": {"level": "DEBUG", "handlers": ["session"], "propagate": False},
"django_datadog_logger.middleware.error_log": {"handlers": ["error"], "level": "INFO", "propagate": False},
"django_datadog_logger.middleware.request_log": {"handlers": ["request"], "level": "INFO", "propagate": False},
"django_datadog_logger.rest_framework": {"handlers": ["application"], "level": "INFO", "propagate": False},
},
}
If you would like to whitelist your projects for passing extra arguments to the json log record, please set the following regular expression:
DJANGO_DATADOG_LOGGER_EXTRA_INCLUDE = r"^(django_datadog_logger|my_project)(|\..+)$"
Add Celery logger configuration and request_id tracking decorator to tasks:
import logging
from celery import Celery, shared_task
from celery.result import AsyncResult
from celery.signals import after_setup_logger, after_setup_task_logger
from django.conf import settings
from django_datadog_logger.celery import store_celery_request
logger = logging.getLogger(__name__)
@after_setup_logger.connect
def on_after_setup_logger(logger, *args, **kwargs):
from django_datadog_logger.formatters.datadog import DatadogJSONFormatter
if settings.API_LOG_CELERY_JSON:
formatter = DatadogJSONFormatter()
for handler in list(logger.handlers):
handler.setFormatter(formatter)
handler.setLevel(settings.API_LOG_CELERY_LEVEL)
@after_setup_task_logger.connect
def on_after_setup_task_logger(logger, *args, **kwargs):
from django_datadog_logger.formatters.datadog import DatadogJSONFormatter
if settings.API_LOG_CELERY_JSON:
formatter = DatadogJSONFormatter()
for handler in list(logger.handlers):
handler.setFormatter(formatter)
handler.setLevel(settings.API_LOG_CELERY_LEVEL)
app = Celery("my_project")
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
@shared_task(bind=True)
@store_celery_request
def debug_task(self):
print("Request: {0!r}".format(self.request))
logger.critical("CRITICAL", extra={"level": "CRITICAL"})
logger.error("ERROR", extra={"level": "ERROR"})
logger.warning("WARNING", extra={"level": "WARNING"})
logger.info("INFO", extra={"level": "INFO"})
logger.debug("DEBUG", extra={"level": "DEBUG"})
return 42
ddtrace
The ddtrace library has an option to inject tracing context data into log records: https://ddtrace.readthedocs.io/en/stable/advanced_usage.html#logs-injection
There is a helper to look for those attributes and add them automatically to the log entry created by this library.
# log.py
# Patch logging library to inject dd.* attributes on log records
import ddtrace
ddtrace.patch(logging=True)
# Configure logger with DatadogJSONFormatter
import logging
from django_datadog_logger.formatters.datadog import DatadogJSONFormatter
logger = logging.root
handler = logging.StreamHandler()
handler.formatter = DatadogJSONFormatter()
logger.addHandler(handler)
logger.setLevel(logging.INFO)
# Log a test message
logger.info("test")
$ DD_SERVICE=django DD_ENV=test DD_VERSION=1234 python log.py
{"message": "test", "logger.name": "root", "logger.thread_name": "MainThread", "logger.method_name": "<module>", "syslog.timestamp": "2021-08-23T18:26:10.391099+00:00", "syslog.severity": "INFO", "dd.version": "1234", "dd.env": "test", "dd.service": "django", "dd.trace_id": "0", "dd.span_id": "0"}
If you remove the call to datadog.patch(logging=True) you end up with:
$ python test.py
{"message": "test", "logger.name": "root", "logger.thread_name": "MainThread", "logger.method_name": "<module>", "syslog.timestamp": "2021-08-23T18:27:47.951461+00:00", "syslog.severity": "INFO"}
Credits
This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.
Release files for django-datadog-logger 0.9.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_datadog_logger-0.9.1.tar.gz | 75.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_datadog_logger-0.9.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 89.4 kB
Release files / django_datadog_logger-0.9.1.tar.gz
| Download URL | django_datadog_logger-0.9.1.tar.gz |
|---|---|
| Size | 75.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ac97a03a673f2e56d032368080111a131624bc7ff9196eb6884fc28264e6a4e7
|
|
BLAKE2b-256 checksum How to use checksums |
727d25e135e6190be7fd977c923bf4d9a43384ea6df19e46ef261e01f743a410
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 8, 2026.
Transparency logRelease files / django_datadog_logger-0.9.1-py3-none-any.whl
| Download URL | django_datadog_logger-0.9.1-py3-none-any.whl |
|---|---|
| Size | 13.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
76061776560ebd06b748d46b936e6678d0af457e8e41acd7c1bb43bf60a0a508
|
|
BLAKE2b-256 checksum How to use checksums |
75029905afe8ac7f1879063392217599cb20d8f5d1fed5415c1ee79771caba32
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 8, 2026.
Transparency log