通过TimedRotatingFileHandler按时间切割日志


线上跑了一个定时脚本,每天生成的日志文件都写在了一个文件中。但是日志信息不可能输出到单一的一个文件中。

原因有二:1.日志文件越来越大会影响系统的性能。2.日志文件格式不够清晰,比如我想看今天的日志,不太方便找到的今天的日志信息(即使对日志输出做了时间提示)

通过设置TimedRotatingFileHandler进行日志按周(W)、天(D)、时(H)、分(M)、秒(S)切割。

先看一个简单例子:

  1. import time
  2. import logging
  3. import os
  4. from logging import handlers
  5. def _logging(**kwargs):
  6. level = kwargs.pop('level', None)
  7. filename = kwargs.pop('filename', None)
  8. datefmt = kwargs.pop('datefmt', None)
  9. format = kwargs.pop('format', None)
  10. if level is None:
  11. level = logging.DEBUG
  12. if filename is None:
  13. filename = 'default.log'
  14. if datefmt is None:
  15. datefmt = '%Y-%m-%d %H:%M:%S'
  16. if format is None:
  17. format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
  18. log = logging.getLogger(filename)
  19. format_str = logging.Formatter(format, datefmt)
  20. # backupCount 保存日志的数量,过期自动删除
  21. # when 按什么日期格式切分(这里方便测试使用的秒)
  22. th = handlers.TimedRotatingFileHandler(filename=filename, when='S', backupCount=3, encoding='utf-8')
  23. th.setFormatter(format_str)
  24. th.setLevel(logging.INFO)
  25. log.addHandler(th)
  26. log.setLevel(level)
  27. return log
  28. os.makedirs("./logs", exist_ok=True)
  29. logger = _logging(filename='./logs/default.log')
  30. if __name__ == '__main__':
  31. while True:
  32. time.sleep(0.1)
  33. logger.info('哈哈哈')

结果如下:

上述代码可以正常运行,而且也可以生成固定的日志个数,但是有一个问题,生成的日志文件格式是你的文件名+时间的格式,没有设置时间的话默认设置到了秒(这里是按秒切割)

修改日志格式后缀名称:

  1. # 在上述代码中加入
  2. def namer(filename):
  3. return filename.split('default.')
  4. th.namer = namer
  5. # 设置为S,默认的suffix为 Y-%m-%d_%H-%M-%S
  6. th.suffix = "%Y-%m-%d_%H-%M-%S.log"
  7. # 为了看的更视觉效果,可以显示在控制台答应
  8. cmd = logging.StreamHandler()
  9. cmd.setFormatter(format_str)
  10. cmd.setLevel(level)
  11. log.addHandler(cmd)

运行结果:

名字好像可以了,但是日志好像没有起到自动删除的目的啊,而且也没在之前的log文件夹了。

来看看源码:

  1. def getFilesToDelete(self):
  2. """
  3. Determine the files to delete when rolling over.
  4. More specific than the earlier method, which just used glob.glob().
  5. """
  6. dirName, baseName = os.path.split(self.baseFilename)
  7. fileNames = os.listdir(dirName)
  8. result = []
  9. prefix = baseName + "."
  10. plen = len(prefix)
  11. for fileName in fileNames:
  12. if fileName[:plen] == prefix:
  13. suffix = fileName[plen:]
  14. if self.extMatch.match(suffix):
  15. result.append(os.path.join(dirName, fileName))
  16. if len(result) < self.backupCount:
  17. result = []
  18. else:
  19. result.sort()
  20. result = result[:len(result) - self.backupCount]
  21. return result

这是它的删除逻辑,关键是通过.前面的字段判断是否重复,当有特定的重复数后开始删除。

所以问题来了,要么自己去重写源码,要么就只能用default.日期.log这种格式了。

附上平时使用的日志代码

  1. import logging
  2. import os
  3. from logging import handlers
  4. def _logging(**kwargs):
  5. level = kwargs.pop('level', None)
  6. filename = kwargs.pop('filename', None)
  7. datefmt = kwargs.pop('datefmt', None)
  8. format = kwargs.pop('format', None)
  9. if level is None:
  10. level = logging.DEBUG
  11. if filename is None:
  12. filename = 'default.log'
  13. if datefmt is None:
  14. datefmt = '%Y-%m-%d %H:%M:%S'
  15. if format is None:
  16. format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
  17. log = logging.getLogger(filename)
  18. format_str = logging.Formatter(format, datefmt)
  19. def namer(filename):
  20. return filename.split('default.')[1]
  21. # cmd = logging.StreamHandler()
  22. # cmd.setFormatter(format_str)
  23. # cmd.setLevel(level)
  24. # log.addHandler(cmd)
  25. os.makedirs("./debug/logs", exist_ok=True)
  26. th_debug = handlers.TimedRotatingFileHandler(filename="./debug/" + filename, when='D', backupCount=3,
  27. encoding='utf-8')
  28. # th_debug.namer = namer
  29. th_debug.suffix = "%Y-%m-%d.log"
  30. th_debug.setFormatter(format_str)
  31. th_debug.setLevel(logging.DEBUG)
  32. log.addHandler(th_debug)
  33. th = handlers.TimedRotatingFileHandler(filename=filename, when='D', backupCount=3, encoding='utf-8')
  34. # th.namer = namer
  35. th.suffix = "%Y-%m-%d.log"
  36. th.setFormatter(format_str)
  37. th.setLevel(logging.INFO)
  38. log.addHandler(th)
  39. log.setLevel(level)
  40. return log
  41. os.makedirs('./logs', exist_ok=True)
  42. logger = _logging(filename='./logs/default')

