Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging in classes - Python [duplicate]

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 :

  • to use the same logger everywhere. But my classes are used by a framework, I don't have a single entrypoint where I could define a main logger. If so, how should I create it and add handlers ?
  • to use one logger per file. Should I create it as a class attribute, and adding handlers only the first time the class is instantiated ? Or put it with the imports before the class definition ? This tutorial told me not to, but I don't really get why.

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 ?

like image 947
MeanStreet Avatar asked May 17 '18 12:05

MeanStreet


People also ask

Why does logger print twice in Python?

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.

Is logging in Python thread-safe?

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.

How do you use logging class in Python?

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.

How do I create a multiple logging level in Python?

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.


1 Answers

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
like image 81
Hai Vu Avatar answered Sep 18 '22 01:09

Hai Vu