opensourcegeek
opensourcegeek

Reputation: 5962

python 2.4 logging - dynamic log file name inside loop

I'm trying to write to a separate log file which is created inside a loop using basicConfig. So far I managed to create only one log file which has all the subsequent logging calls. Am I missing something trivial here? I checked the docs it had hints about filemode but nothing else.

import logging


class MultipleInstancesStarter:
    def __init__(self):
        pass


    def startMany(self):
        objs = [Main(str(i)) for i in xrange(1, 10)]
        print objs
        for obj in objs:
            obj._start()


class Main:
    def __init__(self, i):
        self.index = i


    def _start(self):
        name = self.index
        logging.basicConfig(
                        filename="log_" + name + ".log",
                        filemode="w",
                        format="%(asctime)s -  %(levelname)s - %(filename)s:%(module)s:%(lineno)d - %(message)s",
                        level=logging.DEBUG)

        logging.debug("%s Message Debug" % name)
        logging.info("%s Message Info" % name)
        logging.error("%s Message Error" % name)


if __name__ == '__main__':
    MultipleInstancesStarter().startMany()

This creates only log_1.log with log entries from 2nd iteration as well. I tried creating an object outside the loop and it creates a separate file no problem though as shown below.

def startMany(self):
    obj2 = Main("sample")
    obj2._start()

    objs = [Main(str(i)) for i in xrange(1, 10)]
    print objs
    for obj in objs:
        obj._start()

Not sure what I'm doing wrong though, any help would be appreciated. Cheers

Upvotes: 1

Views: 1982

Answers (1)

Paco
Paco

Reputation: 4698

This will work:

import logging


class MultipleInstancesStarter:
    def __init__(self):
        pass

    def startMany(self):
        objs = [Main(str(i)) for i in xrange(1, 10)]
        print objs
        for obj in objs:
            obj._start()


class Main:
    def __init__(self, i):
        self.index = i

    def _start(self):
        name = self.index
        logger = logging.getLogger('%s-%s' % (__name__, self.index))
        handler = logging.FileHandler('log_%s.log' % name)
        log_format = ('%(asctime)s -  %(levelname)s - %(filename)s:'
                      '%(module)s:%(lineno)d - %(message)s')
        formatter = logging.Formatter(log_format)
        handler.setFormatter(formatter)
        logger.addHandler(handler)

        logger.debug("%s Message Debug" % name)
        logger.info("%s Message Info" % name)
        logger.error("%s Message Error" % name)


if __name__ == '__main__':
    MultipleInstancesStarter().startMany()

This it the output (I used tail on the log files):

==> log_1.log <== 2013-11-12 21:08:15,866 - ERROR - test.py:test:31 - 1 Message Error

==> log_2.log <== 2013-11-12 21:08:15,866 - ERROR - test.py:test:31 - 2 Message Error

==> log_3.log <== 2013-11-12 21:08:15,866 - ERROR - test.py:test:31 - 3 Message Error

==> log_4.log <== 2013-11-12 21:08:15,866 - ERROR - test.py:test:31 - 4 Message Error

==> log_5.log <== 2013-11-12 21:08:15,866 - ERROR - test.py:test:31 - 5 Message Error

==> log_6.log <== 2013-11-12 21:08:15,866 - ERROR - test.py:test:31 - 6 Message Error

==> log_7.log <== 2013-11-12 21:08:15,867 - ERROR - test.py:test:31 - 7 Message Error

==> log_8.log <== 2013-11-12 21:08:15,867 - ERROR - test.py:test:31 - 8 Message Error

==> log_9.log <== 2013-11-12 21:08:15,867 - ERROR - test.py:test:31 - 9 Message Error

Basically, if the logging part becomes a bit tricky, use different loggers, one for each instance in that case. A good article to read on Python documentation

EDIT: I forgot to add the log level. To do so, you can add this before adding the handler to the logger

handler.setLevel(logging.DEBUG)

Upvotes: 2

Related Questions