What is the most pythonic way of logging for multiple modules and multiple handlers with specified encoding?

后端 未结 2 1573
半阙折子戏
半阙折子戏 2021-01-13 17:57

I\'m looking for concrete advice about how the multiple module and multiple handler logging should be done. I have added my simplified code here, but I don\'t want to bias t

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-13 18:28

    For modules consisting of many parts, I use the method recommended in the documentation, which just has one line per module, logger = logging.getLogger(__name__). As you point out, the module shouldn't know or care how or where its messages are going, it just passes it on to the logger that should have been set up by the main program.

    To reduce cut-n-paste depending on which is your main program, make sure your modules have a hierarchy that makes sense, and have just one function somewhere that sets up your logging, which can then be called by any main you wish.

    For example, make a logsetup.py:

    import logging
    
    def configure_log(level=None,name=None):
        logger = logging.getLogger(name)
        logger.setLevel(level)
    
        file_handler = logging.FileHandler('../logs/%s' % name,'w','utf-8')
        file_handler.setLevel(logging.DEBUG)
        file_format = logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d in %(funcName)s]')
        file_handler.setFormatter(file_format)
        logger.addHandler(file_handler)
    
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.INFO)
        console_format = logging.Formatter('%(message)s')
        console_handler.setFormatter(console_format)
        logger.addHandler(console_handler)
    

    To have your individual modules have a mode in which they behave as main, define a separate function, such as main.

    In level0.py and/or level1.py:

    def main():
      # do whatever
    

    And in the very top level program, call that function:

    import logging
    from logsetup import configure_log
    configure_log(logging.DEBUG,'level0') # or 'level1'
    from level0 import main # or level1
    
    if __name__ == "__main__"
      main()
    

    You should still have the __name__ == "__main__" clause there, some modules (cough multiprocessing cough) have different behavior depending on whether or not the clause exists.

提交回复
热议问题