logging module: add client_addr to all log records

Joel.Hedlund at gmail.com Joel.Hedlund at gmail.com
Mon May 8 17:54:31 EDT 2006


Hi!

I'm writing a server and I want to use the logging module for logging
stuff. I want to log all transactions in detail, and if everything goes
haywire I want to know which client did it. Therefore I want to affix
the client address to every single log item.

I would like to do the following:
Formatter("[%(client_addr)s]: %(message)s")
...
logger.critical("Offal Barrage Detected: Running Away", client_addr =
'french.knights.org')

I've written something that accomplishes this (example below), but I
have this nagging feeling that this could have been done in a better
way. Any ideas?

When test.py executes it prints this:
[WARNING|2006-05-08 23:44:57,421|internal]: Unable to Pronounce 'ni!'
[WARNING|2006-05-08 23:44:57,421|french.knights.nu]: Incoming Bovine
Detected

I'm grateful for any advice.

Cheers!
/Joel Hedlund

test.py
---------------------------------------------------------------------
import logging
import cowlogger
logger = logging.getLogger('cowlogger')
logger.warning("Unable to Pronounce 'ni!'")
logger.warning("Incoming Bovine Detected",
               client_addr = 'french.knights.nu')
---------------------------------------------------------------------

cowlogger.py
---------------------------------------------------------------------
import logging

BaseLogger = logging.getLoggerClass()

class LogRecord(logging.LogRecord):
    def __init__(self, name, level, pathname, lineno, msg, args,
                 exc_info, client_addr):
        """
        Adding client_addr as instantiation parameter and
        attribute.
        """
        logging.LogRecord.__init__(self, name, level, pathname,
                                   lineno, msg, args, exc_info)
        self.client_addr = client_addr

class CowLogger(BaseLogger):
    def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
                   client_addr):
        """
        Code nicked from logging.Logger. I just added client_addr
        to header and LogRecord instantiation.
        """
        return LogRecord(name, level, fn, lno, msg, args, exc_info,
                         client_addr)

    def _log(self, level, msg, args, exc_info=None,
             client_addr = 'internal'):
        """
        Code nicked from logging.Logger. I just added client_addr
        to header and makeRecord call.
        """
        if logging._srcfile:
            fn, lno, func = self.findCaller()
        else:
            fn, lno, func = "(unknown file)", 0, "(unknown function)"
        if exc_info:
            if type(exc_info) != types.TupleType:
                exc_info = sys.exc_info()
        record = self.makeRecord(self.name, level, fn, lno, msg,
                                 args, exc_info, client_addr)
        self.handle(record)

logging.setLoggerClass(CowLogger)

# Setting up log item formatting:
format = "[%(levelname)s|%(asctime)s|%(client_addr)s]: %(message)s"
formatter = logging.Formatter(format)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger = logging.getLogger('cowlogger')
logger.addHandler(handler)
---------------------------------------------------------------------




More information about the Python-list mailing list