logging module: add client_addr to all log records

J

Joel.Hedlund

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)
---------------------------------------------------------------------
 
V

Vinay Sajip

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

See a very similar example which uses the new 'extra' keyword argument:

http://docs.python.org/dev/lib/module-logging.html

The example is for a similar use case to yours - showing the IP address
of a client in a logging message.

Best regards,

Vinay Sajip
 
J

Joel Hedlund

See a very similar example which uses the new 'extra' keyword argument:

Now that's brilliant! Exactly what I need.

But unfortunately, it's also unavailable until 2.5 comes out. Until then I'm
afraid I'm stuck with my shoddy hack... but it's always nice to know the time
will come when I can finally throw it out!

Thanks for taking the time!

Cheers!
/Joel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top