I'm trying to use Python's logging
module, and have questions on the best way to use it.
I define several classes, want to write logs and be able to set the level of all of them at the same time. I tried :
Thanks for any hints. I've found lots of docs on the basic way to use a logger, but not much on how to use it in classes.
EDIT: I don't think it's a duplicate of the link below. The accepted answer explains how to load the config in a main program, and then use it in all the modules. But what if I don't have a main program ? Where do I define it ?
The reason is that, when we use logging. getLogger() without any argument, we will get the root logger. my_logger in logger.py is thus a child logger of this root logger. By default, child logger messages will be propagated to the logger in the upper hierarchy.
Although logging module is thread-safe, it's not process-safe. If you want multiple processes to write to the same log file, then you have to manually take care of the access to your file.
Logger class methodsTo get an instance of the Logger class we have to call the function getLogger(logger_name) . Once we have a Logger instance we can call the main methods: debug(message) : to log a message at the debug level. info(message) : to log a message at the info level.
You can set a different logging level for each logging handler but it seems you will have to set the logger's level to the "lowest". In the example below I set the logger to DEBUG, the stream handler to INFO and the TimedRotatingFileHandler to DEBUG. So the file has DEBUG entries and the stream outputs only INFO.
If you create logger objects in separate files, but with the same name. They will share all the attributes. In fact, they are the same logger. The logging
module also allow the creation of logger objects in a hierarchical order. For example, a logger with name spam.mod2 is a sub logger of spam in which it takes on all of spam's attributes, but can also be customized.
To put it into concrete example. I am going to create a simple project which has 2 modules: mod1
and mod2
. A common module setup_logger
is used to create a single logger. Finally, I have a main
module, which drives the whole system.
The setup_logger
module will create a new logger object and name it spam. The code can be simple as listed, or as complex as you want.
# setup_logger.py
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('spam')
Next, mod1
being lazy, just reuse that logger object:
# mod1.py
from setup_logger import logger
class Class1(object):
def do_something(self):
logger.info('Class1: doing something')
mod2
creates its own logger object, but still need to import setup_logger
so that the spam logger is created. mod2
creates a sub logger by naming it spam.mod2:
# mod2.py
import logging
import setup_logger
# mod2 creates its own logger, as a sub logger to 'spam'
logger = logging.getLogger('spam.mod2')
class Class2:
def do_something(self):
logger.info('Class2: doing something')
Finally, main
will put all of them together:
# main.py
import mod1
import mod2
if __name__ == '__main__':
object1 = mod1.Class1()
object1.do_something()
object2 = mod2.Class2()
object2.do_something()
Output:
INFO:spam:Class1: doing something
INFO:spam.mod2:Class2: doing something
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With