python通过TimedRotatingFileHandler按时间切割日志


Posted in Python onJuly 17, 2019

通过TimedRotatingFileHandler按时间切割日志

线上跑了一个定时脚本,每天生成的日志文件都写在了一个文件中。但是日志信息不可能输出到单一的一个文件中。

原因有二:1.日志文件越来越大会影响系统的性能。2.日志文件格式不够清晰,比如我想看今天的日志,不太方便找到的今天的日志信息(即使对日志输出做了时间提示)

通过设置 TimedRotatingFileHandler 进行日志按周(W)、天(D)、时(H)、分(M)、秒(S)切割。

先看一个简单例子:

import time
import logging
import os
from logging import handlers
def _logging(**kwargs):
  level = kwargs.pop('level', None)
  filename = kwargs.pop('filename', None)
  datefmt = kwargs.pop('datefmt', None)
  format = kwargs.pop('format', None)
  if level is None:
    level = logging.DEBUG
  if filename is None:
    filename = 'default.log'
  if datefmt is None:
    datefmt = '%Y-%m-%d %H:%M:%S'
  if format is None:
    format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
  log = logging.getLogger(filename)
  format_str = logging.Formatter(format, datefmt)
  # backupCount 保存日志的数量,过期自动删除
  # when 按什么日期格式切分(这里方便测试使用的秒)
  th = handlers.TimedRotatingFileHandler(filename=filename, when='S', backupCount=3, encoding='utf-8')
  th.setFormatter(format_str)
  th.setLevel(logging.INFO)
  log.addHandler(th)
  log.setLevel(level)
  return log
os.makedirs("./logs", exist_ok=True)
logger = _logging(filename='./logs/default.log')
if __name__ == '__main__':
  while True:
    time.sleep(0.1)
    logger.info('哈哈哈')

结果如下:

python通过TimedRotatingFileHandler按时间切割日志

上述代码可以正常运行,而且也可以生成固定的日志个数,但是有一个问题,生成的日志文件格式是你的 文件名+时间 的格式,没有设置时间的话默认设置到了秒(这里是按秒切割)

修改日志格式后缀名称:

# 在上述代码中加入
def namer(filename):
  return filename.split('default.')
th.namer = namer
# 设置为S,默认的suffix为 Y-%m-%d_%H-%M-%S
th.suffix = "%Y-%m-%d_%H-%M-%S.log"
# 为了看的更视觉效果,可以显示在控制台答应
cmd = logging.StreamHandler()
cmd.setFormatter(format_str)
cmd.setLevel(level)
log.addHandler(cmd)

运行结果:

python通过TimedRotatingFileHandler按时间切割日志

名字好像可以了,但是日志好像没有起到自动删除的目的啊,而且也没在之前的log文件夹了。

来看看源码:

def getFilesToDelete(self):
    """
    Determine the files to delete when rolling over.

    More specific than the earlier method, which just used glob.glob().
    """
    dirName, baseName = os.path.split(self.baseFilename)
    fileNames = os.listdir(dirName)
    result = []
    prefix = baseName + "."
    plen = len(prefix)
    for fileName in fileNames:
      if fileName[:plen] == prefix:
        suffix = fileName[plen:]
        if self.extMatch.match(suffix):
          result.append(os.path.join(dirName, fileName))
    if len(result) < self.backupCount:
      result = []
    else:
      result.sort()
      result = result[:len(result) - self.backupCount]
    return result

这是它的删除逻辑,关键是通过 . 前面的字段判断是否重复,当有特定的重复数后开始删除。

所以问题来了,要么自己去重写源码,要么就只能用 default.日期.log 这种格式了。

附上平时使用的日志代码

import logging
import os
from logging import handlers
def _logging(**kwargs):
  level = kwargs.pop('level', None)
  filename = kwargs.pop('filename', None)
  datefmt = kwargs.pop('datefmt', None)
  format = kwargs.pop('format', None)
  if level is None:
    level = logging.DEBUG
  if filename is None:
    filename = 'default.log'
  if datefmt is None:
    datefmt = '%Y-%m-%d %H:%M:%S'
  if format is None:
    format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
  log = logging.getLogger(filename)
  format_str = logging.Formatter(format, datefmt)
  def namer(filename):
    return filename.split('default.')[1]
  # cmd = logging.StreamHandler()
  # cmd.setFormatter(format_str)
  # cmd.setLevel(level)
  # log.addHandler(cmd)
  os.makedirs("./debug/logs", exist_ok=True)
  th_debug = handlers.TimedRotatingFileHandler(filename="./debug/" + filename, when='D', backupCount=3,
                         encoding='utf-8')
  # th_debug.namer = namer
  th_debug.suffix = "%Y-%m-%d.log"
  th_debug.setFormatter(format_str)
  th_debug.setLevel(logging.DEBUG)
  log.addHandler(th_debug)
  th = handlers.TimedRotatingFileHandler(filename=filename, when='D', backupCount=3, encoding='utf-8')
  # th.namer = namer
  th.suffix = "%Y-%m-%d.log"
  th.setFormatter(format_str)
  th.setLevel(logging.INFO)
  log.addHandler(th)
  log.setLevel(level)
  return log
