473,396 Members | 1,834 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

customizing a logging logger

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
4 1687
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Eric DeWall | last post by:
In trying to clean up the inevitable debug printing littered through some code, I started reading up on the 'logging' module. Browsing groups indicates that the design of the module is...
8
by: Steve Erickson | last post by:
I have a logger class that uses the Python logging module. When I call it within a program using the unittest module, I get one line in the log file for the first test, two identical ones for the...
1
by: flupke | last post by:
Hi, i'm trying to log to the same file (using logging module) from different classes but i can't seem to get it to work. File 1 is the main file which sets up the logger and then i want to also...
1
by: jjesso | last post by:
I am trying to add a new logging level. logging.config.fileConfig("bengineLog.cfg") logging.CLIENT = logging.INFO + 1 logging.addLevelName( logging.CLIENT, 'CLIENT' ) logging.root.setLevel( )...
3
by: Chris Smith | last post by:
Hola, pythonisas: The documentation for the logging module is good, but a bit obscure. In particular, there seems to be a lot of action at a distance. The fact that getLogger() can actually be a...
3
by: seb | last post by:
Hi, I am writing to a file some basic information using the logging module. It is working but in the log file some line are printed several time. I had put some print debugging messages in the...
3
by: pundarikakshaiah | last post by:
Hi, I am using JDK1.4 logging framework and below are the properties that I have in my logging.properties file to configure logging.. handlers= java.util.logging.FileHandler,...
4
by: samwyse | last post by:
In the Python 2.5 Library Reference, section 14.5.3 (Logging to multiple destinations), an example is given of logging to both a file and the console. This is done by using logging.basicConfig()...
6
by: Larry Bates | last post by:
Every time I look at the logging module (up until now) I've given up and continue to use my home-grown logger that I've been using for years. I'm not giving up this time ;-) I find that I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.