Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redefining logging root logger

Tags:

python

logging

At my current project there are thousand of code lines which looks like this:

logging.info("bla-bla-bla")

I don't want to change all these lines, but I would change log behavior. My idea is changing root logger to other Experimental logger, which is configured by ini-file:

[loggers]
keys =  Experimental

[formatter_detailed]
format = %(asctime)s:%(name)s:%(levelname)s %(module)s:%(lineno)d:  %(message)s

[handler_logfile]
class = FileHandler
args = ('experimental.log', 'a')
formatter = detailed

[logger_Experimental]
level = DEBUG
qualname = Experimental
handlers = logfile
propagate = 0

Now setting the new root logger is done by this piece of code:

logging.config.fileConfig(path_to_logger_config)
logging.root = logging.getLogger('Experimental')

Is redefining of root logger safe? Maybe there is more convenient way?

I've tried to use google and looked through stackoverflow questions, but I didn't find the answer.

like image 422
Aliaksei Ramanau Avatar asked Sep 15 '11 09:09

Aliaksei Ramanau


People also ask

What does logging getLogger (__ Name __) do?

getLogger(name) is typically executed. The getLogger() function accepts a single argument - the logger's name. It returns a reference to a logger instance with the specified name if provided, or root if not. Multiple calls to getLogger() with the same name will return a reference to the same logger object.

What is root logger in Python?

On top of the hierarchy is the root logger, which can be accessed via logging. root. This logger is called when methods like logging. debug() is used. By default, the root log level is WARN, so every log with lower level (for example via logging.info("info") ) will be ignored.


1 Answers

You're advised not to redefine the root logger in the way you describe. In general you should only use the root logger directly for small scripts - for larger applications, best practice is to use

logger = logging.getLogger(__name__)

in each module where you use logging, and then make calls to logger.info() etc.

If all you want to do is to log to a file, why not just add a file handler to the root logger? You can do using e.g.

if __name__ == '__main__':
    logging.basicConfig(filename='experimental.log', filemode='w')
    main() # or whatever your main entry point is called

or via a configuration file.

Update: When I say "you're advised", I mean by me, here in this answer ;-) While you may not run into any problems in your scenario, it's not good practice to overwrite a module attribute which hasn't been designed to be overwritten. For example, the root logger is an instance of a different class (which is not part of the public API), and there are other references to it in the logging machinery which would still point to the old value. Either of these facts could lead to hard-to-debug problems. Since the logging package allows a number of ways of achieving what you seem to want (seemingly, logging to a file rather than the console), then you should use those mechanisms that have been provided.

like image 162
Vinay Sajip Avatar answered Sep 21 '22 03:09

Vinay Sajip