Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Logging in Class with classmethods / staticmethods

I want to do logging in objects & classes which are spread over several modules.

Usually, I'm checking in the constructor of a class if there is an exisiting (root) logger instance and pass it then into the object.

import logging
from logging import config

class TestClass(object):

    def __init__(self, logger=None):
         self.logger = logger or logging.getLogger(self.__class__.__name__)

    def bar(self):
         self.logger.info("Hi, Bar")

but how do I make this logger available for my utility class which contains only ClassMethods / Staticmethods?

I'm looking for smth like this:

class TestClass(object):

    def __init__(cls, logger=None):
         cls.logger = logger or logging.getLogger(cls.__class__.__name__)

    @classmethod
    def foo(cls):
        cls.logger.info("Hi, Foo")

I know that the code above doesn't work, but I hope it makes clear what I'm looking for.

Any idea / best practices are appreciated!

like image 524
dh1tw Avatar asked Aug 11 '26 06:08

dh1tw


1 Answers

def __init__(self, logger=None):
     self.__class__.logger = logger or logging.getLogger(cls.__class__.__name__)

Of course, this will bind a new logger onto the class every time you create a new instance of the class which is likely not what you want (or maybe it is ... I'm not sure)1

Another approach which I don't recommend would be to use a metaclass to get the logger2:

import logging

class Foo(type):

    @property
    def logger(cls):
        try:
            return cls._logger
        except AttributeError:
            cls._logger = logging.getLogger(cls.__name__)
            return cls._logger

class Bar(object):
    __metaclass__ = Foo


print Bar.logger

print Bar.logger is Bar.logger  # verify we only created one logger instance.

# careful though, the following DOESN'T work:
print Bar().logger  # AttributeError :-P

1Generally I would consider a class comprised of mostly class/static methods to be a somewhat fishy design. Without knowing the actual code though, it's hard to provide better advice...

2I'm mostly posting this so that I can remember how to do this in other applications... I don't recommend it's use here...

like image 173
mgilson Avatar answered Aug 13 '26 21:08

mgilson