python 实现多进程日志轮转ConcurrentLogHandler

作者:qq_41864652 时间:2021-03-01 02:03:42 

记录日志是我们程序中必不可少的一个功能,但是日志文件如果没有合理的管理,时间长了几百兆的日志文件就很难分析了(都不想打开看),但是又不可能经常手动去管理它

日志轮转:根据时间或者文件大小控制日志的文件个数,不用我们手动管理

python中logging模块内置的有几个支持日志轮转的handler

常用的有TimedRotatingFileHandler根据时间轮转 RotatingFileHandler根据文件大小轮转

但是内置的这些handler是多线程安全的,而不支持多进程(可以修改源码加锁保证进程安全)

多进程的时候可以使用ConcurrentLogHandler(需要自行安装)按照文件大小轮转


pip install ConcurrentLogHandler

一、简单的日志轮转功能实现:


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import logging
from cloghandler import ConcurrentRotatingFileHandler
from config import LOG_PATH, LOG_FILENAME, LOG_MAX_BYTES

def create_logger(log_path=os.getcwd(), # 存放日志的目录
        level=logging.DEBUG,
        formatter=logging.BASIC_FORMAT, # 日志输出格式
        logger_name="", # 可以使用logging.getlogger(logger_name)使用此logger
        mode='a',
        delay=0,
        debug=True,
        log_filename=LOG_FILENAME, # 保存日志的文件名(备份出的文件会以此名+.1、 .2命名)
        encoding=None,
        maxBytes=LOG_MAX_BYTES, # 每个日志文件的最大容量
        backupCount=3 # 最多备份几个日志文件):
 # 判断存放日志的文件夹是否存在 如果不存在新建
 if not os.path.exists(log_path):
   os.mkdir(log_path)
 # 存放log的文件名
 log_filename = os.path.join(log_path, log_filename)

# 创建一个logger
 logger = logging.getLogger(logger_name)
 # 设置日志等级
 logger.setLevel(level)
 # 创建一个滚动日志处理器
 crfh = ConcurrentRotatingFileHandler(log_filename, mode=mode, maxBytes=maxBytes, backupCount=backupCount, delay=delay, debug=debug, encoding=encoding)
 # 定义handler的输出格式
 # 设定日志输出格式
 crfh.setFormatter(formatter)
 # 添加日志处理器
 logger.addHandler(crfh)
 # 返回logger对象
 return logger

# 日志格式
formatter_log = logging.Formatter('%(asctime)s - %(filename)s [line: %(lineno)d] 【%(levelname)s】 ----- %(message)s')
# 生成一个logger
logger = create_logger(log_path=LOG_PATH, logger_name="mylogger", formatter=formatter_log)

这样就可以在其他模块导入logger进行使用了


logger.error("error msg")

有时候我们会记录一些数据到文件中,如果多个程序同时写入同一文件会把数据写乱 我们也可以使用这个模块来代替f.write()


from config import CHANNEL_PATH, CHANNEL_FILENAME, LOG_MAX_BYTES
# 只需要把日志的格式改为只存入信息就可以了
formatter_writer = logging.Formatter('%(message)s')
# 创建一个写入器(logger)
writer = create_logger(logger_name="writer",log_path=CHANNEL_PATH, log_filename=CHANNEL_FILENAME, formatter=formatter_writer, level=logging.INFO)

这样就可以使用writer.info("msg")记录数据了

二、使用ini配置文件

创建文件xxx.ini


[loggers]
keys = root,public

[handlers]
keys = consoleHandler,publicFileHandler

[formatters]
keys = my_formatter

[logger_root]
level = DEBUG
handlers = consoleHandler

[logger_public]
handlers = publicFileHandler
qualname = public
propagate = 0

[handler_consoleHandler]
class = StreamHandler
level = DEBUG
formatter = my_formatter
args = (sys.stdout,)

[handler_publicFileHandler]
class = cloghandler.ConcurrentRotatingFileHandler
level = INFO
formatter = my_formatter
kwargs = {"filename": "./logs/public.log", "maxBytes": 1024 * 1024 * 10, "backupCount": 10, "delay": True, "debug": True}

[formatter_my_formatter]
format = %(asctime)s - %(filename)s [line: %(lineno)d] [%(levelname)s] ----- %(message)s
datefmt = %Y-%m-%d %H:%M:%S

创建mylogger.py


import logging
import logging.config
logging.config.fileConfig("./xxx.ini")
logger = logging.getLogger("public")
logger.info("hello world!")

补充:python日志轮转RotatingFileHandler动态加载导致不能记录日志问题

linux下:

Traceback (most recent call last): File “/usr/lib64/python2.7/logging/handlers.py”, line 77, in emit self.doRollover() File “/usr/lib64/python2.7/logging/handlers.py”, line 136, in doRollover os.rename(sfn, dfn) OSError: [Errno 13] Permission denied Logged from file utils.py, line 89

windows下:

Traceback (most recent call last): File “F:\Python27\lib\logging\handlers.py”, line 77, in emit self.doRollover() File “F:\Python27\lib\logging\handlers.py”, line 142, in doRollover os.rename(self.baseFilename, dfn) WindowsError: [Error 32] Logged from file utils.py, line 89

这是由于django开发模式时会同时启动两个进程加载settings.py,导致日志文件占用后无法重命名或者删除

都知道django开发模式下如果有文件变动会自动重新启动,所以同时又两个进程,一个是程序正常运行的进程,另一个是用来监听变更并重启服务的进程,他们都会加载一遍settings.py,可以在settings.py中加print然后启动会看到控制台又两次输出。

解决方式:

python C:\Users\pc\Desktop\yunserver-1.1\manage.py runserver --noreload 0.0.0.0:8000

使用不动态加载方式运行(这样可能会影响开发环境中动态加载)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

来源:https://blog.csdn.net/qq_41864652/article/details/81317908

标签:python,多进程,日志,轮转
0
投稿

猜你喜欢

  • Python使用matplotlib实现在坐标系中画一个矩形的方法

    2022-05-13 00:19:13
  • asp如何同时处理数据库和页面错误?

    2010-06-07 20:58:00
  • python信号量,条件变量和事件详解

    2021-10-06 18:14:23
  • 如何设置SQL Server数据库全文索引服务

    2009-01-13 13:46:00
  • php实现mysql备份恢复分卷处理的方法

    2023-11-16 20:55:33
  • python读文件逐行处理的示例代码分享

    2023-03-17 03:54:04
  • 在Python中使用AOP实现Redis缓存示例

    2021-09-12 11:18:45
  • 解决Python2.7中IDLE启动没有反应的问题

    2022-10-17 17:43:57
  • Jupyter Notebook 文件默认目录的查看以及更改步骤

    2022-03-22 15:01:19
  • python使用threading.Condition交替打印两个字符

    2022-04-13 09:01:46
  • Python3多线程处理爬虫的实战

    2023-08-16 02:16:21
  • 三种Golang数组拷贝方式及性能分析详解

    2023-07-13 07:54:27
  • 使用NumPy读取MNIST数据的实现代码示例

    2021-08-05 19:17:52
  • Python企业编码生成系统之主程序模块设计详解

    2023-11-18 18:44:37
  • CSS分栏布局的方法:绝对定位和浮动

    2009-04-30 13:10:00
  • 用Python实现斐波那契(Fibonacci)函数

    2023-06-29 19:59:07
  • Windows下安装python2.7及科学计算套装

    2023-05-28 13:35:19
  • Linux 发邮件磁盘空间监控(python)

    2022-03-15 09:17:24
  • 基于Python把网站域名解析成ip地址

    2021-08-23 05:31:06
  • python selenium 对浏览器标签页进行关闭和切换的方法

    2023-06-18 19:42:26
  • asp之家 网络编程 m.aspxhome.com