Re: [Tutor] Makeing a logfile

Magnus Lycka magnus at thinkware.se
Wed Apr 28 15:51:23 EDT 2004


John Ertl wrote:
> I am trying to make a single log file for a program that uses several
> modules.  Now when I run the program I open a file and redirect standard out
> to a file.  This works fine for the main program and each of the modules do
> the same thing but to there own files.  I would like to have just one file
> containing my log output.
>  
> How can I get the print statements from the modules to output to the file
> opened in the main program?  I would like to be able to run the modules
> individually and have the output go to the screen but when run from the main
> program the prints go to the opened log file.

First of all, I suggest that you consider using the standard 
library logging module. Don't reinvent the wheel...

Please look at PEP 282 and the chapter on the logging module in
the library reference. It does exactly what you want. From the
docs:

=======================================
Here's a simple logging example that just logs to a file. In order, it creates a Logger instance, then a FileHandler and a Formatter. It attaches the Formatter to the FileHandler, then the FileHandler to the Logger. Finally, it sets a debug level for the logger. 

import logging
logger = logging.getLogger('myapp')
hdlr = logging.FileHandler('/var/tmp/myapp.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr) 
logger.setLevel(logging.WARNING)

We can use this logger object now to write entries to the log file: 

logger.error('We have a problem')
logger.info('While this is just chatty')

If we look in the file that was created, we'll see something like this: 

2003-07-08 16:49:45,896 ERROR We have a problem
=======================================

You can do "logger = logging.getLogger('myapp')" anywhere in 
you application (in any module), and it will find the same log. 
(Of course, you should only format the logger in one place. :)

If you absolutely don't want to use the logging module, you could 
do something like:

======module x.py========
import sys
LOG = sys.stdout

def test_log(msg):
    print >> LOG, msg
=========================

>>> import x
>>> x.test_log('Hello')
Hello
>>> import cStringIO as StringIO
>>> log = StringIO.StringIO()
>>> x.LOG = log
>>> x.test_log('How do you do?')
>>> log.seek(0)
>>> log.read()
'How do you do?\n'

You see? You have redirected x.LOG to some other kind of stream.
(A file would work as well of course.) But this is very primitive
compared to the logging module. (After all, you don't really want
your main program to mess with global variables in various modules,
and you certainly don't want your main program to know if x in turn
imports another module, if that has logging, and if that in turn
import some other module...

So, use the standard solution! It's only a standard module since 
version 2.3, but if you need your code to work with earlier Python 
versions, the logging module will still work with them if you just 
install it.

-- 
Magnus Lycka, Thinkware AB
Alvans vag 99, SE-907 50 UMEA, SWEDEN
phone: int+46 70 582 80 65, fax: int+46 70 612 80 65
http://www.thinkware.se/  mailto:magnus at thinkware.se



More information about the Tutor mailing list