=====================
Django DD Logger
=====================
.. image:: https://img.shields.io/pypi/v/django_dd_logger.svg
:target: https://pypi.python.org/pypi/django-dd-logger
.. image:: https://readthedocs.org/projects/django_dd_logger/badge/?version=latest
:target: https://django-dd-logger.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://pyup.io/repos/github/jacekbj/django_dd_logger/shield.svg
:target: https://pyup.io/repos/github/jacekbj/dd;/
:alt: Security Status
Django DataDog Logger integration package.
This is a fork of https://django-datadog-logger.readthedocs.io/en/latest/.
* Free software: MIT license
* Documentation: https://django-dd-logger.readthedocs.io.
Quick start
-----------
Set up request id tracking (in front) and logging middlewares (at the end):
.. code-block:: python
MIDDLEWARE = [
"django_dd_logger.middleware.request_id.RequestIdMiddleware",
# ...
"django_dd_logger.middleware.error_log.ErrorLoggingMiddleware",
"django_dd_logger.middleware.request_log.RequestLoggingMiddleware",
]
Configure LOGGERS in your Django settings file:
.. code-block:: python
API_LOG_ROOT = env.str("API_LOG_ROOT")
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"console": {"format": "{levelname} {message}", "style": "{"},
"json": {"()": "django_dd_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",
},
"request": {
"level": API_LOG_REQUEST_LEVEL,
"class": "logging.FileHandler",
"filename": os.path.join(API_LOG_ROOT, "api.request.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},
"my_project": {"handlers": ["application"], "level": "INFO", "propagate": False},
"django_dd_logger.middleware.error_log": {"handlers": ["error"], "level": "INFO", "propagate": False},
"django_dd_logger.middleware.request_log": {"handlers": ["request"], "level": "INFO", "propagate": False},
},
}
DDL_EXTRA_INCLUDE = r"^(django_dd_logger|my_project)(|\..+)$"
Add Celery logger configuration and request_id tracking decorator to tasks:
.. code-block:: python
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_dd_logger.celery import store_celery_request
logger = logging.getLogger(__name__)
@after_setup_logger.connect
def on_after_setup_logger(logger, *args, **kwargs):
from django_dd_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_dd_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.
.. code-block:: python
# 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_dd_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")
.. code-block:: bash
$ 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:
.. code-block:: bash
$ 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.
And then it was a bit changed.
.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
Raw data
{
"_id": null,
"home_page": "",
"name": "django-dd-logger",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "django,logging,datadog,logging middleware",
"author": "",
"author_email": "Jacek Bro\u0144ski-Jankowski <contact@jankow.ski>",
"download_url": "https://files.pythonhosted.org/packages/1d/c9/639007632057ff6d1f212f5a9450183ee39af750b31fe3a1de96d1486715/django_dd_logger-0.7.1.tar.gz",
"platform": null,
"description": "=====================\nDjango DD Logger\n=====================\n\n\n.. image:: https://img.shields.io/pypi/v/django_dd_logger.svg\n :target: https://pypi.python.org/pypi/django-dd-logger\n\n.. image:: https://readthedocs.org/projects/django_dd_logger/badge/?version=latest\n :target: https://django-dd-logger.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n\n.. image:: https://pyup.io/repos/github/jacekbj/django_dd_logger/shield.svg\n :target: https://pyup.io/repos/github/jacekbj/dd;/\n :alt: Security Status\n\n\n\nDjango DataDog Logger integration package.\n\nThis is a fork of https://django-datadog-logger.readthedocs.io/en/latest/.\n\n\n* Free software: MIT license\n* Documentation: https://django-dd-logger.readthedocs.io.\n\n\nQuick start\n-----------\n\nSet up request id tracking (in front) and logging middlewares (at the end):\n\n.. code-block:: python\n\n MIDDLEWARE = [\n \"django_dd_logger.middleware.request_id.RequestIdMiddleware\",\n # ...\n \"django_dd_logger.middleware.error_log.ErrorLoggingMiddleware\",\n \"django_dd_logger.middleware.request_log.RequestLoggingMiddleware\",\n ]\n\nConfigure LOGGERS in your Django settings file:\n\n.. code-block:: python\n\n API_LOG_ROOT = env.str(\"API_LOG_ROOT\")\n LOGGING = {\n \"version\": 1,\n \"disable_existing_loggers\": False,\n \"formatters\": {\n \"console\": {\"format\": \"{levelname} {message}\", \"style\": \"{\"},\n \"json\": {\"()\": \"django_dd_logger.formatters.datadog.DataDogJSONFormatter\"},\n },\n \"handlers\": {\n \"console\": {\"level\": \"INFO\", \"class\": \"logging.StreamHandler\", \"formatter\": \"console\"},\n \"application\": {\n \"level\": API_LOG_APPLICATION_LEVEL,\n \"class\": \"logging.FileHandler\",\n \"filename\": os.path.join(API_LOG_ROOT, \"api.application.log\"),\n \"formatter\": \"json\",\n },\n \"request\": {\n \"level\": API_LOG_REQUEST_LEVEL,\n \"class\": \"logging.FileHandler\",\n \"filename\": os.path.join(API_LOG_ROOT, \"api.request.log\"),\n \"formatter\": \"json\",\n },\n \"error\": {\n \"level\": API_LOG_ERROR_LEVEL,\n \"class\": \"logging.FileHandler\",\n \"filename\": os.path.join(API_LOG_ROOT, \"api.error.log\"),\n \"formatter\": \"json\",\n },\n },\n \"loggers\": {\n \"\": {\"handlers\": [\"console\", \"error\"], \"level\": \"DEBUG\", \"propagate\": True},\n \"ddtrace\": {\"handlers\": [\"error\"], \"level\": \"ERROR\", \"propagate\": False},\n \"my_project\": {\"handlers\": [\"application\"], \"level\": \"INFO\", \"propagate\": False},\n \"django_dd_logger.middleware.error_log\": {\"handlers\": [\"error\"], \"level\": \"INFO\", \"propagate\": False},\n \"django_dd_logger.middleware.request_log\": {\"handlers\": [\"request\"], \"level\": \"INFO\", \"propagate\": False},\n },\n }\n DDL_EXTRA_INCLUDE = r\"^(django_dd_logger|my_project)(|\\..+)$\"\n\nAdd Celery logger configuration and request_id tracking decorator to tasks:\n\n.. code-block:: python\n\n import logging\n\n from celery import Celery, shared_task\n from celery.result import AsyncResult\n from celery.signals import after_setup_logger, after_setup_task_logger\n from django.conf import settings\n from django_dd_logger.celery import store_celery_request\n\n logger = logging.getLogger(__name__)\n\n\n @after_setup_logger.connect\n def on_after_setup_logger(logger, *args, **kwargs):\n from django_dd_logger.formatters.datadog import DataDogJSONFormatter\n\n if settings.API_LOG_CELERY_JSON:\n formatter = DataDogJSONFormatter()\n for handler in list(logger.handlers):\n handler.setFormatter(formatter)\n handler.setLevel(settings.API_LOG_CELERY_LEVEL)\n\n\n @after_setup_task_logger.connect\n def on_after_setup_task_logger(logger, *args, **kwargs):\n from django_dd_logger.formatters.datadog import DataDogJSONFormatter\n\n if settings.API_LOG_CELERY_JSON:\n formatter = DataDogJSONFormatter()\n for handler in list(logger.handlers):\n handler.setFormatter(formatter)\n handler.setLevel(settings.API_LOG_CELERY_LEVEL)\n\n\n app = Celery(\"my_project\")\n\n # Using a string here means the worker will not have to\n # pickle the object when using Windows.\n app.config_from_object(\"django.conf:settings\", namespace=\"CELERY\")\n app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)\n\n\n @shared_task(bind=True)\n @store_celery_request\n def debug_task(self):\n print(\"Request: {0!r}\".format(self.request))\n logger.critical(\"CRITICAL\", extra={\"level\": \"CRITICAL\"})\n logger.error(\"ERROR\", extra={\"level\": \"ERROR\"})\n logger.warning(\"WARNING\", extra={\"level\": \"WARNING\"})\n logger.info(\"INFO\", extra={\"level\": \"INFO\"})\n logger.debug(\"DEBUG\", extra={\"level\": \"DEBUG\"})\n return 42\n\nddtrace\n-------\n\nThe ddtrace library has an option to inject tracing context data into log records: https://ddtrace.readthedocs.io/en/stable/advanced_usage.html#logs-injection\n\nThere is a helper to look for those attributes and add them automatically to the log entry created by this library.\n\n.. code-block:: python\n\n # log.py\n\n # Patch logging library to inject dd.* attributes on log records\n import ddtrace\n ddtrace.patch(logging=True)\n\n # Configure logger with DataDogJSONFormatter\n import logging\n from django_dd_logger.formatters.datadog import DataDogJSONFormatter\n\n logger = logging.root\n\n handler = logging.StreamHandler()\n handler.formatter = DataDogJSONFormatter()\n logger.addHandler(handler)\n logger.setLevel(logging.INFO)\n\n\n # Log a test message\n logger.info(\"test\")\n\n.. code-block:: bash\n\n $ DD_SERVICE=django DD_ENV=test DD_VERSION=1234 python log.py\n {\"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\"}\n\nIf you remove the call to `datadog.patch(logging=True)` you end up with:\n\n.. code-block:: bash\n\n $ python test.py\n {\"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\"}\n\n\nCredits\n-------\n\nThis package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.\nAnd then it was a bit changed.\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Django logging utilities for Datadog",
"version": "0.7.1",
"project_urls": {
"Bug Tracker": "https://github.com/jacekbj/django-dd-logger/issues",
"Homepage": "https://github.com/jacekbj/django-dd-logger"
},
"split_keywords": [
"django",
"logging",
"datadog",
"logging middleware"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "955c09b7f6a260d76c43bbb1cb0888a42ecb3072c883f2f38125434f556bdba7",
"md5": "d1f13409aa742f6dfab5c358b75666ef",
"sha256": "f779c9bb801a7a7112cd9730aa37b28547335662c5e61f83676dc25d61628b29"
},
"downloads": -1,
"filename": "django_dd_logger-0.7.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "d1f13409aa742f6dfab5c358b75666ef",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.7",
"size": 11767,
"upload_time": "2024-01-14T20:04:42",
"upload_time_iso_8601": "2024-01-14T20:04:42.647931Z",
"url": "https://files.pythonhosted.org/packages/95/5c/09b7f6a260d76c43bbb1cb0888a42ecb3072c883f2f38125434f556bdba7/django_dd_logger-0.7.1-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1dc9639007632057ff6d1f212f5a9450183ee39af750b31fe3a1de96d1486715",
"md5": "46b8ca2d82e4752be3ee9e8550ba924e",
"sha256": "ccdeafc6f39de42a4c59047fc8be12fa2d6a39d4bed57965564c6c79019b980c"
},
"downloads": -1,
"filename": "django_dd_logger-0.7.1.tar.gz",
"has_sig": false,
"md5_digest": "46b8ca2d82e4752be3ee9e8550ba924e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 21792,
"upload_time": "2024-01-14T20:04:44",
"upload_time_iso_8601": "2024-01-14T20:04:44.020205Z",
"url": "https://files.pythonhosted.org/packages/1d/c9/639007632057ff6d1f212f5a9450183ee39af750b31fe3a1de96d1486715/django_dd_logger-0.7.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-14 20:04:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jacekbj",
"github_project": "django-dd-logger",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "django-dd-logger"
}