Python日志记录在导入模块中的记录器的包装器脚本中创建处理程序

时间:2017-10-25 16:04:07

标签: python logging import

我正在编写一个API(python 2.7.x),我有一个工作脚本,它本身什么都不做但可以被各种更高级别的脚本包装(即从csv提供工作者数据的脚本) ,一个来自dB等)。目前的任务要求我:

  1. 将INFO +记录到控制台
  2. 将一组INFO +事件记录到.csv文件
  3. 将所有事件记录到不同的.log文件
  4. 我已将我的代码提炼为以下示例:

    # SuperExample.py
    import logging
    import SubExample
    
    
    def main():
        logging.basicConfig(level=logging.INFO)
        verbose_log = 'debug.log'
        data_log = 'data.csv'
        format_string = '%(asctime)s::%(name)s::%(levelname)s::%(message)s'
        formatter = logging.Formatter(format_string)
    
        # verbose log is a typical event log used for debugging
        verbose = logging.FileHandler(verbose_log, mode='w')
        verbose.setLevel(logging.DEBUG)
        verbose.setFormatter(formatter)
        SubExample.logger.addHandler(verbose)
    
        # data log will eventually have a different formatter and a filter in
        # order to get a narrow set of events, formatted for post-processing ease
        data = logging.FileHandler(data_log, mode='w')
        data.setLevel(logging.INFO)
        data.setFormatter(formatter)
        SubExample.logger.addHandler(data)
    
        logging.info('Started')
        SubExample.do_something()
        logging.info('Finished')
    
    if __name__ == '__main__':
        main()
    

    # SubExample.py
    import logging
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    
    
    def do_something():
        logger.debug('hey look I am doing something!')
        logger.debug('now I am doing something else!!')
        logger.info('this is my result!!!')
    

    在我的文件中给了我想要的东西,但是在我的控制台中给了我这个:

    INFO:root:Started
    DEBUG:SubExample:hey look I am doing something!
    DEBUG:SubExample:now I am doing something else!!
    INFO:SubExample:this is my result!!!
    INFO:root:Finished
    

    我已经阅读了有关日志记录模块及其最佳做法的信息,但很少有示例代码的工作方式与图书馆介入时所描述的方式完全相同。所以,我的第一个问题是:这是一个基本理智的方法吗?我还没有真正看到其他人从包装脚本中将处理程序附加到下标记录器,但它似乎做了我想做的事。

    我的第二个问题是为什么DEBUG语句会进入控制台?我认为logging.basicConfig(level=logging.INFO)应该阻止这个吗?

1 个答案:

答案 0 :(得分:0)

在SuperExample.py文件中,我删除了basicConfig步骤,改为:

# SuperExample.py
import logging
import SubExample

def main():
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)

    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    logger.addHandler(console)
    ...
    ...
    logger.info('Started')
    ...
    logger.info('Finished')

在SubExample.py文件中:

# SubExample.py
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
logger.addHandler(console)

def do_something():
    ....

其余代码与您的代码相同。当我运行SuperExample.py时,这是输出:

test_project ~$ python SuperExample.py
Started
this is my result!!!
Finished

debug.log文件包含:

2017-10-25 16:18:08,292::SubExample::DEBUG::hey look I am doing something!
2017-10-25 16:18:08,292::SubExample::DEBUG::now I am doing something else!!
2017-10-25 16:18:08,292::SubExample::INFO::this is my result!!!

data.csv文件包含:

2017-10-25 16:18:08,292::SubExample::INFO::this is my result!!!

因此,似乎正确的方法是在每个模块的记录器中添加StreamHandler,并将其级别设置为您希望从那里记录到控制台的级别。此外,每当执行logging.getLogger()时,您必须设置该记录器的级别以从处理程序获得预期的行为。