Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it good design to create a module-wide logger in python?

When coding python, I use the logging module a lot.

After some bad experiences and reading articles like this one, I try to prevent import-time executed code wherever possible.

However, for the sake of simplicity, I tend to get my logging object right at the beginning of the module file:

# -*- coding: utf-8 -*-
import logging
logger = logging.getLogger('product.plugin.foo.bar')

This way, my logger is globally accessible and I can just write "logger.error()" anywhere. The alternative is to create it class-wide:

class Bar(object):
    logger = logging.getLogger('product.plugin.foo.bar')

However, now I have to type the Class name everytime. To prevent typing the class name, I am tempted to use "self" instead, which will fail in static methods.

    def my_method(self):
        Bar.logger.error('foo')

    def my_method_2(self):
        self.logger.error('foo') # ok...

    @staticmethod
    def my_method_2():
        self.logger.error('foo') # boom!

So, at first, it looks like creating the logger object module-wide seems like the right thing to do - still it feels like I could end up in import-related trouble when doing it like this...

like image 633
c089 Avatar asked Aug 17 '10 12:08

c089


People also ask

Is logging module thread safe?

Preliminary #2: Logging Is Thread-Safe, but Not Process-Safe You can see in the module source code that _acquireLock() and _releaseLock() are ubiquitous to the module and its classes.

Does Python logging module use log4j?

The inbuilt logging module in python requires some handful of lines of code to configure log4j-like features viz - file appender, file rotation based on both time & size. For one-liner implementation of the features in your code, you can use the package autopylogger .


1 Answers

It's fine. I even use the same variable name logger. Any logging is better than no logging, but I find it's nice practise to only expose the logger variable, keep the module hidden away so your code only references the logger, and hence the namespace you've designated for the module.

If you later need to refine the namespaces for code within the module, you can use self.logger within those classes, or shadow the global logger where necessary.

Update0

__all__ = [anything but logger]
import logging
logger = logging.getLogger("why.is.this.method.still.java.camel.case")
del logging

Taking note of S.Lott's contribution below. Also note that generally you don't want from x import * anyway.

like image 170
Matt Joiner Avatar answered Sep 27 '22 23:09

Matt Joiner