多进程使用 logging 把日志存储到不同文件的实践

查看 93|回复 4
作者:f1ynnv2   
之前用 python 写单进程多线程的应用时,使用 logging 记录日志写到同一个文件很正常,最近写了个多进程多线程的应用使用 logging 记录日志到同一个文件时就开始出现问题了,主要就是基于时间的文件归档时会出 bug 。
简单搜了一下也找到了原因:logging 是线程安全但是进程不安全,官方推荐使用 queue 或者 socket 来实现多进程日志记录到同一个文件,或者自己修改 doRollOver 相关的操作。
我想问的问题是,我其实并没有上面“多进程存储日志到一个日志文件”的需求,相反我是希望把每个进程的日志单独存储为一个文件的,但是实践上感觉不太方便,以下是详情:
之前写单进程多线程时,只要在 logging 的封装模块里初始化一个全局的 logger ,其它所有模块不管是在哪个线程里,只要 import 一下这个 logger 就可以直接拿来用。
但是现在写多进程多线程的时候问题就出现了:
  • 如果仍然按照上述方法,那么不同进程 import 这个 logger 后,在自己的变量空间里虽然是互不干扰,但是在底层仍然操作同一个文件,因此会导致上面提到按时间归档的问题;
  • 有一个解决方法是在每个进程的启动函数里初始化一个专属的 logger ,指定不同的存储文件,然后通过参数的方式传递给调用的所有模块 /函数,让这些模块 /函数直接使用这个 logger 。技术上可行,但是实践上非常不优雅,调用的每个子模块都要传递这个 logger 参数。
    因为想问问大家,这个需求“多进程通过 logging 写日志到各自文件”是否有更优雅的实践?如果没的话,最后也只能回归官方通过 socket/queue 的方案来写单个文件了。

    logger, logging, 日志, 进程

  • Three2   
    又想到另一个方案:
    在每个函数里重新获取一次 logger ,这个 logger 在函数里初始化时根据当前函数所在的进程名称来初始化使用的文件。
    这个方案和原来单进程多线程相比仍然不够方便:之前单进程多线程的环境下,每个模块只要 import 一下 logger 这个全局变量,模块里的任何函数都能直接用。目前看来想要实现这种方便,是不是只能回归官方的 socket/queue 方案了。
    f1ynnv2
    OP
      
    每个进程的日志名字不同不就完事了
    gulu   
    @Three2 #1 可能我没表达清楚,我最后的问题其实就是“如何优雅的实现每个进程使用不同日志名字”。目前只想到这一个办法,但是不够优雅:
    -------
    每个进程的启动函数里初始化一个专属的 logger ,指定不同的存储文件,然后通过参数的方式传递给调用的所有模块 /函数,让这些模块 /函数直接使用这个 logger 。技术上可行,但是实践上非常不优雅,调用的每个子模块都要传递这个 logger 参数。
    gulu   
    全局的 logger 定义为 None ,第一次用的时候再初始化它。
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部