How to log messages _only once_ from all modules ?

Ron Barak rbarakx at gmail.com
Tue Nov 24 10:14:56 EST 2009


On Nov 24, 5:08 pm, Soltys <sol... at noabuse.com> wrote:
> Ron Barak pisze:
>
>
>
>
>
> > On Nov 24, 3:45 pm, Soltys <sol... at noabuse.com> wrote:
> >> Barak, Ron pisze:
>
> >>> Hi,
> >>> I'm trying to add the logging module to my application, but I seem to be missing something.
> >>> My application (a wxPython one) has a main script that calls various helper classes.
> >>> I want the log messages from all modules to go to one central log file.
> >>> When I implement logging, I think that due to preparation, I get the same message more than once.
> >>> Here's an example:
> >>> $ cat -n server.py
> >>>      1  import logging
> >>>      2  import logging.handlers
> >>>      3
> >>>      4  class Server():
> >>>      5      def __init__(self):
> >>>      6          self.client_logger = logging.getLogger("client")
> >>>      7          self.client_logger.setLevel(logging.DEBUG)
> >>>      8          h = logging.FileHandler("client.log")
> >>>      9          h.setLevel(logging.DEBUG)
> >>>     10          formatter = logging.Formatter("%(asctime)s %(name)-12s %(levelname)-8s %(message)s")
> >>>     11          h.setFormatter(formatter)
> >>>     12          self.client_logger.addHandler(h)
> >>>     13
> >>>     14      def util(self):
> >>>     15          self.client_logger.warning('This message comes from Server module')
> >>> $ cat -n client.py
> >>>      1  import logging
> >>>      2  import logging.handlers
> >>>      3  from server import Server
> >>>      4
> >>>      5  class Client():
> >>>      6      def __init__(self):
> >>>      7          self.client_logger = logging.getLogger("client")
> >>>      8          self.client_logger.setLevel(logging.DEBUG)
> >>>      9          h = logging.FileHandler("client.log")
> >>>     10          h.setLevel(logging.DEBUG)
> >>>     11          formatter = logging.Formatter("%(asctime)s %(name)-12s %(levelname)-8s %(message)s")
> >>>     12          h.setFormatter(formatter)
> >>>     13          self.client_logger.addHandler(h)
> >>>     14
> >>>     15      def client_test(self):
> >>>     16          self.client_logger.warning("This message comes from Client module")
> >>>     17
> >>>     18  if __name__ == "__main__":
> >>>     19      ser = Server()
> >>>     20      cli = Client()
> >>>     21      ser.util()
> >>>     22      cli.client_test()
> >>> $ rm client.log ; python client.py ; cat client.log
> >>> 2009-11-24 14:40:39,762 client       WARNING  This message comes from Server module
> >>> 2009-11-24 14:40:39,762 client       WARNING  This message comes from Server module
> >>> 2009-11-24 14:40:39,762 client       WARNING  This message comes from Client module
> >>> 2009-11-24 14:40:39,762 client       WARNING  This message comes from Client module
> >>> Googling and readinghttp://docs.python.org/library/logging.htmldidn'tenlighten me.
> >>> Could you suggest what should I change in the above scripts so that the log messages would appear only once ?
> >>> Thanks,
> >>> Ron.
> >> Have a look athttp://docs.python.org/library/logging.html#logger-objects
> >> First thing mentioned is Logger.propagate which is, what I believe, you're
> >> looking for ;)
>
> >> --
> >> Soltys
>
> >> "Free software is a matter of liberty not price"- Hide quoted text -
>
> >> - Show quoted text -
>
> > Hi Soltys,
> > I actually tried that, without any noticeable effects, viz.:
>
> > $ cat server.py
> > import logging
> > import logging.handlers
>
> > class Server():
> >     def __init__(self):
> >         self.client_logger = logging.getLogger("client")
> >         self.client_logger.setLevel(logging.DEBUG)
> >         h = logging.FileHandler("client.log")
> >         h.setLevel(logging.DEBUG)
> >         formatter = logging.Formatter("%(asctime)s %(name)-12s %
> > (levelname)-8s %(message)s")
> >         h.setFormatter(formatter)
> >         self.client_logger.addHandler(h)
> >         self.client_logger.propagate = 0
>
> >     def util(self):
> >         self.client_logger.warning('This message comes from Server
> > module')
>
> > $ cat client.py
> > import logging
> > import logging.handlers
> > from server import Server
>
> > class Client():
> >     def __init__(self):
> >         self.client_logger = logging.getLogger("client")
> >         self.client_logger.setLevel(logging.DEBUG)
> >         h = logging.FileHandler("client.log")
> >         h.setLevel(logging.DEBUG)
> >         formatter = logging.Formatter("%(asctime)s %(name)-12s %
> > (levelname)-8s %(message)s")
> >         h.setFormatter(formatter)
> >         self.client_logger.addHandler(h)
> >         self.client_logger.propagate = 0
>
> >     def client_test(self):
> >         self.client_logger.warning("This message comes from Client
> > module")
>
> > if __name__ == "__main__":
> >     ser = Server()
> >     cli = Client()
> >     ser.util()
> >     cli.client_test()
>
> > $ rm client.log ; python client.py ; cat client.log
> > 2009-11-24 16:06:35,710 client       WARNING  This message comes from
> > Server module
> > 2009-11-24 16:06:35,710 client       WARNING  This message comes from
> > Server module
> > 2009-11-24 16:06:35,710 client       WARNING  This message comes from
> > Client module
> > 2009-11-24 16:06:35,710 client       WARNING  This message comes from
> > Client module
>
> > $
>
> Rename logger in server.py to server:
> self.client_logger = logging.getLogger("server")
>
> Rerun, you should get sth. like this:
> $ cat client.log
> 2009-11-24 16:06:54,990 server       WARNING  This message comes from Server module
> 2009-11-24 16:06:54,990 client       WARNING  This message comes from Client module
>
> --
> Soltys
>
> "Free software is a matter of liberty not price"- Hide quoted text -
>
> - Show quoted text -

Many thanks Soltys, that did the trick (actually, no need for setting
propagate to 0), namely,

$ cat client.py
import logging
import logging.handlers
from server import Server

class Client():
    def __init__(self):
        self.client_logger = logging.getLogger("client")
        self.client_logger.setLevel(logging.DEBUG)
        h = logging.FileHandler("client.log")
        h.setLevel(logging.DEBUG)
        formatter = logging.Formatter("%(asctime)s %(name)-12s %
(levelname)-8s %(message)s")
        h.setFormatter(formatter)
        self.client_logger.addHandler(h)

    def client_test(self):
        self.client_logger.warning("This message comes from Client
module")

if __name__ == "__main__":
    ser = Server()
    cli = Client()
    ser.util()
    cli.client_test()

$ cat server.py
import logging
import logging.handlers

class Server():
    def __init__(self):
        self.client_logger = logging.getLogger("server")
        self.client_logger.setLevel(logging.DEBUG)
        h = logging.FileHandler("client.log")
        h.setLevel(logging.DEBUG)
        formatter = logging.Formatter("%(asctime)s %(name)-12s %
(levelname)-8s %(message)s")
        h.setFormatter(formatter)
        self.client_logger.addHandler(h)

    def util(self):
        self.client_logger.warning('This message comes from Server
module')

$ rm client.log ; python client.py ; cat client.log
2009-11-24 17:13:15,989 server       WARNING  This message comes from
Server module
2009-11-24 17:13:15,989 client       WARNING  This message comes from
Client module




More information about the Python-list mailing list