os.makedirs('./logs', exist_ok=True)
logger = _logging(filename='./logs/default')

总结

以上所述是小编给大家介绍的python通过TimedRotatingFileHandler按时间切割日志,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
简明 Python 基础学习教程
Feb 08 Python
调试Python程序代码的几种方法总结
Apr 28 Python
使用httplib模块来制作Python下HTTP客户端的方法
Jun 19 Python
python使用magic模块进行文件类型识别方法
Dec 08 Python
Python后台管理员管理前台会员信息的讲解
Jan 28 Python
python与C、C++混编的四种方式(小结)
Jul 15 Python
Python3 使用pillow库生成随机验证码
Aug 26 Python
使用pytorch搭建AlexNet操作(微调预训练模型及手动搭建)
Jan 18 Python
python中count函数简单的实例讲解
Feb 06 Python
python爬取天气数据的实例详解
Nov 20 Python
Python3.9.1中使用split()的处理方法(推荐)
Feb 07 Python
Python查找算法的实现 (线性、二分,分块、插值查找算法)
Apr 24 Python
python递归法实现简易连连看小游戏
Mar 25 #Python
django2笔记之路由path语法的实现
Jul 17 #Python
Django之创建引擎索引报错及解决详解
Jul 17 #Python
python实现连连看辅助之图像识别延伸
Jul 17 #Python
Django 路由控制的实现
Jul 17 #Python
详解python实现数据归一化处理的方式:(0,1)标准化
Jul 17 #Python
简单了解django索引的相关知识
Jul 17 #Python
You might like
强烈推荐:php.ini中文版(2)
2006/10/09 PHP
php echo 输出字符串函数详解
2010/05/13 PHP
PHPMailer使用教程(PHPMailer发送邮件实例分析)
2012/12/06 PHP
PHP fopen()和 file_get_contents()应用与差异介绍
2014/03/19 PHP
分享php多功能图片处理类
2016/05/15 PHP
PHP识别二维码的方法(php-zbarcode安装与使用)
2016/07/07 PHP
php实现登陆模块功能示例
2016/10/20 PHP
jquery中的sortable排序之后的保存状态的解决方法
2010/01/28 Javascript
jQuery代码优化 选择符篇
2011/11/01 Javascript
网站内容禁止复制和粘贴、另存为的js代码
2014/02/26 Javascript
使用javascript实现简单的选项卡切换
2015/01/09 Javascript
JS日期格式化之javascript Date format
2015/10/01 Javascript
深入理解requestAnimationFrame的动画循环
2016/09/20 Javascript
微信小程序链接传参并跳转新页面
2016/11/29 Javascript
浅谈关于angularJs中使用$.ajax的注意点
2017/08/12 Javascript
node跨域请求方法小结
2017/08/25 Javascript
NodeJs form-data格式传输文件的方法
2017/12/13 NodeJs
JS闭包原理与应用经典示例
2018/12/20 Javascript
微信小程序实现图片上传
2019/05/23 Javascript
js getBoundingClientRect使用方法详解
2019/07/17 Javascript
[02:32]【DOTA2亚洲邀请赛】iceice,梦开始的地方
2017/03/13 DOTA
详谈套接字中SO_REUSEPORT和SO_REUSEADDR的区别
2018/04/28 Python
对python3中pathlib库的Path类的使用详解
2018/10/14 Python
pyqt5利用pyqtDesigner实现登录界面
2019/03/28 Python
python3 求约数的实例
2019/12/05 Python
基于打开pycharm有带图片md文件卡死问题的解决
2020/04/24 Python
python中数字是否为可变类型
2020/07/08 Python
pytho matplotlib工具栏源码探析一之禁用工具栏、默认工具栏和工具栏管理器三种模式的差异
2021/02/25 Python
使用CSS3设计地图上的雷达定位提示效果
2016/04/05 HTML / CSS
大学生优秀的自我评价分享
2013/10/22 职场文书
工地资料员岗位职责
2013/12/31 职场文书
领导班子四风查摆对照检查材料思想汇报
2014/10/05 职场文书
委托书英文
2015/01/28 职场文书
库房管理员岗位职责
2015/02/12 职场文书
2016思想纪律作风整顿心得体会
2016/01/23 职场文书
2019年亲子运动会口号
2019/10/11 职场文书