python多进程下实现日志记录按时间分割

yipeiwu_com6年前Python基础

python多进程下实现日志记录按时间分割,供大家参考,具体内容如下

原理:自定义日志handler继承TimedRotatingFileHandler,并重写computeRollover与doRollover函数。其中重写computeRollover是为了能按整分钟/小时/天来分割日志,如按天分割,2018-04-10 00:00:00~2018-04-11 00:00:00,是一个半闭半开区间,且不是原意的:从日志创建时间或当前时间开始,到明天的这个时候。

代码如下:

#!/usr/bin/env python
# encoding: utf-8

"""自定义日志处理类"""


import os
import time
from logging.handlers import TimedRotatingFileHandler


class MyLoggingHandler(TimedRotatingFileHandler):

  def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None):
    TimedRotatingFileHandler.__init__(self, filename, when=when, interval=interval, backupCount=backupCount, encoding=encoding, delay=delay, utc=utc, atTime=atTime)

  def computeRollover(self, currentTime):
    # 将时间取整
    t_str = time.strftime(self.suffix, time.localtime(currentTime))
    t = time.mktime(time.strptime(t_str, self.suffix))
    return TimedRotatingFileHandler.computeRollover(self, t)

  def doRollover(self):
    """
    do a rollover; in this case, a date/time stamp is appended to the filename
    when the rollover happens. However, you want the file to be named for the
    start of the interval, not the current time. If there is a backup count,
    then we have to get a list of matching filenames, sort them and remove
    the one with the oldest suffix.
    """
    if self.stream:
      self.stream.close()
      self.stream = None
    # get the time that this sequence started at and make it a TimeTuple
    currentTime = int(time.time())
    dstNow = time.localtime(currentTime)[-1]
    t = self.rolloverAt - self.interval
    if self.utc:
      timeTuple = time.gmtime(t)
    else:
      timeTuple = time.localtime(t)
      dstThen = timeTuple[-1]
      if dstNow != dstThen:
        if dstNow:
          addend = 3600
        else:
          addend = -3600
        timeTuple = time.localtime(t + addend)
    dfn = self.rotation_filename(self.baseFilename + "." +
                   time.strftime(self.suffix, timeTuple))
    # 修改内容--开始
    # 在多进程下,若发现dfn已经存在,则表示已经有其他进程将日志文件按时间切割了,只需重新打开新的日志文件,写入当前日志;
    # 若dfn不存在,则将当前日志文件重命名,并打开新的日志文件
    if not os.path.exists(dfn):
      try:
        self.rotate(self.baseFilename, dfn)
      except FileNotFoundError:
        # 这里会出异常:未找到日志文件,原因是其他进程对该日志文件重命名了,忽略即可,当前日志不会丢失
        pass
    # 修改内容--结束
    # 原内容如下:
    """
    if os.path.exists(dfn):
      os.remove(dfn)
    self.rotate(self.baseFilename, dfn)
    """

    if self.backupCount > 0:
      for s in self.getFilesToDelete():
        os.remove(s)
    if not self.delay:
      self.stream = self._open()
    newRolloverAt = self.computeRollover(currentTime)
    while newRolloverAt <= currentTime:
      newRolloverAt = newRolloverAt + self.interval
    # If DST changes and midnight or weekly rollover, adjust for this.
    if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
      dstAtRollover = time.localtime(newRolloverAt)[-1]
      if dstNow != dstAtRollover:
        if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour
          addend = -3600
        else:      # DST bows out before next rollover, so we need to add an hour
          addend = 3600
        newRolloverAt += addend
    self.rolloverAt = newRolloverAt

说明

第一次修改,如有不妥之处,还请指出,不胜感激。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

python正向最大匹配分词和逆向最大匹配分词的实例

正向最大匹配 # -*- coding:utf-8 -*- CODEC='utf-8' def u(s, encoding): 'converted other enco...

Python中itertools模块用法详解

本文实例讲述了Python中itertools模块用法,分享给大家供大家参考。具体分析如下: 一般来说,itertools模块包含创建有效迭代器的函数,可以用各种方式对数据进行循环操作,...

pyqt 实现QlineEdit 输入密码显示成圆点的方法

pyqt 实现QlineEdit 输入密码显示成圆点的方法

使用自带的函数就可以实现: lineEdit.setEchoMode(QLineEdit.Password) import struct from PyQt5.QtWidgets i...

Python操作Sql Server 2008数据库的方法详解

Python操作Sql Server 2008数据库的方法详解

本文实例讲述了Python操作Sql Server 2008数据库的方法。分享给大家供大家参考,具体如下: 最近由于公司的一个项目需要,需要使用Sql Server 2008数据库,开发...

unittest+coverage单元测试代码覆盖操作实例详解

unittest+coverage单元测试代码覆盖操作实例详解

基于上一篇文章,这篇文章是关于使用coverage来实现代码覆盖的操作实例,源代码在上一篇已经给出相应链接。 本篇文章字用来实现代码覆盖的源代码,整个项目的测试框架如下: 就是在源代码...