20 Customizing handlers with dictConfig() 30 (continues on next page) There are times when you want to customize logging handlers in particular ways, and if you use dictConfig() you may be able to do this without subclassing. As an example, consider that you may want to set the ownership of a log file. On POSIX, this is easily done using$_{shutil.chown()}$ , but the file handlers in the stdlib don’t offer built-in support. You can customize handler creation using a plain function such as: You can then specify, in a logging configuration passed to$_{dictConfig()}$ , that a logging handler be created by calling this function: In this example I am setting the ownership using the$_{pulse}$user and group, just for the purposes of illustration. Putting it together into a working script,$_{chowntest.py}$ : import logging , logging.config , os , shutil def owned_file_handler (filename, mode ='a', encoding= None , owner= None ): if owner: if not os.path.exists(filename): open(filename, 'a').close() shutil.chown(filename, *owner) return logging.FileHandler(filename, mode, encoding) LOGGING ={ 'version':1, def owned_file_handler (filename, mode ='a', encoding= None , owner= None ): if owner: if not os.path.exists(filename): open(filename, 'a').close() shutil.chown(filename, *owner) return logging.FileHandler(filename, mode, encoding) LOGGING ={ 'version':1, 'disable_existing_loggers ': False , 'formatters': { 'default': { 'format':' %(asctime)s %(levelname)s %(name)s %(message)s ' }, }, 'handlers': { 'file':{ # The values below are popped from this dictionary and # used to create the handler, set the handler's level and # its formatter. '() ': owned_file_handler, 'level ':'DEBUG', 'formatter':'default', # The values below are passed to the handler creator callable # as keyword arguments. 'owner': ['pulse','pulse'], 'filename':'chowntest.log ', 'mode':'w', 'encoding':'utf-8 ', }, }, 'root': { 'handlers': ['file'], 'level ':'DEBUG', }, }