Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Naming Python loggers

In Django, I've got loggers all over the place, currently with hard-coded names.

For module-level logging (i.e., in a module of view functions) I have the urge to do this.

log = logging.getLogger(__name__) 

For class-level logging (i.e., in a class __init__ method) I have the urge to do this.

self.log = logging.getLogger("%s.%s" % (     self.__module__, self.__class__.__name__)) 

I'm looking for second opinions before I tackle several dozen occurrences of getLogger("hard.coded.name").

Will this work? Anyone else naming their loggers with the same unimaginative ways?

Further, should I break down and write a class decorator for this log definition?

like image 340
S.Lott Avatar asked Dec 30 '08 19:12

S.Lott


People also ask

What is logger logging getLogger (__ Name __?

logger = logging.getLogger(__name__) This means that logger names track the package/module hierarchy, and it's intuitively obvious where events are logged just from the logger name. Sounds like good advice.

What are logging levels in Python?

There are six log levels in Python; each level is associated with an integer that indicates the log severity: NOTSET=0, DEBUG=10, INFO=20, WARN=30, ERROR=40, and CRITICAL=50. All the levels are rather straightforward (DEBUG < INFO < WARN ) except NOTSET, whose particularity will be addressed next.

What does logger getLogger do Python?

Python logging getLogger The getLogger returns a logger with the specified name. If no name is specified, it returns the root logger. It is a common practice to put the module name there with __name__ . All calls to this function with a given name return the same logger instance.


1 Answers

I typically don't use or find a need for class-level loggers, but I keep my modules at a few classes at most. A simple:

import logging LOG = logging.getLogger(__name__) 

At the top of the module and subsequent:

LOG.info('Spam and eggs are tasty!') 

from anywhere in the file typically gets me to where I want to be. This avoids the need for self.log all over the place, which tends to bother me from both a put-it-in-every-class perspective and makes me 5 characters closer to 79 character lines that fit.

You could always use a pseudo-class-decorator:

>>> import logging >>> class Foo(object): ...     def __init__(self): ...             self.log.info('Meh') ...  >>> def logged_class(cls): ...     cls.log = logging.getLogger('{0}.{1}'.format(__name__, cls.__name__)) ...  >>> logged_class(Foo) >>> logging.basicConfig(level=logging.DEBUG) >>> f = Foo() INFO:__main__.Foo:Meh 
like image 152
cdleary Avatar answered Sep 21 '22 01:09

cdleary