Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the name of the class containing a logging call in Python?

Tags:

If I want the function name I can simply include %(funcName)s in the Formatter. But how do I get the name of the class containing the logging call instead?

I've gone through the documentation for logging, but I can't find any mentioning of it.

like image 528
c00kiemonster Avatar asked Sep 12 '11 08:09

c00kiemonster


People also ask

How do I find the name of a class in Python?

To get the class name of an instance in Python: Use the type() function and __name__ to get the type or class of the Object/Instance. Using the combination of the __class__ and __name__ to get the type or class of the Object/Instance.

What is logger logging getLogger (__ name __)?

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.

How do I print logging INFO in Python?

Python - Print Logs in a File. If you want to print python logs in a file rather than on the console then we can do so using the basicConfig() method by providing filename and filemode as parameter. The format of the message can be specified by using format parameter in basicConfig() method.


2 Answers

For a rather easy, pythonic way to get the class name to output with your logger, simply use a logging class.

import logging   # Create a base class class LoggingHandler:     def __init__(self, *args, **kwargs):         self.log = logging.getLogger(self.__class__.__name__)   # Create test class A that inherits the base class class testclassa(LoggingHandler):     def testmethod1(self):         # call self.log.<log level> instead of logging.log.<log level>         self.log.error("error from test class A")   # Create test class B that inherits the base class class testclassb(LoggingHandler):     def testmethod2(self):         # call self.log.<log level> instead of logging.log.<log level>         self.log.error("error from test class B")   testclassa().testmethod1() testclassb().testmethod2() 

By naming the logger as above, the %(name)s will be the name of your class

example output

$ python mymodule.py [2016-02-03 07:12:25,624] ERROR [testclassa.testmethod1:29] error from test class A [2016-02-03 07:12:25,624] ERROR [testclassb.testmethod2:36] error from test class B 

Alternative(s)

Non-inheritance

import logging   def log(className):     return logging.getLogger(className)   class testclassa:     def testmethod1(self):         log(self.__class__.__name__).error("error from test class A")   class testclassb:     def testmethod2(self):         log(self.__class__.__name__).error("error from test class B")   testclassa().testmethod1() testclassb().testmethod2() 
like image 52
kylehuff Avatar answered Oct 16 '22 00:10

kylehuff


There is almost certainly a better way of doing this, but until someone points that out, this will work:

import inspect  class testclass:     def testmethod(self):         log()  def log():     stack = inspect.stack()     try:         print "Whole stack is:"         print "\n".join([str(x[4]) for x in stack])         print "-"*20         print "Caller was %s" %(str(stack[2][4]))     finally:         del stack  testclass().testmethod() 

The output of this is the following:

Whole stack is: ['    stack = inspect.stack()\n'] ['        f()\n'] ['testclass().testmethod()\n'] ['                exec code in self.locals\n'] ['            ret = method(*args, **kwargs)\n'] None -------------------- Caller was ['testclass().testmethod()\n'] 
like image 28
ed. Avatar answered Oct 16 '22 00:10

ed.