龙空技术网

Python 的日志模块有啥进程不安全?

写日记的梗图 201

前言:

目前看官们对“python多进程的坑”可能比较珍视,咱们都需要了解一些“python多进程的坑”的相关内容。那么小编在网摘上搜集了一些关于“python多进程的坑””的相关内容,希望你们能喜欢,姐妹们一起来学习一下吧!

很早以前有一位老同事和我说 Python 日志模块多进程不安全,没办法多个进程同时写一个日志文件。当时只是看了一下官方文档确实明确的说是 Thread Safe,就也没有深究这个问题。

这几天正好看一个项目里用了 ConcurrentLogHandler 包,忽然想仔细看一下 Python 日志模块到底在多进程下有啥问题。

TL;DR;正常情况下,如果不做日志 Rotate,不会有任何问题如果多进程 Rotate 日志文件,会出问题这一切都和读写文件没什么关系

上面说的正常情况下,是指 Handle 初始化的时候模式要用默认的 mode='a'

1. 正常情况下,如果不做日志 Rotate,不会有任何问题

Python 的 logging.FileHandler 日志读写依赖的是什么?如果看过 logging.FileHandler日志模块的源码就知道该模块在初始化的时候会调用 open 打开一个文件输出流,每次写日志就是 write + flush 的过程。

 def emit(self, record):    try:        msg = self.format(record)        stream = self.stream        stream.write(msg)        stream.write(self.terminator)        self.flush()    except Exception:        self.handleError(record)

而我们知道,python 在写文件的过程中,如果是通过 mode='a' 打开的文件,多进程写文件不会出现任何问题(见文末参考),所以,mode='a' 的情况下,多进程同时写日志文件不会出现任何问题

2. 如果多进程 Rotate 日志文件,会出问题

但是如果多个进程同时 Rotate 文件,就会出现问题。

一个典型的 case 是一个进程已经 Rotate 并写入 Rotate 后的文件了;

另一个进程此时恰巧进行 Rotate,就会删掉第一次创建的新文件,这期间第一个进程写入的日志就会丢失。

网上还有人说发现了特定情况下,同时写新旧两个日志文件的情况,这个我也没有遇到过,暂时也没有脑细胞分析会不会出现这种情况

3. 如何解决

相关的解决办法网上已经很多了,也不是本文讨论的重点,例如:

重写 FileRotateHandler,目前我们线上程序就是沿着这个思路做的使用 ConcurrentLogHandler 包备注:

A. ConcurrentLogHandler 的作用

我们可以看一下该模块官方文档是怎么说的:

Python logging handler that allows multiple processes to safely write to the same log file concurrently. This module extends the standard RotatingFileHandler functionality, and can be use as a drop-in replacement for that logging class.

Python 官方的 logging handler 允许多进程对日志文件的安全读写。本模块扩展了 RotatingFileHandler 的功能,可以用来直接替换原来的 RotatingFileHandler。

B. 更多参考

Linux下多进程写同一文件,要不要加锁?: 多进程同时写一个文件会怎样?: 多进程解决日志错乱问题: 多进程日志记录: -进程-日志

标签: #python多进程的坑