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进阶教程之词典、字典、dict
Aug 29 Python
python中MySQLdb模块用法实例
Nov 10 Python
Python中的迭代器漫谈
Feb 03 Python
用Python制作检测Linux运行信息的工具的教程
Apr 01 Python
numpy 计算两个数组重复程度的方法
Nov 07 Python
对python修改xml文件的节点值方法详解
Dec 24 Python
python实现对输入的密文加密
Mar 20 Python
python监控nginx端口和进程状态
Sep 06 Python
numpy.random.shuffle打乱顺序函数的实现
Sep 10 Python
Python彻底删除文件夹及其子文件方式
Dec 23 Python
python将下载到本地m3u8视频合成MP4的代码详解
Nov 24 Python
python 使用pandas读取csv文件的方法
Dec 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学习之简单计算器实现代码
2011/06/09 PHP
PHP中将数组转成XML格式的实现代码
2011/08/08 PHP
PHP判断是否连接上网络的方法
2015/07/01 PHP
PHP会话控制实例分析
2016/12/24 PHP
图像替换新技术 状态域方法
2010/01/28 Javascript
关于jQuery中.attr()和.prop()的问题探讨
2013/09/06 Javascript
js模拟点击以提交表单为例兼容主流浏览器
2013/11/29 Javascript
JS的参数传递示例介绍
2014/02/08 Javascript
JS获取地址栏参数的几种方法小结
2014/02/28 Javascript
JS对字符串编码的几种方式使用指南
2015/05/14 Javascript
JS+CSS实现下拉列表框美化效果(3款)
2015/08/15 Javascript
Javascript实现汉字和拼音互转的终极方案
2016/10/19 Javascript
探讨AngularJs中ui.route的简单应用
2016/11/16 Javascript
Mac系统下Webstorm快捷键整理大全
2017/05/28 Javascript
详解vue+vueRouter+webpack的简单实例
2017/06/17 Javascript
vuex2中使用mapGetters/mapActions报错的解决方法
2018/10/20 Javascript
vue组件化中slot的基本使用方法
2019/05/01 Javascript
layui 实现加载动画以及非真实加载进度的方法
2019/09/23 Javascript
微信小程序中网络请求缓存的解决方法
2019/12/29 Javascript
微信小程序实现同时上传多张图片
2020/02/03 Javascript
ES6函数和数组用法实例分析
2020/05/23 Javascript
VueJS实现用户管理系统
2020/05/29 Javascript
Python读取图片属性信息的实现方法
2016/09/11 Python
CentOS 6.5下安装Python 3.5.2(与Python2并存)
2017/06/05 Python
使用XML库的方式,实现RPC通信的方法(推荐)
2017/06/14 Python
对Python中list的倒序索引和切片实例讲解
2018/11/15 Python
django框架实现模板中获取request 的各种信息示例
2019/07/01 Python
python实现可变变量名方法详解
2019/07/01 Python
Scrapy框架实现的登录网站操作示例
2020/02/06 Python
Django windows使用Apache实现部署流程解析
2020/10/12 Python
Web前端页面跳转并取到值
2017/04/24 HTML / CSS
习近平在党的群众路线教育实践活动总结大会上的讲话
2014/10/21 职场文书
学校2014年度工作总结
2014/12/06 职场文书
幼师大班个人总结
2015/02/13 职场文书
预备党员转正意见
2015/06/01 职场文书
2016年小学感恩节活动总结
2016/04/01 职场文书