【问题标题】:How to shutdown the logger in python after a function containing it is interrupted?如何在包含记录器的函数中断后关闭 python 中的记录器?
【发布时间】:2022-12-30 21:53:03
【问题描述】:

我在函数内部的 python 中使用 logging module。代码的简化结构如下所示。

def testfunc(df):
    import logging
    import sys
    from datetime import datetime
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    # to print to the screen
    ch = logging.StreamHandler(sys.__stdout__)
    ch.setLevel(logging.INFO) 
    logger.addHandler(ch)
    #to print to file
    fh = logging.FileHandler('./data/treatment/Treatment_log_'+str(datetime.today().strftime('%Y-%m-%d'))+'.log')
    fh.setLevel(logging.INFO) 
    logger.addHandler(fh)
    #several lines of code and some information like:
    logger.info('Loop starting...')

    for i in range(6):   # actually a long for-loop 
        #several lines of somewhat slow code (even with multiprocessing) and some information like:
        logger.info('test '+str(i))
            
    logging.shutdown()    

    return None

所以,我知道:

  • 记录器需要关闭(logging.shutdown());
  • 它包含在函数的末尾。

问题是:

  • 实际函数处理数据帧的子集,有时会因为没有足够的数据等而导致错误。
  • 如果我再次运行该函数,我看到的是所有消息都重复两次(如果我需要再次运行,甚至更多)。
  • 情况提醒了举报的hereherehere,例如...但略有不同...

我明白了,这是因为 logging 模块没有关闭,处理程序也没有被删除......我理解最终的功能,我应该预见到这种情况,并包括避免引发错误的步骤,比如关闭记录器和完成功能等等......但目前我什至使用日志信息来识别这种情况......

我的问题是:一旦发生这种情况(功能因错误而中止),我该如何关闭它? ...在我目前的情况下,我只是在测试代码?目前,让它停止的方法是在 Spyder 中启动新控制台(在我的理解中,重新启动内核)。在这种情况下正确的程序是什么?

我感谢任何帮助...


【问题讨论】:

  • logging.shutdown 将在应用程序结束时调用。一旦你调用它,你就不能可靠地使用记录器任何地方其他在应用程序中。
  • 亲爱的@chepner,感谢您这么快发表评论。是的,我明白了……(logging.shutdown) 在该函数的末尾……关键是……抛出了错误,函数中止了……我正在重新启动控制台/内核…… . 那是唯一的方法吗?我需要保存所有以前的数据,重新加载等等......
  • 如果您打算再次调用该函数,为什么要在此函数中调用 logging.shutdown()?通常,您根本不需要致电logging.shutdown;当您导入模块时,它已注册为 atexit,因此它会在脚本末尾自动调用。您在什么情况下使用testfunc
  • 我不打算将解决方案包含在函数中......最后,我希望规避所有可能的问题......目前,我正在使用日志来跟踪文件中错误的可能原因,但稍后我会只需保留日志以供控制...我的问题确实处于当前的“开发”阶段...
  • 该函数不打算在循环中按顺序调用,也不是那么频繁......但是当它被调用时,我想保持程序的执行(我有多少条记录,我何时获得数据并进行处理等。 ..)...我不需要其他部分(在该功能之外)记录在文件中的日志...至少现在...它不是用于应用程序,我正在处理数据进行分析...我想象记录日志是跟踪针对该过程具体执行的操作的更简单方法...

标签: python logging


【解决方案1】:

我想你可以先检查一下是否有任何现有的记录器

loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]

如果没有,您可以创建记录器

如果有,不要创建一个新的

或者,您可以让另一个文件设置记录器,并通过 subprocess.Popen() 或类似方式调用此文件。

第一个选项的代码来自这里How to list all existing loggers using python.logging module

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-17
    • 1970-01-01
    • 2019-06-27
    • 2016-07-07
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    相关资源
    最近更新 更多