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 04 Python
python获取标准北京时间的方法
Mar 24 Python
Python下的twisted框架入门指引
Apr 15 Python
Python常用的文件及文件路径、目录操作方法汇总介绍
May 21 Python
python实现百万答题自动百度搜索答案
Jan 16 Python
python人民币小写转大写辅助工具
Jun 20 Python
用python代码将tiff图片存储到jpg的方法
Dec 04 Python
Python实战购物车项目的实现参考
Feb 20 Python
python爬虫selenium和phantomJs使用方法解析
Aug 08 Python
python检测服务器端口代码实例
Aug 31 Python
python中的itertools的使用详解
Jan 13 Python
Python函数参数分类原理详解
May 28 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遍历数组的方法分享
2012/03/22 PHP
用PHP即时捕捉PHP中的错误并发送email通知的实现代码
2013/01/19 PHP
javascript 短路法代码精简
2009/08/20 Javascript
JavaScript Cookie 直接浏览网站分网址
2009/12/08 Javascript
用js传递value默认值的示例代码
2014/09/11 Javascript
javascript引用类型之时间Date和数组Array
2015/08/27 Javascript
详解js界面跳转与值传递
2016/11/22 Javascript
JS中from 表单序列化提交的代码
2017/01/20 Javascript
JS闭包用法实例分析
2017/03/27 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
2018/04/26 Javascript
Redux实现组合计数器的示例代码
2018/07/04 Javascript
jQuery实现表格隔行换色
2018/09/01 jQuery
深入理解es6块级作用域的使用
2019/03/28 Javascript
调试Python程序代码的几种方法总结
2015/04/28 Python
Python中转换角度为弧度的radians()方法
2015/05/18 Python
Python 中的 else详解
2016/04/23 Python
Python反射的用法实例分析
2018/02/11 Python
python十进制和二进制的转换方法(含浮点数)
2018/07/07 Python
Python 画出来六维图
2019/07/26 Python
python实现最大优先队列
2019/08/29 Python
wxPython之wx.DC绘制形状
2019/11/19 Python
html5 canvas 使用示例
2010/10/22 HTML / CSS
HTML5之SVG 2D入门3—文本与图像及渲染文本介绍
2013/01/30 HTML / CSS
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
彪马荷兰官网:PUMA荷兰
2019/05/08 全球购物
碧欧泉Biotherm加拿大官方网站:法国高端护肤品牌
2019/10/18 全球购物
现代绅士日常奢侈品:Todd Snyder
2019/12/13 全球购物
ECHT官方网站:男女健身服
2020/02/14 全球购物
环境工程毕业生自荐信
2013/11/17 职场文书
员工培训心得体会
2013/12/30 职场文书
环境建设实施方案
2014/03/14 职场文书
党支部鉴定意见
2015/06/02 职场文书
小学总务工作总结
2015/08/13 职场文书
2016年“六一儿童节”校园广播稿
2015/12/17 职场文书
高端收音机+蓝牙音箱,JBL TUNER FM带收音蓝牙音箱评测
2021/04/24 无线电
JavaScript高级程序设计之基本引用类型
2021/11/17 Javascript