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 相关文章推荐
wxPython使用系统剪切板的方法
Jun 16 Python
使用Python的Django框架结合jQuery实现AJAX购物车页面
Apr 11 Python
Python中optparser库用法实例详解
Jan 26 Python
Pandas 同元素多列去重的实例
Jul 03 Python
详解Django+Uwsgi+Nginx 实现生产环境部署
Nov 06 Python
python读csv文件时指定行为表头或无表头的方法
Jun 26 Python
Python3环境安装Scrapy爬虫框架过程及常见错误
Jul 12 Python
Python DataFrame一列拆成多列以及一行拆成多行
Aug 06 Python
pytorch获取模型某一层参数名及参数值方式
Dec 30 Python
Pytorch 搭建分类回归神经网络并用GPU进行加速的例子
Jan 09 Python
浅析Python 抽象工厂模式的优缺点
Jul 13 Python
Jupyter Notebook内使用argparse报错的解决方案
Jun 03 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使用array_rand()函数从数组中随机选择一个或多个元素
2014/04/28 PHP
php实现的太平洋时间和北京时间互转的自定义函数分享
2014/08/19 PHP
PHP生成不重复随机数的方法汇总
2014/11/19 PHP
PHP按指定键值对二维数组进行排序的方法
2015/12/22 PHP
php实现图片上传时添加文字和图片水印技巧
2020/04/18 PHP
php正则判断是否为合法身份证号的方法
2017/03/16 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
thinkPHP5框架接口写法简单示例
2019/08/05 PHP
php实现统计IP数及在线人数的示例代码
2020/07/22 PHP
Nigma vs Alliance BO5 第五场2.14
2021/03/10 DOTA
javascript控制frame,iframe的src属性代码
2009/12/31 Javascript
创建公共调用 jQuery Ajax 带返回值
2012/08/01 Javascript
微信小程序 es6-promise.js封装请求与处理异步进程
2017/06/12 Javascript
vue-quill-editor实现图片上传功能
2017/08/08 Javascript
Node.js 中使用 async 函数的方法
2017/11/20 Javascript
vue 点击按钮实现动态挂载子组件的方法
2018/09/07 Javascript
swiper在angularjs中使用循环轮播失效的解决方法
2018/09/27 Javascript
javascript中一些奇葩的日期换算方法总结
2018/11/14 Javascript
微信小程序云开发如何使用npm安装依赖
2019/05/18 Javascript
Vue实现数据请求拦截
2019/10/23 Javascript
python中将字典形式的数据循环插入Excel
2018/01/16 Python
python去除文件中重复的行实例
2018/06/29 Python
Python实战购物车项目的实现参考
2019/02/20 Python
python pytest进阶之xunit fixture详解
2019/06/27 Python
Python日志器使用方法及原理解析
2020/09/27 Python
利用CSS3参考手册和CSS3代码生成工具加速来学习网页制
2012/07/11 HTML / CSS
马来西亚时装购物网站:ZALORA马来西亚
2017/03/14 全球购物
枚举与#define宏的区别
2014/04/30 面试题
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
酒店保洁主管岗位职责
2013/11/28 职场文书
学期自我评价
2014/01/27 职场文书
12月小学生校园广播稿
2014/02/04 职场文书
2014乡镇“三八”国际劳动妇女节活动总结
2014/03/01 职场文书
2015年基层党组织公开承诺书
2015/01/21 职场文书
毕业生党员个人总结
2015/02/14 职场文书
小数乘法教学反思
2016/02/22 职场文书