473,395 Members | 1,466 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,395 software developers and data experts.

Optional use of logging library module

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 controversial but personally I'm
very happy to see such a full-featured logger as part of the standard
distribution. Here's my problem though (using 2.3.3) - I'm trying to write
some reusable classes that _optionally_ use the logging module. So a class
might look like:

class SomeClass:
def __init__( self, logger=None):
self.logger = logger
(...etc.)

User of the class passes in a Logger object they have already set up with
handlers, etc., class simply calls log methods on the logger when
appropriate. But I can't find a way to create a good "null" logging object
that the class can use by default if no Logger is passed in. I'd like a
simple approach that doesn't involve extending the existing logging library.

Options I've considered:

1) if self.logger: self.logger.log( 'some message' ) [throughout class
methods]
Constantly check if the logger exists - what a pain.

2) [in __init__:] if not logger: self.logger = logging.getLogger("null")
This would be great if a "null" logger was directly supported by the library
and set to do nothing. But it's not, so handlers would need to be
installed, and there's no guarantee for "null" to be unique anyway

3) class NullLogger:
def debug(self, msg, *args, **kwargs): pass
def info(self, msg, *args, **kwargs): pass
def warning(self, msg, *args, **kwargs): pass
def error(self, msg, *args, **kwargs): pass
def exception(self, msg, *args): pass
def critical(self, msg, *args, **kwargs): pass
warn = warning
fatal = critical
Works well, but again I'd rather not extend the original library and this to
be imported all over.

I've also looked at ways of creating a separate logging.Manager, but it is
very coupled to logging.Logger for reasons I can't quite understand from
glancing the code.

Any help is kindly appreciated!
--Eric
Jul 18 '05 #1
6 2188
Eric DeWall wrote:
User of the class passes in a Logger object they have already set up with
handlers, etc., class simply calls log methods on the logger when
appropriate. But I can't find a way to create a good "null" logging object
that the class can use by default if no Logger is passed in. I'd like a
simple approach that doesn't involve extending the existing logging library.


Try the 'null' object design pattern:
http://aspn.activestate.com/ASPN/Coo...n/Recipe/68205

--Irmen
Jul 18 '05 #2
Eric DeWall wrote:
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 controversial but personally I'm
very happy to see such a full-featured logger as part of the standard
distribution. Here's my problem though (using 2.3.3) - I'm trying to write
some reusable classes that _optionally_ use the logging module. So a class
might look like:

<snip>

Hello,

This is an idea by you could do this :

* None or some other ID is passed in (ala the void pattern) as
your Logger
* The Logger is created as a genuine logger
* The logger has propagate set to false to stop messages going upwards
* The logger has it's severity level set so that no messages are logged

OR, you could do this

* None or some other ID is passed in (ala the void pattern) as your
Logger
* The Logger is created as a genuine logger
* A filter is created which simply filters out everything

However what I would suggest could be a good solution for you is to
always have a logger present and log debug messages as debug and use the
other levels for what they are meant for WARNING, ERROR, etc. That way
you can easily turn the logger off in the instance you are working
with. Yes, OK you take a small speed knock but the speed knock I've had
on this is small (I'm not a speed junkie anyways).

I also agree with you, a fully featured logger is essential and
personally - I'm happy with the design, it's not too complicated you
only need to read through the docs and try it out - easy peasy lemon
squeezy.

Cheers,

Neil

--

Neil Benn
Senior Automation Engineer
Cenix BioScience
BioInnovations Zentrum
Tatzberg 47
D-01307
Dresden
Germany

Tel : +49 (0)351 4173 154
e-mail : be**@cenix-bioscience.com
Cenix Website : http://www.cenix-bioscience.com
Jul 18 '05 #3
Hi Neil,

First off, happy to see someone else with some real appreciation for a
standardized and full-featured logging module! You're preaching to the
choir a bit here - I'm also not a speed freak and I will personally _always_
associate a logger with my class instance. But some folks _don't_
use/like/appreciate the logging module so I'd rather not make it a
requirement for them to use logging to reuse my classes. Irmen's suggestion
of the null pattern elegantly solves my dilemma. And for folks who don't
want logging, they'll still have to handle exceptions when something goes
wrong. :)

--Eric

