logging

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Baurzhan Ismagulov

    #1

    logging

    Hello all,

    I want that each module has its own logger. I've defined the following
    config file:

    [formatters]
    keys=f01

    [handlers]
    keys=console

    [loggers]
    keys=root,l01

    [formatter_f01]
    format=%(name)s : %(message)s

    [handler_console]
    class=StreamHan dler
    args=[]
    formatter=f01

    [logger_root]
    level=CRITICAL
    handlers=consol e

    [logger_l01]
    level=DEBUG
    qualname=l01
    handlers=consol e


    I use it like this:

    import logging
    import logging.config

    logging.config. fileConfig('a.c onf')
    log = logging.getLogg er('l01')
    log.debug('zzz' )


    I want logger_root to go to /dev/null, so I've configured it with level
    CRITICAL. My understanding is that in this way debug messages are not
    printed on logger_root's handler. However, running the program results
    in the message being printed twice. What is the problem?


    Thanks in advance,
    Baurzhan.
  • Vinay Sajip

    #2
    Re: logging

    Baurzhan Ismagulov wrote:
    [color=blue]
    > Hello all,
    >
    > I want that each module has its own logger. I've defined the following
    > config file:
    >
    > [logger_root]
    > level=CRITICAL
    > handlers=consol e
    >
    > [logger_l01]
    > level=DEBUG
    > qualname=l01
    > handlers=consol e
    >[/color]
    [color=blue]
    > I want logger_root to go to /dev/null, so I've configured it with level
    > CRITICAL. My understanding is that in this way debug messages are not
    > printed on logger_root's handler. However, running the program results
    > in the message being printed twice. What is the problem?[/color]

    You've defined the handler against both the root logger and l01. You
    only need it configured for the root logger - events passed to l01 will
    be passed to all handlers up the hierarchy. So remove the
    "handlers=conso le" line from [logger_l01] and it should print the
    message just once.

    Vinay Sajip

    Comment

    • Baurzhan Ismagulov

      #3
      Re: logging

      Hello Vinay,

      On Tue, May 23, 2006 at 04:13:38PM -0700, Vinay Sajip wrote:[color=blue][color=green]
      > > [logger_root]
      > > level=CRITICAL
      > > handlers=consol e
      > >
      > > [logger_l01]
      > > level=DEBUG
      > > qualname=l01
      > > handlers=consol e
      > >
      > > I want logger_root to go to /dev/null, so I've configured it with level
      > > CRITICAL. My understanding is that in this way debug messages are not
      > > printed on logger_root's handler. However, running the program results
      > > in the message being printed twice. What is the problem?[/color]
      >
      > You've defined the handler against both the root logger and l01. You
      > only need it configured for the root logger - events passed to l01 will
      > be passed to all handlers up the hierarchy. So remove the
      > "handlers=conso le" line from [logger_l01] and it should print the
      > message just once.[/color]

      Thanks for the idea! I think this should work for the example I sent.
      However, I have more than one module, and I want to log only l01. How
      can I do that?

      Thanks in advance,
      Baurzhan.

      Comment

      • Vinay Sajip

        #4
        Re: logging


        Baurzhan Ismagulov wrote:
        [color=blue]
        > Thanks for the idea! I think this should work for the example I sent.
        > However, I have more than one module, and I want to log only l01. How
        > can I do that?
        >[/color]

        I don't know what your logger hierarchy looks like: you could perhaps
        log to child loggers of l01 ("l01.XXX"), or set all other loggers you
        use to have a CRITICAL level, or filter them using a filter which
        filters out everything.

        Regards,

        Vinay

        Comment

        • Baurzhan Ismagulov

          #5
          Re: logging

          Hello Vinay,

          On Thu, May 25, 2006 at 10:14:00AM -0700, Vinay Sajip wrote:[color=blue]
          > I don't know what your logger hierarchy looks like: you could perhaps
          > log to child loggers of l01 ("l01.XXX"), or set all other loggers you
          > use to have a CRITICAL level, or filter them using a filter which
          > filters out everything.[/color]

          Ok, here is my hierarchy:

          [formatters]
          keys=f01

          [handlers]
          keys=console

          [loggers]
          keys=root,l01,l 02

          [formatter_f01]
          format=%(name)s : %(message)s

          [handler_console]
          class=StreamHan dler
          args=[]
          formatter=f01

          [logger_root]
          level=CRITICAL
          handlers=consol e

          [logger_l01]
          level=DEBUG
          qualname=l01
          handlers=consol e

          [logger_l02]
          level=CRITICAL
          qualname=l02
          handlers=consol e


          The program is:

          import logging
          import logging.config

          logging.config. fileConfig('a.c onf')
          log1 = logging.getLogg er('l01')
          log2 = logging.getLogg er('l02')
          log1.debug('zzz ')
          log2.debug('qqq ')


          With the config above, I expect that zzz gets printed, and qqq doesn't.
          When I run the script, zzz is printed twice, and qqq isn't. I want that
          zzz is printed once. How do I do that? I can add a filter if this can't
          be done otherwise, however, I'm at the moment reluctant to do that since
          I don't see why CRITICAL for root passes zzz through and drops qqq
          correctly for l02.


          Thanks in advance,
          Baurzhan.

          Comment

          • Vinay Sajip

            #6
            Re: logging

            Baurzhan Ismagulov wrote:
            [color=blue]
            > Hello Vinay,
            > Ok, here is my hierarchy:
            >[/color]
            [snip][color=blue]
            > [handlers]
            > keys=console[/color]
            [snip][color=blue]
            > [logger_root]
            > level=CRITICAL
            > handlers=consol e
            >
            > [logger_l01]
            > level=DEBUG
            > qualname=l01
            > handlers=consol e
            >
            > [logger_l02]
            > level=CRITICAL
            > qualname=l02
            > handlers=consol e[/color]
            [snip]
            [color=blue]
            > With the config above, I expect that zzz gets printed, and qqq doesn't.
            > When I run the script, zzz is printed twice, and qqq isn't. I want that
            > zzz is printed once. How do I do that? I can add a filter if this can't
            > be done otherwise, however, I'm at the moment reluctant to do that since
            > I don't see why CRITICAL for root passes zzz through and drops qqq
            > correctly for l02.[/color]

            Did you try removing the handler from l01, as I suggested in an earlier
            reply? The config above still has the console handler attached to root,
            l01 and l02. The reason that zzz is printed twice is that when a logger
            decides to process an event, it is passed to handlers attached to
            ancestor loggers (unless propagate is set to 0 - but this is not the
            normal situation). So, log1 is deciding to process the event (based on
            the level), and passing it to its own handlers (l01->console) and then
            to its ancestor loggers' handlers (root->console). Remove the handlers
            from l01 and l02 and try again.

            Comment

            • ibr@radix50.net

              #7
              Re: logging

              Hello Vinay,

              On Tue, May 30, 2006 at 09:13:25AM -0700, Vinay Sajip wrote:[color=blue]
              > [snip][color=green]
              > > [handlers]
              > > keys=console[/color]
              > [snip][color=green]
              > > [logger_root]
              > > level=CRITICAL
              > > handlers=consol e
              > >
              > > [logger_l01]
              > > level=DEBUG
              > > qualname=l01
              > > handlers=consol e
              > >
              > > [logger_l02]
              > > level=CRITICAL
              > > qualname=l02
              > > handlers=consol e[/color]
              > [snip][/color]
              ....[color=blue][color=green]
              > > When I run the script, zzz is printed twice, and qqq isn't. I want that
              > > zzz is printed once.[/color][/color]
              ....[color=blue]
              > Did you try removing the handler from l01, as I suggested in an earlier
              > reply?[/color]

              I had removed the whole line, and it complained about the missing
              handlers line. Now I've tried with 'handlers=', this seems to work.
              Thanks much!

              [color=blue]
              > The reason that zzz is printed twice is that when a logger decides to
              > process an event, it is passed to handlers attached to ancestor
              > loggers (unless propagate is set to 0 - but this is not the normal
              > situation). So, log1 is deciding to process the event (based on the
              > level), and passing it to its own handlers (l01->console) and then to
              > its ancestor loggers' handlers (root->console).[/color]

              Hmm, log1 decides once whether to print an event, and after that it gets
              printed in log1 and all its ancestors, regardless of their level? I find
              this quite counter-intuitive. I'd instead expect that each logger
              decides whether to print an event according to its own level. Could you
              give an example why one would want the python behavior?


              With kind regards,
              Baurzhan.

              Comment

              • Vinay Sajip

                #8
                Re: logging

                ibr@radix50.net wrote:
                [color=blue]
                > Hello Vinay,
                >
                > Hmm, log1 decides once whether to print an event, and after that it gets
                > printed in log1 and all its ancestors, regardless of their level? I find
                > this quite counter-intuitive. I'd instead expect that each logger
                > decides whether to print an event according to its own level. Could you
                > give an example why one would want the python behavior?[/color]

                Loggers are hierarchical for a reason - not just randomly named
                channels. Just as it is generally useful to develop a system by
                modularising it into subsystems, packages, modules, etc. so it is
                useful when logging to follow a parallel hierarchy. The audiences for
                the logging events are orthogonal to the events themselves, and the way
                the logging module is organised reflects good practice as determined by
                practical experience over a period of time. The approach you're
                questioning is not specific to Python - log4j (which inspired Python's
                logging), and the logging built into Java 1.4, also work this way.
                Practically, this makes configuration a lot simpler; if I want to log
                everything to console, I just attach a handler to the root logger, and
                I never have to worry about attaching to every single logger. (Logger
                names are generally not cast in stone - I might break down a module's
                logic into smaller pieces and thus introduce new logger names to
                describe events in the refactored module. I certainly don't want to
                change my logging configuration every time I refactor my code.)

                May I suggest you review the log4j documentation to get a better
                exposition of the principles which govern the design of such logging
                systems.

                Comment

                • Baurzhan Ismagulov

                  #9
                  Re: logging

                  Hello Vinay,

                  On Wed, May 31, 2006 at 03:05:13PM -0700, Vinay Sajip wrote:[color=blue][color=green]
                  > > Hmm, log1 decides once whether to print an event, and after that it gets
                  > > printed in log1 and all its ancestors, regardless of their level? I find
                  > > this quite counter-intuitive. I'd instead expect that each logger
                  > > decides whether to print an event according to its own level. Could you
                  > > give an example why one would want the python behavior?[/color]
                  >
                  > Loggers are hierarchical for a reason - not just randomly named
                  > channels. ...[/color]

                  Thanks for the explanation! Please note that I am not questioning the
                  usefulness of hierarchical logging -- I think it's a Good Thing. What I
                  can't understand is the motivation for the single place of decision
                  whether a message should be printed ("is enabled" in log4j terms) or
                  not.

                  Consider the following scenario: root is CRITICAL, l01 is DEBUG, a debug
                  message is logged on l01. l01 decides that the message should be
                  printed, and _both_ root and l01 print it. Now, it is good that the
                  message is propagated to root, but why doesn't root decide for itself
                  whether to print it or not?

                  For instance, I log root to syslog and have only critical messages
                  there. I log l01 to console to debug. I want that my message to l01 is
                  not printed by root since its level is CRITICAL. This is why I want that
                  each logger re-evaluates the message level for itself. Could you perhaps
                  give a useful example why one could want loggers to decide once?


                  And another thing I couldn't find how to do: I want to have several
                  debug levels. I can log messages without problems, but numeric values in
                  the configuration file cause error messages during
                  logging.config. fileConfig. Can I specify numeric values in the config
                  file?


                  With kind regards,
                  Baurzhan.

                  Comment

                  • Vinay Sajip

                    #10
                    Re: logging

                    Hello Baurzhan,
                    [color=blue]
                    > Consider the following scenario: root is CRITICAL, l01 is DEBUG, a debug
                    > message is logged on l01. l01 decides that the message should be
                    > printed, and _both_ root and l01 print it. Now, it is good that the
                    > message is propagated to root, but why doesn't root decide for itself
                    > whether to print it or not?[/color]

                    It's not propagated to the root logger (or to ancestor loggers in
                    general) - just to the handlers associated with ancestor loggers.
                    [color=blue]
                    > For instance, I log root to syslog and have only critical messages
                    > there. I log l01 to console to debug. I want that my message to l01 is
                    > not printed by root since its level is CRITICAL. This is why I want that
                    > each logger re-evaluates the message level for itself. Could you perhaps
                    > give a useful example why one could want loggers to decide once?[/color]

                    You can set levels on handlers as well as loggers. So if you add a
                    syslog handler to the root and set its level to CRITICAL, only CRITICAL
                    messages are sent to syslog.
                    [color=blue]
                    > And another thing I couldn't find how to do: I want to have several
                    > debug levels. I can log messages without problems, but numeric values in
                    > the configuration file cause error messages during
                    > logging.config. fileConfig. Can I specify numeric values in the config
                    > file?[/color]

                    You should use addLevelName to add custom levels. You can do e.g.

                    logging.MYCUSTO MLEVEL = 25
                    logging.addLeve lName(logging.M YCUSTOMLEVEL, "MYCUSTOMLEVEL" )

                    and then reference MYCUSTOMLEVEL in the config file.

                    Regards,

                    Vinay

                    Comment

                    • Baurzhan Ismagulov

                      #11
                      Re: logging

                      Hello Vinay,

                      On Sun, Jun 04, 2006 at 05:23:55AM -0700, Vinay Sajip wrote:[color=blue]
                      > It's not propagated to the root logger (or to ancestor loggers in
                      > general) - just to the handlers associated with ancestor loggers.[/color]
                      ....[color=blue]
                      > You can set levels on handlers as well as loggers. So if you add a
                      > syslog handler to the root and set its level to CRITICAL, only CRITICAL
                      > messages are sent to syslog.[/color]
                      ....[color=blue]
                      > logging.MYCUSTO MLEVEL = 25
                      > logging.addLeve lName(logging.M YCUSTOMLEVEL, "MYCUSTOMLEVEL" )[/color]

                      Thanks much!

                      With kind regards,
                      Baurzhan.

                      Comment

                      Working...