python通过TimedRotatingFileHandler按时间切割日志的更多相关文章

  1. zap+日志分级分文件+按时间切割日志整合demo

    实现功能     info debug 级别的日志输出到 /path/log/demo.log     warn error .... 级别的日志输出到 /path/log/demo_error.lo ...

  2. python 多线程日志切割+日志分析

    python 多线程日志切割+日志分析 05/27. 2014 楼主最近刚刚接触python,还是个小菜鸟,没有学习python之前可以说楼主的shell已经算是可以了,但用shell很多东西实现起来 ...

  3. Nginx服务优化及优化深入(配置网页缓存时间、日志切割、防盗链等等)

    原文:https://blog.51cto.com/11134648/2134389 默认的Nginx安装参数只能提供最基本的服务,还需要调整如网页缓存时间.连接超时.网页压缩等相应参数,才能发挥出服 ...

  4. python实现根据当前时间创建目录并输出日志

    举个例子:比如我们要实现根据当前时间的年月日来新建目录来存放每天的日志,当前时间作为日志文件名称:代码如下: #!/usr/bin/env python3 # _*_ coding: utf-8 _* ...

  5. python:利用logbook模块管理日志

    日志管理作为软件项目的通用部分,无论是开发还是自动化测试过程中,都显得尤为重要. 最初是打算利用python的logging模块来管理日志的,后来看了些github及其他人的自动化框架设计,做了个比对 ...

  6. nginx按天切割日志

    原文链接:http://www.cnblogs.com/benio/archive/2010/10/13/1849935.html  本文只节选部分内容 Nginx自己没有日志分割的功能,一旦时间过长 ...

  7. 【转】Python之日期与时间处理模块(date和datetime)

    [转]Python之日期与时间处理模块(date和datetime) 本节内容 前言 相关术语的解释 时间的表现形式 time模块 datetime模块 时间格式码 总结 前言 在开发工作中,我们经常 ...

  8. [Java][log4j]支持同一时候按日期和文件大小切割日志

    依据DailyRollingFileAppender和RollingFileAppender改编,支持按日期和文件大小切割日志.  源文件: package com.bao.logging; impo ...

  9. python统计apache、nginx访问日志IP访问次数并且排序(显示前20条)【转】

    前言:python统计apache.nginx访问日志IP访问次数并且排序(显示前20条).其实用awk+sort等命令可以实现,用awk数组也可以实现,这里只是用python尝试下.   apach ...

随机推荐

  1. WPF 为资源字典 添加事件响应的后台类

    原文:WPF 为资源字典 添加事件响应的后台类 前言,有许多同学在写WPF程序时在资源字典里加入了其它控件,但又想写事件来控制这个控件,但是资源字典没有CS文件,不像窗体XAML还有一个后台的CS文件 ...

  2. 图像滤镜艺术---Oilpaint油画滤镜

    原文:图像滤镜艺术---Oilpaint油画滤镜  Oilpaint油画滤镜     图像油画效果实际上是将图像边缘产生一种朦胧,雾化的效果,同时,将一定的边缘模糊化,这样图像整体上看去像素与像素之间 ...

  3. GIS基础软件及操作(八)

    原文 GIS基础软件及操作(八) 练习八.地理建模 地理建模:Model Builder 土壤侵蚀危险性建模分析 认识ModelBuilder操作界面 1: 添加硬盘上的数据或工具到模型中,数据也可以 ...

  4. js判断图片是否存在

    var imageData = Array(); for(var i = 0; i < imageTemp.length; i++){ ajaxSizeRequest = $.ajax({ ty ...

  5. QPixmap的缓冲区

    我想qt 中QPixmap这个类大家都很熟悉,它可以很简单的在标签上贴图:例如: QPixmap p; p.load("1.png"): label->setPixmap(p ...

  6. Qt之Model-View架构(雨田哥的博客)

    Qt之Model-View架构 Qt之Model-View架构 简述 效果图 代码 结尾 简述 为什么会用这个模式,这里我就不解释了,可以看下 豆子哥的见解 .这里我只是如何去使用的.供大家共同探讨学 ...

  7. 利用批处理自动创建schtasks系统任务

    通过批处理自动创建schtasks系统任务,把下列代码保存成bat文件,放到要执行的文件的同级目录即可. @echo on set curpath=%cd%c:cd %systemroot%schta ...

  8. 设计模式之单例模式的几种写法——java

    对于设计模式的使用场景和好处,之前有介绍一篇,今天主要是单例模式的编写方式,直接看代码吧 单例模式之饿汉模式,不会懒加载.线程安全 /** * @Author wangtao * @Descripti ...

  9. Java 添加、修改PPT幻灯片中的表格

    本文将介绍通过Java编程在PPT操作表格的方法.包括添加表格到PPT幻灯片,并设置表格样式.单元格对齐方式.单元格背景色.边框样式.字体.字号.合并单元格等:同时,通过加载已有表格的幻灯片也可以对表 ...

  10. VsCode 常用快捷键、debug菜单、debug插件

    常用快捷键emmet                   百度emmet即可知  Ctrl + P            转到文件Ctrl+鼠标左键不松手     预览代码Ctrl+鼠标左键松手    ...