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实现支持目录FTP上传下载文件的方法
Jun 03 Python
玩转python爬虫之URLError异常处理
Feb 17 Python
Python实现的当前时间多加一天、一小时、一分钟操作示例
May 21 Python
Python 字符串转换为整形和浮点类型的方法
Jul 17 Python
Python网络爬虫之爬取微博热搜
Apr 18 Python
Python OpenCV 调用摄像头并截图保存功能的实现代码
Jul 02 Python
在Django model中设置多个字段联合唯一约束的实例
Jul 17 Python
Django使用模板后无法找到静态资源文件问题解决
Jul 19 Python
Python Celery多队列配置代码实例
Nov 22 Python
使用Python实现微信拍一拍功能的思路代码
Jul 09 Python
如何使用scrapy中的ItemLoader提取数据
Sep 30 Python
聊聊Python pandas 中loc函数的使用,及跟iloc的区别说明
Mar 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
日本收入最高的漫画家:海贼王作者版税年收入高达8.45亿元
2020/03/04 日漫
Syphon 秘笈
2021/03/03 冲泡冲煮
php获取表单中多个同名input元素的值
2014/03/20 PHP
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
set_exception_handler函数在ThinkPHP中的用法
2014/10/31 PHP
9条PHP编程小知识及易犯的小错误
2015/01/22 PHP
浅谈php中urlencode与rawurlencode的区别
2016/09/05 PHP
用Javascript数组处理多个字符串的连接问题
2009/08/20 Javascript
高亮显示web页表格行的javascript代码
2010/11/19 Javascript
JQuery写动态树示例代码
2013/07/31 Javascript
js将字符串转成正则表达式的实现方法
2013/11/13 Javascript
利用yarn实现一个webpack+react种子
2016/10/25 Javascript
js输入框使用正则表达式校验输入内容的实例
2017/02/12 Javascript
Vue不能观察到数组length的变化
2018/06/08 Javascript
vue兄弟组件传递数据的实例
2018/09/06 Javascript
jQuery实现轮播图源码
2019/10/23 jQuery
vue3.0 上手体验
2020/09/21 Javascript
python统计cpu利用率的方法
2015/06/02 Python
python中zip()方法应用实例分析
2016/04/16 Python
python 截取 取出一部分的字符串方法
2017/03/01 Python
解决python中使用plot画图,图不显示的问题
2018/07/04 Python
Python API 操作Hadoop hdfs详解
2020/06/06 Python
Python 利用OpenCV给照片换底色的示例代码
2020/08/03 Python
快速一键生成Python爬虫请求头
2021/03/04 Python
HTML5 canvas 基本语法
2009/08/26 HTML / CSS
香港化妆品经销商:我的公主
2016/08/05 全球购物
MONNIER Frères英国官网:源自巴黎女士奢侈品配饰电商平台
2018/12/06 全球购物
linux面试题参考答案(9)
2015/01/07 面试题
用Java语言将一个键盘输入的数字转化成中文输出
2013/01/25 面试题
质量保证书
2015/01/17 职场文书
国博复兴之路观后感
2015/06/02 职场文书
社会实践单位意见
2015/06/05 职场文书
2016年第32个教师节致辞
2015/11/26 职场文书
2016年感恩节寄语
2015/12/07 职场文书
JS 基本概念详细介绍
2021/10/16 Javascript
MySQL数据库如何查看表占用空间大小
2022/06/10 MySQL