6

I've added the following logging configuration to my Django App's settings.py file:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
    },
}

Now, I simply want to add some custom log records to one of my views in views.py, but it appears the logger is NOTSET, which means only levels of warning and higher are logged:

import logging
from django.http import JsonResponse

logger = logging.getLogger(__name__)

def testing(request):
    logger.info("Doesn't show...")
    logger.warning(f"Log Level: {logger.level} = {logging.getLevelName(logger.level)}")
    return JsonResponse({"Hello": "World"})

The snippet above logs the following:

Log Level: 0 = NOTSET

Am I doing something wrong? Why is the logger's level not set (even though I clearly set it in settings.py)?

3 Answers 3

11
+50

Why this behavior?

The logging.getLogger(__name__) statement will initialize a python logger with a dotted path to the current module. In your case, it would be my_app.views. Django is not able to understand the logs that you have created from the views.py since your logger name my_app.views which is not listed in settings.py. Django won't do anything to the logs if you are not specified the logger name/ logger-name pattern accordingly.

How warning logs are displayed?

I hope this So post this explains well, Python logging not outputting anything

Solution

Option-1

change either your logger name in settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'my_app.views': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
    },
}

Key Change: I have changed the logger name django to my_app.views

Option-2

Specify logger name in the getLogger method

logger = logging.getLogger('django')

Key Point: The name of the logger and the logger defined in the Django Settings module should be same.

Sign up to request clarification or add additional context in comments.

1 Comment

Why we should use: os.getenv('DJANGO_LOG_LEVEL', 'INFO') , instead just 'INFO' . I've print the value of DJANGO_LOG_LEVEL on the shell, but it returns None.
2

Since you configured the logger for 'django' and your module is (presumably) not in the django package, you need to get the 'django' logger explicitly:

# logger = logging.getLogger(__name__)
logger = logging.getLogger('django')

Otherwise, you get a logger that is not configured so logger.level is NOTSET.

Django, however, will use your logging configuration.

From https://docs.python.org/3/library/logging.html:

The logger name hierarchy is analogous to the Python package hierarchy, and identical to it if you organise your loggers on a per-module basis using the recommended construction logging.getLogger(__name__). That’s because in a module, __name__ is the module’s name in the Python package namespace.

Comments

0

Because logging.getLogger(__name__) create a python logger with a path to the current module and since you don't register this logger in your setting, Django is not able to understand the logger that you have created from the views.py. One solution is to register it in your setting as @JPG said before. Another solution is to create it manually. For example you can create an Utils.py file and create this function to create your logger.

import logging
def get_view_logger(view_name):
    logger = logging.getLogger(view_name)
    logger.setLevel(logging.INFO)
    handler = TimedRotatingFileHandler(os.path.join(BASE_DIR, 'log/' + view_name + '.log'),
                                       when='midnight', backupCount=20, encoding="utf8")
    formatter = logging.Formatter('%(asctime)s [%(levelname)s] : %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    return logger

You can customize each of component of your logger like handler, formatter and etc.

2 Comments

Django is not able to understand the logs → Django doesn't play any part in "understanding" the logs. Python's logging library simply returns a logger that is not configured.
Django doesn't play any part in understanding the logger either. It might even be accurate to say that Django plays no part at all in this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.