下面提供一个完整攻略实现 Python 多进程日志轮转 ConcurrentLogHandler。
1. 前言
Python 3 自带有 logging
模块,方便我们快速实现日志记录功能。如果在单进程环境中,使用 logging.handlers.TimedRotatingFileHandler
类就可以实现日志轮转。但是在多进程环境下,这个类有些局限性,日志轮转会出现问题。因此,我们可以使用 ConcurrentLogHandler
扩展模块来解决这个问题。
2. 安装 ConcurrentLogHandler
可以通过 pip 安装 ConcurrentLogHandler
模块:
pip install ConcurrentLogHandler
3. 使用 ConcurrentLogHandler
使用 ConcurrentLogHandler 就像使用 Python 原生的 logging.handlers.TimedRotatingFileHandler
一样,只需要在初始化时选择 ConcurrentRotatingFileHandler 类即可。使用示例如下:
import logging
from concurrent_log_handler import ConcurrentRotatingFileHandler
logger = logging.getLogger()
handler = ConcurrentRotatingFileHandler(filename='test.log', mode='a', maxBytes=1024*1024*10, backupCount=5, encoding='utf-8', delay=False)
logger.addHandler(handler)
logger.info('hello world')
这里的 filename
是日志文件名,maxBytes
是单个日志文件的最大字节数,backupCount
是备份数量,mode
是写入模式,encoding
是编码方式,delay
是去掉日志初始化延时特性。
使用 ConcurrentRotatingFileHandler
时,需要注意的是,日志文件不能以日期结尾,即类似 test.log.20200101
这样的文件名会导致日志文件不断新建,形成大量垃圾文件。
4. 完整示例
下面提供一个完整的示例代码,演示如何使用 ConcurrentRotatingFileHandler
实现多进程日志轮转。
import logging
from concurrent_log_handler import ConcurrentRotatingFileHandler
import multiprocessing
import time
def worker():
logger = multiprocessing.get_logger()
logger.setLevel(logging.INFO)
handler = ConcurrentRotatingFileHandler(filename='test.log', mode='a', maxBytes=1024*1024*10, backupCount=5, encoding='utf-8', delay=False)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info('hello from worker')
def main():
logger = logging.getLogger()
logger.setLevel(logging.INFO)
handler = ConcurrentRotatingFileHandler(filename='test.log', mode='a', maxBytes=1024*1024*10, backupCount=5, encoding='utf-8', delay=False)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
process_list = []
for i in range(3):
p = multiprocessing.Process(target=worker)
p.start()
process_list.append(p)
for p in process_list:
p.join()
logger.info('hello from main')
if __name__ == '__main__':
main()
这里使用了 Python 自带的 multiprocessing
模块,可以在多进程中测试日志记录是否正常。在执行此程序时,可以查看 test.log
文件的变化,观察日志轮转是否生效。
5. 总结
通过使用 ConcurrentRotatingFileHandler
扩展模块,可以方便地实现多进程环境下的日志轮转。在使用此模块时,需要特别注意日志文件名的设置,以免出现问题。以上就是 Python 实现多进程日志轮转 ConcurrentLogHandler 的完整攻略。