Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python logging: display only information from debug level

For my first logging experiment in Python (2.7) I'm creating a basic logging module, which will quickly create a logger for (so I won't have to configure it per module/class).

What I want to do is to create a logger which displays all messages of level INFO and higher on the console, and moves all DEBUG level information to a text file.

Thus far I have create a logger which prints INFO and up to the console, and which prints every log messages to a text file. However, I don't want all the INFO and higher messages in my text file.

I have made a Python Fiddle which holds my code.

I used the following debug messages from a tutorial:

log.debug('All systems operational')
log.info('Airspeed 300 knots')
log.warn('Low on fuel')
log.error('No fuel. Trying to glide.')
log.critical('Glide attempt failed. About to crash.')

Which on the console produce:

[INFO] root: Airspeed 300 knots
[WARNING] root: Low on fuel
[ERROR] root: No fuel. Trying to glide.
[CRITICAL] root: Glide attempt failed. About to crash.

And in my debug_log.txt file:

2013-06-14 14:51:46,963:DEBUG:root:All systems operational
2013-06-14 14:51:46,964:INFO:root:Airspeed 300 knots
2013-06-14 14:51:46,964:WARNING:root:Low on fuel
2013-06-14 14:51:46,964:ERROR:root:No fuel. Trying to glide.
2013-06-14 14:51:46,964:CRITICAL:root:Glide attempt failed. About to crash.

In the above block, the latter four lines should not be in the file. Is what I'm trying to do possible and how would I get the desired result?

like image 680
Marijke Luttekes Avatar asked Jun 14 '13 12:06

Marijke Luttekes


1 Answers

You have to create your own handler object.

From the documentation: The FileHandler class, located in the core logging package, sends logging output to a disk file. It inherits the output functionality from StreamHandler. So here the idea is to extend the FileHandler class, and in the emit() method, filter out all record objects that are not in the logging.DEBUG level.

I have not tested this, but I think it would do the job:

from logging import FileHandler, DEBUG

log = logging.getLogger('foo')


class DebugFileHandler(FileHandler):
    def __init__(self, filename, mode='a', encoding=None, delay=False)
        super().__init__(filename, mode, encoding, delay)
    
    def emit(self, record):
        if not record.levelno == DEBUG:
            return
        super().emit(record)

log.addHandler(DebugFileHandler())

Of course, you'll have to adapt this code to your code. And, to be honest, record.level is a wild guess, but I think it makes sense :-) And, I got it right!

In this example, the handler will only be applied for the foo logger. You may want to activate it for your main handler, or only for some specific handlers, as you may prefer.

like image 66
zmo Avatar answered Oct 17 '22 09:10

zmo