临时更改python日志记录处理程序

时间:2011-06-08 17:15:15

标签: python logging celery

我正在开发一个使用标准日志记录模块进行日志记录的应用。我们有一个设置,我们根据级别等登录到一堆文件。我们还使用芹菜从主应用程序中运行一些工作(维护通常很耗时)。

芹菜任务除了执行实际工作的调用函数(让我们说spam)之外什么都不做。这些函数使用日志记录模块输出状态消息。现在,我想编写一个装饰器,它劫持spam所做的所有日志调用,并将它们放入StringIO,以便我可以将它们放在某处。

我的解决方案之一是在执行函数时为根记录器插入处理程序以捕获所有内容。但是,这会弄乱全球共享对象,以后可能会出现问题。

我遇到了this answer,但这并不是我想要的。

2 个答案:

答案 0 :(得分:2)

关于StringIO的事情是,可能有多个进程在运行(Celery任务),因此有多个StringIO,对吗?

您可以这样做:

  1. 在Celery下运行的进程中,向根记录器添加一个处理程序,该处理程序将事件发送到套接字(用于TCP的SocketHandler或用于UDP的DatagramHandler)。
  2. 创建套接字接收器以接收和处理事件,如文档here所示。这类似于跨多个Celery运行进程的整合StringIO。
  3. 如果您正在使用多处理,您还可以使用here所述的方法。虽然那篇文章谈到了Python 3.2,但是使用logutils的Python 2.x也可以使用该功能。

    更新:如果您想避免单独的接收器进程,可以使用类似于this answer中的处理程序直接登录到数据库。如果要缓冲所有日志记录直到进程结束,可以将MemoryHandler与数据库处理程序结合使用来实现此目的。

答案 1 :(得分:0)

对于StringIO处理程序,您可以为根记录器添加额外的处理程序以获取所有内容,但同时添加一个虚拟过滤器(Logger.addFilter),用于过滤所有内容(所以什么都没有实际记录到StringIO)。

然后你可以为 spam 编写一个装饰器,在函数执行之前删除过滤器(Logger.removeFilter),并在之后添加虚拟过滤器。