临时更改 python 日志处理程序

发布于 2024-11-14 15:54:10 字数 469 浏览 3 评论 0 原文

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

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

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

我遇到了 这个答案,但这并不完全是我想要的。

I'm working on an app that uses the standard logging module to do logging. We have a setup where we log to a bunch of files based on levels etc. We also use celery to run some jobs out of the main app (maintenance stuff usually that's time consuming).

The celery task does nothing other than call functions (lets say spam) which do the actual work. These functions use the logging module to output status messages. Now, I want to write a decorator that hijacks all the logging calls made by spam and puts them into a StringIO so that I can put them somewhere.

One of the solutions I had was to insert a handler for the root logger while the function is executing that grabs everything. However, this is messing with global shared objects which might be problematic later.

I came across this answer but it's not exactly what I'm looking for.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寄意 2024-11-21 15:54:10

关于 StringIO 的问题是,可能有多个进程正在运行(Celery 任务),因此有多个 StringIO,对吧?

您可以执行以下操作:

  1. 在 Celery 下运行的进程中,向根记录器添加一个将事件发送到套接字的处理程序(用于 TCP 的 SocketHandler 或用于 UDP 的 DatagramHandler)。
  2. 创建一个套接字接收器来接收和处理事件,如文档所述 此处。这就像跨多个 Celery 运行进程的整合 StringIO。

如果您使用多重处理,还可以使用此处描述的方法。尽管该帖子讨论的是 Python 3.2,但使用 logutils

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

The thing about the StringIO is, there could be multiple processes running (Celery tasks), hence multiple StringIOs, right?

You can do something like this:

  1. In the processes run under Celery, add to the root logger a handler which sends events to a socket (SocketHandler for TCP or DatagramHandler for UDP).
  2. Create a socket receiver to receive and handle the events, as documented here. This acts like a consolidated StringIO across multiple Celery-run processes.

If you are using multiprocessing, you can also use the approach described here. Though that post talks about Python 3.2, the functionality is also available for Python 2.x using logutils.

Update: If you want to avoid a separate receiver process, you can log to a database directly, using a handler similar to that in this answer. If you want to buffer all the logging till the end of the process, you can use a MemoryHandler in conjunction with a database handler to achieve this.

昔日梦未散 2024-11-21 15:54:10

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

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

For the StringIO handler, you could add an extra handler for the root logger that would grab everything, but at the same time add a dummy filter (Logger.addFilter) that filters everything out (so nothing is actually logged to StringIO).

You could then write a decorator for spam that removes the filter (Logger.removeFilter) before the function executes, and adds the dummy filter back after.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文