0

I have written a simple django LOGGING in my settings.py and I excepted that to log all error with a traceback in my file. But it doesn't and it just logs errors and everything in one line, but tracebacks are logged into the console. here is my LOGGING:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
            'simple': {
                'format': '{levelname} {asctime} {name} {module}.{funcName}:{lineno} {message}',
                'style': '{',
            },
        },
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': 'logs/debug.log',
            'formatter': 'simple'
        },
    },
    'loggers': {
        '': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

can anybody help me to understand why and what to do? thanks.

John Strood
  • 1,859
  • 3
  • 26
  • 39
A.Stvt
  • 23
  • 5

2 Answers2

2

To achieve this you can add a custom format and then write a custom filter for it to populate its value:

'formatters': {

    'simple_trace': {
        'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(trace)s'
    },

Now, CustomFilter should be inherited from logging.Filter something like:

class CustomFilter(logging.Filter):

    def filter(self, log_record):

        def _get_trace():
            trace = ""
            if log_record.levelname in ['ERROR', 'CRITICAL']:
                # Get the recent stack-trace
                trace = traceback.format_exc().strip()
            return json.dumps(trace)

        log_record.trace = _get_trace()

Like this you can add other format too and just add it's value in log_record.

Finally, we need to inherit handler (in your case- logging.FileHandler ) and add this custom filter to it.

class CustomHandler(logging.FileHandler):    

    def __init__(self, *args, **kwargs):
        logging.FileHandler.__init__(self, *args, **kwargs)
        self.addFilter(CustomFilter())

while setting handlers we need to put our CustomHandler in class:

'handlers': {
    'file': {
        'level': 'DEBUG',
        'class': 'logging_custom.CustomHandler', # path to CustomHandler defination
        'filename': 'logs/debug.log',
        'formatter': 'simple_trace'
    },
},
bak2trak
  • 1,062
  • 8
  • 11
  • It works well but filter method should have a return True statement I guess. – Nicolas Julémont Apr 12 '23 at 10:56
  • Thanks! I can now see the full stack trace in my log file. There was one issue because it was not returning anything and further I just had to write it to log file with properly formatted so I removed json conversion. import traceback class CustomFilter(logging.Filter): def filter(self, log_record): log_record.trace = traceback.format_exc() return log_record – kta May 13 '23 at 10:33
0

The formatter you are using is "simple" (as defined on the config:

 'formatters': {
        'simple': {
            'format': '{levelname} {asctime} {name} {module}.{funcName}:{lineno} {message}',
            'style': '{',
        },
    },

So playing around with this is the trick: Have a look at this: https://docs.python.org/3/library/logging.html#logrecord-attributes

The one you probably want is: {stack_info}

Jmons
  • 1,766
  • 17
  • 28
  • thanks. it worked! but it is written in that link You shouldn’t need to format this yourself. and the other question I have is why it logs in the console too? I haven't difined any console log handler here... @Jmons – A.Stvt Oct 11 '18 at 11:47
  • Mm, what it means is that if you use that variable, you don't pass a second formatter in: i.e. if you use something like "line number" you could hten pass in the second level formatter to specify things like leading 0's etc. the "Format" of the *logger* is different- you're saying which fields you want to be printed out in that log line. *generally speaking* you dont want a full stack trace on every log line - thats a sign you're doing logging 'wrong', i.e. most log lines are informational rather then just exceptions. – Jmons Oct 12 '18 at 10:28