"Neil Benn" <be**@cenix-bioscience.com> wrote in message
news:ma*************************************@pytho n.org...
<snip>
However what I would suggest could be a good solution for you is to
always have a logger present and log debug messages as debug and use the
other levels for what they are meant for WARNING, ERROR, etc. That way
you can easily turn the logger off in the instance you are working
with. Yes, OK you take a small speed knock but the speed knock I've had
on this is small (I'm not a speed junkie anyways).

I also agree with you, a fully featured logger is essential and
personally - I'm happy with the design, it's not too complicated you
only need to read through the docs and try it out - easy peasy lemon
squeezy.

Cheers,

Neil

<snip>
Jul 18 '05 #4
> associate a logger with my class instance. But some folks _don't_
use/like/appreciate the logging module so I'd rather not make it a
requirement for them to use logging to reuse my classes. Irmen's suggestion


I'm curious to know what people don't like about the logging module. I
haven't seen any posts on c.l.py complaining about it, can you point
me to some discussions?
Vinay Sajip
Jul 18 '05 #5
Vinay Sajip wrote:
I'm curious to know what people don't like about the logging module. I
haven't seen any posts on c.l.py complaining about it, can you point
me to some discussions?


First of all: the logging package is *nice*, thank you for providing it.

Here are two older threads that may give you an idea what difficulties
people may encounter when learning to use it:
http://groups.google.com/groups?selm...t%40python.org
http://groups.google.com/groups?selm...ulder.noaa.gov

What I would like to see:

- A one-stop function to get output to a file or stream.

- A standard way to register custom handlers, something like
registerHandlerClass(klass, name=None), name defaulting to klass.__name__.
This would probably imply replacing eval() with a dictionary lookup.

- I find the programmatic interface easier to learn than the config-file
format. A utility function that writes the current configuration to a file
might help here.

- Let config-files and programmatic setup respect each other.

- Allow for multiple root loggers. Logging can be used for totally unrelated
tasks. I feel a little uneasy to have them all in the same hierarchy. (This
one is thinking aloud, I'm not even sure if this cannot be done already
with the Manager class)

None of these are showstoppers, and judging from recent posts on python-dev
you are already working on the first and most important issue.

If you want to attract further suggestions on how to smoothen the logging
experience, from people who are more familiar with the package than I am,
it would probably be a good idea to open up a new thread.

Peter
Jul 18 '05 #6
Peter,

Thanks for the feedback. My thoughts below...
- A one-stop function to get output to a file or stream.
Now in CVS.
- A standard way to register custom handlers, something like
registerHandlerClass(klass, name=None), name defaulting to klass.__name__.
This would probably imply replacing eval() with a dictionary lookup.

- I find the programmatic interface easier to learn than the config-file
format. A utility function that writes the current configuration to a file
might help here.

- Let config-files and programmatic setup respect each other.

The above are good ideas. By "respect each other", I assume you mean
that file-based configuration should not overwrite programmatic
configuration? The overall problem with file-based configuration is
that it replaces the existing configuration totally. I'm thinking
about a different way of configuring which works in an incremental
way. It's too early to say much about it, though.
- Allow for multiple root loggers. Logging can be used for totally unrelated
tasks. I feel a little uneasy to have them all in the same hierarchy. (This
one is thinking aloud, I'm not even sure if this cannot be done already
with the Manager class)
I'm not sure that you need API changes for this - you can achieve the
same effect through non-propagating non-root loggers. Since you can
direct messages at any point to any destination, you can easily keep
totally separate logs for unrelated tasks.
None of these are showstoppers, and judging from recent posts on python-dev
you are already working on the first and most important issue.

If you want to attract further suggestions on how to smoothen the logging
experience, from people who are more familiar with the package than I am,
it would probably be a good idea to open up a new thread.


Good idea. I'll do this.

Thanks again,
Vinay
Jul 18 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Tero Saarni | last post by:
I'm using Logging in my library module for producing trace log of certain events. For being more useful these log entries should be associated with the filename and line number of *users* code...
23
by: Rotem | last post by:
Hi, while working on something in my current project I have made several improvements to the logging package in Python, two of them are worth mentioning: 1. addition of a logging record field...
7
by: Leo Breebaart | last post by:
I have another question where I am not so much looking for a solution but rather hoping to get some feedback on *which* solutions people here consider good Pythonic ways to approach a issue. ...
0
by: robert | last post by:
As more and more python packages are starting to use the bloomy (Java-ish) 'logging' module in a mood of responsibility and as I am not overly happy with the current "thickener" style of usage, I...
2
by: Tod Olson | last post by:
Anyone have advice for importing the logging module using MacPython 2.4.3? MacPython installs the logging module in: /Library/Frameworks/Python.framework/Versions/2.4/lib/logging/ There's an...
3
by: Chris Shenton | last post by:
I am setting up handlers to log DEBUG and above to a rotating file and ERROR and above to console. But if any of my code calls a logger (e.g., logging.error("foo")) before I setup my handlers, the...
3
by: Lowell Alleman | last post by:
Here is the situation: I wrote my own log handler class (derived from logging.Handler) and I want to be able to use it from a logging config file, that is, a config file loaded with the...
4
by: Matthew Wilson | last post by:
I'm working on a package that uses the standard library logging module along with a .cfg file. In my code, I use logging.config.fileConfig('/home/matt/mypackage/matt.cfg') to load in the...
6
by: Thomas Heller | last post by:
I'm using the logging module in my comtypes library to log 'interesting' things that happen. In other words, the idea is if the user of the library is interested in the details that happen in the...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.