By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,941 Members | 1,753 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,941 IT Pros & Developers. It's quick & easy.

customizing a logging logger

P: n/a
Suppose I have some sort of context variable that I want to appear in
log messages. E.g.:

logger = logging.getLogger("somelogger")
class SomeOp:
def __init__(self, ctx):
self.ctx = ctx
def method1(self):
logger.info("%s: here's a message", self.ctx)

What's the idiomatic way to abstract away the inclusion of self.ctx
from the calls in logger.info() et al? Is there some way I can
declare a

@property
def info(self): return logger.info

but have it insert the '"%s: " % self.ctx' bit for me in one place
instead of the dozens of places I currently do it in the class?

Thanks,
Gary

Aug 18 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
I think the following question is clearer.

I want to make it so that method1 below can be transformed:

logger = logging.getLogger("somelogger")
class SomeOp:
def __init__(self, ctx):
self.ctx = ctx
def method1(self):
logger.info("%s: here's a message", self.ctx)
logger.debug("%s: msg #2", self.ctx)
v = 'yessir'
logger.debug("%s: msg #3 %s", self.ctx, v)

into something like:

def method1(self):
logger.info("here's a message")
logger.debug("msg #2")
v = 'yessir'
logger.debug("msg #3 %s", v)
What is the best way to do this, so that I don't have to manually put
the self.ctx in the log string in hundreds of different places?

Thanks,
Gary

Sep 11 '07 #2

P: n/a
On 9/11/07, ga**************@gmail.com <ga**************@gmail.comwrote:
I think the following question is clearer.

I want to make it so that method1 below can be transformed:

logger = logging.getLogger("somelogger")
class SomeOp:
def __init__(self, ctx):
self.ctx = ctx
def method1(self):
logger.info("%s: here's a message", self.ctx)
logger.debug("%s: msg #2", self.ctx)
v = 'yessir'
logger.debug("%s: msg #3 %s", self.ctx, v)

into something like:

def method1(self):
logger.info("here's a message")
logger.debug("msg #2")
v = 'yessir'
logger.debug("msg #3 %s", v)
What is the best way to do this, so that I don't have to manually put
the self.ctx in the log string in hundreds of different places?
One way to do it is to make a mixin class (eg: ContextLogging) which
you construct with the context string. The mixin constructor has a
line like this:

self.logger = logging.getLogger(ctx).

(assuming your context string is appropriate for a logger name)

Then your methods call self.logger instead of the module-level logger.

Another method is also to use a mixin class, which provides methods
"log_debug", "log_info", etc methods which wrap calls to a logger
object.

Another (more advanced) method is to create a custom Logger class. It
uses the call stack to determine if it's caller has a "ctx" attribute,
and pushes the value of that attribute into the message string. Then
you call logging.setLoggerClass so that you get instances of your
custom logger class.
Sep 11 '07 #3

P: n/a
On 11 Sep, 17:14, garyjefferson...@gmail.com wrote:
What is the best way to do this, so that I don't have to manually put
the self.ctx in the log string in hundreds of different places?
Another way is to generate your log messages via a factory method
which prepends the context: you can do this via a mixin, too.

def log_message(self, msg):
return "%s: %s" % (self.ctx, msg)

Note also that in recent versions, an optional "extra" parameter can
be used, to pass info into the LogRecord.

See http://mail.python.org/pipermail/pat...ry/021535.html
which may be of some help - it's a similar use case.

Best regards,

Vinay Sajip

Sep 12 '07 #4

P: n/a
On Sep 12, 10:46 am, Vinay Sajip <vinay_sa...@yahoo.co.ukwrote:
On 11 Sep, 17:14, garyjefferson...@gmail.com wrote:
What is the best way to do this, so that I don't have to manually put
the self.ctx in the log string in hundreds of different places?

Another way is to generate your log messages via a factory method
which prepends the context: you can do this via a mixin, too.

def log_message(self, msg):
return "%s: %s" % (self.ctx, msg)

Note also that in recent versions, an optional "extra" parameter can
be used, to pass info into the LogRecord.

Seehttp://mail.python.org/pipermail/patches/2007-January/021535.html
which may be of some help - it's a similar use case.

Best regards,

Vinay Sajip

The email thread you pointed to was very informative, especially since
I was about to go down the road of creating one logger per context
(eek!).

Whichever method I choose, I am particularly concerned with the
following aspect:

I like to use the "logger.debug("msg %s %s", s1, s2)" format, as I
understand that when the logging for this log level is turned off, we
don't have to do the potentially expensive string building that a '%'
operator would imply.

It seems like using something other than a literal string in the
message is the way to go, since I assume that its __repr__() won't get
called unless the logger is actually going to log a message for it.
Is that right?

Are any of the other methods likely to provide as-good or better
performance?

thanks,
Gary

Sep 12 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.