Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the same logging format for all handlers?

I am using .setFormatter() to set the same logging.Formatter() on each of my handlers.

Is there a way to set a global default format?

Alternatively - is it possible to iterate though the handlers already added via .addHandler() to a logger ?

Another question mentions what the format is, but not how to set it.

like image 286
WoJ Avatar asked Oct 03 '17 15:10

WoJ


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 are handlers in logging?

The log handler is the component that effectively writes/displays a log: Display it in the console (via StreamHandler), in a file (via FileHandler), or even by sending you an email via SMTPHandler, etc. Each log handler has 2 important fields: A formatter which adds context information to a log.


1 Answers

The intended way is to attach the formatter to each handler as you're creating them.

Since you're supposed to set up logging destinations in one, central place at the start of the main program, this isn't so taxing to do.

E.g. this is the stock logging set-up code that I use in my scripts that are to be run autonomously:

# set up logging #####################################
import sys,logging,logging.handlers,os.path
log_file=os.path.splitext(__file__)[0]+".log"
l = logging.getLogger()
l.setLevel(logging.DEBUG)
f = logging.Formatter('%(asctime)s %(process)d:%(thread)d %(name)s %(levelname)-8s %(message)s')
h=logging.StreamHandler(sys.stdout)
h.setLevel(logging.NOTSET)
h.setFormatter(f)
l.addHandler(h)
h=logging.handlers.RotatingFileHandler(log_file,maxBytes=1024**2,backupCount=1)
h.setLevel(logging.NOTSET)
h.setFormatter(f)
l.addHandler(h)
del h,f
#hook to log unhandled exceptions
def excepthook(type,value,traceback):
    logging.error("Unhandled exception occured",exc_info=(type,value,traceback))
    #Don't need another copy of traceback on stderr
    if old_excepthook!=sys.__excepthook__:
        old_excepthook(type,value,traceback)
old_excepthook = sys.excepthook
sys.excepthook = excepthook
del excepthook,log_file
# ####################################################

There are other methods but each has a downside:

  • Each logger has an undocumented <logger>.handlers list, but it only lists handlers connected to that logger directly. So, you need to iterate over this list for all loggers you have if you have multiple.
  • There is a global undocumented logging._handlerList (references to all handlers are kept there to shut them down at exit). Likewise, that is an implementation detail.
  • Finally, you can override a handler's init logic by

    • replacing __init__ methods of Handler and/or subclass (that will affect everything else that uses logging), or by
    • subclassing/addin a mixin to the required classes.

    That is probably an overkill.

like image 53
ivan_pozdeev Avatar answered Oct 02 '22 10:10

ivan_pozdeev