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机器学习之决策树算法
Dec 22 Python
分数霸榜! python助你微信跳一跳拿高分
Jan 08 Python
python3中获取文件当前绝对路径的两种方法
Apr 26 Python
python实现图片筛选程序
Oct 24 Python
python消费kafka数据批量插入到es的方法
Dec 27 Python
python 实现UTC时间加减的方法
Dec 31 Python
pyqt远程批量执行Linux命令程序的方法
Feb 14 Python
利用python实现对web服务器的目录探测的方法
Feb 26 Python
使用Keras建立模型并训练等一系列操作方式
Jul 02 Python
详解python tcp编程
Aug 24 Python
python实现登录与注册系统
Nov 30 Python
Python代码,能玩30多款童年游戏!这些有几个是你玩过的
Apr 27 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 从数据库提取二进制图片的处理代码
2009/09/09 PHP
解决文件名解压后乱码的问题 将文件名进行转码的代码
2012/01/10 PHP
PHP答题类应用接口实例
2015/02/09 PHP
ThinkPHP3.2.3数据库设置新特性
2015/03/05 PHP
Yii中实现处理前后台登录的新方法
2015/12/28 PHP
Yii2中简单的场景使用介绍
2017/06/02 PHP
PHP框架laravel的.env文件配置教程
2017/06/07 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
jQuery+PHP实现图片上传并提交功能
2020/07/27 PHP
快速排序 php与javascript的不同之处
2011/02/22 Javascript
2014 年最热门的21款JavaScript框架推荐
2014/12/25 Javascript
javascript中的五种基本数据类型
2015/08/26 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
2015/09/09 Javascript
jQuery实现简易的天天爱消除小游戏
2015/10/16 Javascript
js实现正则匹配中文标点符号的方法
2015/12/23 Javascript
概述jQuery中的ajax方法
2016/12/16 Javascript
纯jQuery实现前端分页功能
2017/03/23 jQuery
Vue中定义全局变量与常量的各种方式详解
2017/08/23 Javascript
webpack优化的深入理解
2018/12/10 Javascript
改进 JavaScript 和 Rust 的互操作性并深入认识 wasm-bindgen 组件
2019/07/13 Javascript
微信小程序实现写入读取缓存详解
2019/08/30 Javascript
python3+PyQt5实现拖放功能
2018/04/24 Python
详解Python 协程的详细用法使用和例子
2018/06/15 Python
Python后台管理员管理前台会员信息的讲解
2019/01/28 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
Django 返回json数据的实现示例
2020/03/05 Python
详解HTML5常用的语义化标签
2019/09/27 HTML / CSS
美国高端寝具品牌:Coyuchi
2017/02/08 全球购物
应届大学生自荐信格式
2013/09/21 职场文书
管理部部长岗位职责
2013/12/05 职场文书
城市规划应届生推荐信
2014/09/08 职场文书
县政府领导班子“四风”方面突出问题整改措施
2014/09/23 职场文书
房屋转让协议书
2014/10/18 职场文书
校园安全教育心得体会
2016/01/15 职场文书
Java 在线考试云平台的实现
2021/11/23 Java/Android
详解JSON.parse和JSON.stringify用法
2022/02/18 Javascript