WoJ
WoJ

Reputation: 29987

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.

Upvotes: 7

Views: 7267

Answers (2)

ivan_pozdeev
ivan_pozdeev

Reputation: 36018

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.

Upvotes: 4

Vinay Sajip
Vinay Sajip

Reputation: 99355

If you have a number of handlers, you're advised to configure logging using the logging.config.dictConfig() API. This other answer shows how to configure formatters for handlers; you may be able to adapt it to your needs.

Upvotes: 0

Related Questions