Package: django-datadog-logger
Django DataDog LoggerDjango DataDog Logger integration package.Free software: MIT licenseDocumentation:https://django-datadog-logger.readthedocs.io.Quick startSet 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:importloggingfromceleryimportCelery,shared_taskfromcelery.resultimportAsyncResultfromcelery.signalsimportafter_setup_logger,after_setup_task_loggerfromdjango.confimportsettingsfromdjango_datadog_logger.celeryimportstore_celery_requestlogger=logging.getLogger(__name__)@after_setup_logger.connectdefon_after_setup_logger(logger,*args,**kwargs):fromdjango_datadog_logger.formatters.datadogimportDataDogJSONFormatterifsettings.API_LOG_CELERY_JSON:formatter=DataDogJSONFormatter()forhandlerinlist(logger.handlers):handler.setFormatter(formatter)handler.setLevel(settings.API_LOG_CELERY_LEVEL)@after_setup_task_logger.connectdefon_after_setup_task_logger(logger,*args,**kwargs):fromdjango_datadog_logger.formatters.datadogimportDataDogJSONFormatterifsettings.API_LOG_CELERY_JSON:formatter=DataDogJSONFormatter()forhandlerinlist(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_requestdefdebug_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"})return42ddtraceThe ddtrace library has an option to inject tracing context data into
log records:https://ddtrace.readthedocs.io/en/stable/advanced_usage.html#logs-injectionThere 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 recordsimportddtraceddtrace.patch(logging=True)# Configure logger with DataDogJSONFormatterimportloggingfromdjango_datadog_logger.formatters.datadogimportDataDogJSONFormatterlogger=logging.roothandler=logging.StreamHandler()handler.formatter=DataDogJSONFormatter()logger.addHandler(handler)logger.setLevel(logging.INFO)# Log a test messagelogger.info("test")$DD_SERVICE=djangoDD_ENV=testDD_VERSION=1234pythonlog.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 todatadog.patch(logging=True)you end up with:$pythontest.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"}CreditsThis package was created withCookiecutterand theaudreyr/cookiecutter-pypackageproject template.History0.6.2 (2023-04-27)Fixed case where accessing request.auth may raise errors0.6.1 (2023-04-27)Removed dependency on Celery package, fixed import error0.6.0 (2023-04-27)Removed dependency on Celery package0.5.6 (2023-01-17)Datadog formatter: avoid recursion loop when accessing WSGI request
auth attribute0.5.5 (2023-01-16)Improved support for request version reporting inhttp.request_versionAdd support forhttp.url_details.view_name0.5.4 (2023-01-16)Added support for HTTP Accept header ashttp.accept0.5.3 (2022-12-19)Added support for JWT cid claim0.5.2 (2022-11-23)Fixed: don't let the logger throw a DisallowedHost error0.5.1 (2022-08-09)Fixed: ActionLoginMixin class methodsperform_createandperform_updatecallsuper(). Remove atomic transaction0.5.0 (2021-10-20)Added support for Celery v5+0.4.0 (2021-08-27)Enhancement: Updated formatting in README.rst #5Enhancement: Extract and add dd.* attributes from log record to log
entry dict #6Fixed: KeyError because a dict appears where a list is expected #70.3.5 (2021-06-14)Prevent recursion when warnings are logged whilst accessing WSGI
request.user0.3.4 (2021-06-14)Fixed import error for future package0.3.3 (2020-11-04)Added support for incoming HTTP X-Request-ID header values0.3.2 (2020-04-24)Respect User.USERNAME_FIELD0.3.1 (2020-04-24)Removed API_LOG_REQUEST_DURATION_WARN_SECONDS0.3.0 (2020-04-15)Improved Celery task received messages logging.Removed RequestIdFilter (not needed anymore).0.2.0 (2020-04-14)Added Celery request local.0.1.0 (2020-02-17)First release on PyPI.