Creating a custom django logging handler. 'module' object has no attribute 'handlers'
Asked Answered
C

1

6

I'm attempting to create a class based logging handler which notifies some third party service when the app sees a DisallowedHost exception using some of the built in logging configurations provided by django.

However, I'm getting a particular import error that I am unable to understand how to resolve.

My settings.py

LOGGING = {
    ...
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'notify_my_service': {
            'level': 'ERROR',
            'class': 'tools.exception_logging.NotifyMyServiceHandler'
        }
    },
    'loggers': {
        ...
        'django.security.DisallowedHost': {
            'handlers': ['notify_my_service'],
            'propagate': False,
        },
    },
}

My exception handler:

import logging

class NotifyMyServiceHandler(logging.handlers.HTTPHandler):
    def emit(self, error):
        doSomething()

The big traceback

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line 227, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/runserver.py", line 117, in inner_run
    autoreload.raise_last_exception()
  File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line 250, in raise_last_exception
    six.reraise(*_exception)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line 227, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/__init__.py", line 22, in setup
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/log.py", line 75, in configure_logging
    logging_config_func(logging_settings)
  File "/usr/lib/python2.7/logging/config.py", line 794, in dictConfig
    dictConfigClass(config).configure()
  File "/usr/lib/python2.7/logging/config.py", line 576, in configure
    '%r: %s' % (name, e))
ValueError: Unable to configure handler 'notify_my_service': 'module' object has no attribute 'handlers'

So, it appears the logging module for some reason isn't getting properly imported. I've tried examples from other threads such as importing settings in the exception handler module.

Is it possible to write custom handlers for django logging in this way?

Callison answered 5/12, 2018 at 20:49 Comment(0)
I
5

When I simulate your situation with code here, the problem I run into is with this code, which errors because the logging module does not have a handlers attribute.

import logging

class NotifyMyServiceHandler(logging.handlers.HTTPHandler):
    def emit(self, error):
        doSomething()

What you are looking for is to import the logging.handlers module. So you need:

import logging.handlers

class NotifyMyServiceHandler(logging.handlers.HTTPHandler):
    def emit(self, error):
        doSomething()

Unfortunately, the logging.config module reports the error by raising a new exception that hides the original stack trace, which makes finding the original error difficult.

Ingrate answered 8/1, 2019 at 18:21 Comment(1)
Yes, sorry I should have updated this question as I've discovered this same problem, which results in the exception you discovered. It doesn't appear using simple middleware works either, as django's DisallowedHost handling happens before any middleware is executed.Callison

© 2022 - 2024 — McMap. All rights reserved.