Advise on using logging.getLogger needed.

Jean-Michel Pichavant jeanmichel at sequans.com
Mon Oct 3 11:12:44 EDT 2011


Steven W. Orr wrote:
> I hope I don't sound like I'm ranting :-(
>
> I have created a module (called xlogging) which sets up logging the way I want
> it. I found out that if I set up my logger without a name, then it gets
> applied to every logger that is referenced by every module that ever gets
> imported.
>
> The problem is that I must call xlogging.getLogger or logging.getLogger in all
> other modules using the name of the root logger, and I don't know what that
> name is.
>
> I want the name of the root logger to be the name of the running program, so
> in my setup, I say
>
>             pname = sys.argv[0]
>             try:
>                 rslash = pname.rindex('/')
>             except ValueError:
>                 pass
>             else:
>                 pname = pname[rslash + 1:]
>
>             try:
>                 dot_py = pname.rindex('.py')
>             except ValueError:
>                 pass
>             else:
>                 pname = pname[0:dot_py]
>
>   
This is also written

pname, _ = os.path.splitext(os.path.basename(sys.argv[0]))


> and then I say
>
>             logger = logging.getLogger(pname)
>
> My problem is that I just want the modules that I write, to be able to get the
>  named root logger and still be able to refer to possible sub-loggers.
>
> So, let's say I run program foo. At some point in my mail setup, I set the
> configuration for the foo logger. I'd like my xlogging module to supply a
> getLogger function such that if I don't supply any arguments, it will return
> the logger that would normally be returned by logging.getLogger(pname).
>
> Also, part of the reason I'm confused is because foo calls m1 and m2 and they
> want to say
>
> logger = xlogging.getLogger(MaybeWithAnArg?)
>
> at the top of their code. This means that the import statement for m1 and m2
> are getting the calls to getLogger executed before I get the chance to set
> things up.
>
> I am running 2.6, so I don't have access to logging.getChild, but I'm not
> clear that I even want that.
>
> My modules are used by multiple programs. Does this mean that I should simply
> use __name__ all the time? (That seems inelegant, no?)
>
> If I'm making sense, is there a way to do this?
>
>
>   
To be honest, I'm not sure I've understood exactly what you're trying to 
do, but I have the feeling you're just trying  to the usual stuff with 
the wrong method.

I would advise to drop your xlogging module, it just add some confusion. 
Maybe you'll be able to add it later on.

 * in libraries/modules, you never configure any logger. The 
configuration of the logger is let to the main program.
  -> only instanciate a logger, something like
       logger = logging.getLogger(__name__)
   Then use it, you don't care about what becomes of the logs, it's up 
to the program using the module to decide

 * From the main program, you can create a logger for your application, 
but you still configure the root logger, only the root logger will grab 
the log event from other modules.


m1 module file:

import logging

_logger=logging.getLogger(__name__)

def func():
    _logger.debug('foo')


myApp file:
import m1
import logging
_logger = logging.getLogger('MyApp')

def run():
    _logger.info('bar')
    m1.func()

if __name__=='__main__':
    # here you configure the logs by configuring the *root* logger
    rootLogger = logging.getLogger() # no name => root logger
    rootLogger.handlers = [] # clean up the current configuration
    rootLogger.addHandler(logging.StreamHandler())
    rootLogger.handlers[-1].setFormatter(logging.Formatter('%(name)s - 
%(levelname)s:%(message)s'))
    rootLogger.setLevel(level=logging.DEBUG)
    run()

you should get something like
MyApp - INFO:bar
m1 - DEBUG:foo

Hope it helps,

JM



More information about the Python-list mailing list