/django-custom-logging

Django middleware for custom format logging 🪵

Primary LanguagePythonMIT LicenseMIT

       __  _                                
  ____/ / (_)___ _____  ____ _____          
 / __  / / / __ `/ __ \/ __ `/ __ \         
/ /_/ / / / /_/ / / / / /_/ / /_/ /         
\__,_/_/ /\__,_/_/ /_/\__, /\____/          
    /___/            /____/                 
      _______  _______/ /_____  ____ ___    
     / ___/ / / / ___/ __/ __ \/ __ `__ \   
    / /__/ /_/ (__  ) /_/ /_/ / / / / / /   
    \___/\__,_/____/\__/\____/_/ /_/ /_/    
           __                  _            
          / /___  ____ _____ _(_)___  ____ _
         / / __ \/ __ `/ __ `/ / __ \/ __ `/
        / / /_/ / /_/ / /_/ / / / / / /_/ / 
       /_/\____/\__, /\__, /_/_/ /_/\__, /  
               /____//____/        /____/   

Test PyPI PyPI - Downloads PyPI - Python Version PyPI - License Code style: black

django middleware for custom format logging

Installation

  1. Install the package
python -m pip install django-custom-logging
  1. Add adequate middlewares to MIDDLEWARE in setting file. Current version only supports a middleware that captures request into local thread(threading.local())
MIDDLEWARE = (
    # other middlewares ...
    "custom_logging.middlewares.capture_request",
)
  1. Add custom_logging.filters.CustomFilter to LOGGING in setting file and set capture_list containing a list of variables to be captured(capture_in) and format string to be printed(capture_out). Also add filter on handler's filter list.
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "verbose": {
            "format": "{levelname} {asctime} {module} {process:d} {thread:d}"
                      " [USER_ID:{user_id}] {message}",
                                #^^^^^^^^^ - (A)
            "style": "{",
        },
    },
    "filters": {
        "custom_filter": {
        #^^^^^^^^^^^^^ - (B)
            "()": "custom_logging.filters.CustomFilter",
            "capture_list": (
                # (capture_in, capture_out)
                ("request.user.id", "user_id"),
                                    #^^^^^^^ - (A)
            ),
        },
    },
    "handlers": {
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "verbose",
            "filters": ["custom_filter"],
                        #^^^^^^^^^^^^^ - (B)
        },
    },
    "root": {"level": "INFO", "handlers": ["console"]},
}

Note that you can use any format styles(%, {, $), but should make format arguments with str type. For example, if you want to capture request.user.id as user_id, please follow format below.

%-style: %(user_id)s
{-style: {user_id}
$-style: ${user_id}

How to use

You can use logger just like before. No extra parameter is needed.

import logging

from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

logger = logging.getLogger(__name__)


class ExampleView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):
        logger.info("example log")
        return Response({"hello": "world!"}, status=status.HTTP_200_OK)
INFO 2021-03-25 11:33:25,170 credentials 35052 4748750336 [USER_ID:-] Found credentials in shared credentials file: ~/.aws/credentials
INFO 2021-03-25 11:33:25,505 views 35052 4748750336 [USER_ID:33] example log

Supported versions

  • Python: >=3.5
  • Django: >=3

Contribution

Feel free to open issue or pull request.