Need to do a daily log rotation (0utc) using Python

帅比萌擦擦* 提交于 2019-12-04 18:47:35

For anyone arriving via Google, please don't move the log file out from under the logger while it is in use by calling the system copy of move commands or etc.

What you are looking for is a TimedRotatingFileHandler:

import time

import logging
from logging.handlers import TimedRotatingFileHandler

# format the log entries
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s')

handler = TimedRotatingFileHandler('/path/to/logfile.log', 
                                   when='midnight',
                                   backupCount=10)
handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

# generate example messages
for i in range(10000):
    time.sleep(1)
    logger.debug('debug message')
    logger.info('informational message')
    logger.warn('warning')
    logger.error('error message')
    logger.critical('critical failure')

You can simply do this:

import os
import time
date1 = time.strftime('%Y%m%d%H%M%S')
cmd1= "cp logfile logfile{0}".format(date1)
cmd2= "cat /dev/null > logfile"
os.system(cmd1)
os.system(cmd2)

'logfile' is the name of the file. I have copied the older log a new log file with a name based on time and date and then emptied the original file. If you want to rotate it every one hour, put this script in cron.

For anyone who does not like the idea of rotating files, but simply wants to use a file handler that immediately writes to a file with a specific date in its name: it is not hard to write your own handler. Here is an example:

class FileHandlerWithOneFilePerPeriod(FileHandler):
"""A handler which writes formatted logging records to files, one file per period."""

def __init__(self, filename_pattern, mode='a', encoding=None, delay=False):
    """
    Constructs the file handler.

    :param filename_pattern: the filename. Use strftime() directives to specify the format of the period.
    For example, %Y%m%d can be used to generate one log file per day.
    :param mode: the mode to open the file before writing. Common values are 'w' for writing (truncating the file
    if it already exists), 'x' for creating and writing to a new file, and 'a' for appending (which on some Unix
    systems, means that all writes append to the end of the file regardless of the current seek position).
    :param encoding: encoding is the name of the encoding used to decode or encode the file. This should only be
    used in text mode.
    :param delay: True if the file is opened when the first log message is emitted; False if the file is opened now
    by the constructor.
    """
    self.filename_pattern = filename_pattern
    filename = datetime.now().strftime(self.filename_pattern)
    super().__init__(filename, mode, encoding, delay)

def emit(self, record: LogRecord):
    new_filename = datetime.fromtimestamp(record.created).strftime(self.filename_pattern)
    if self.stream is None:
        self.set_new_filename(new_filename)
    elif self.differs_from_current_filename(new_filename):
        self.close()
        self.set_new_filename(new_filename)

    super().emit(record)

def set_new_filename(self, new_filename):
    self.baseFilename = new_filename

def differs_from_current_filename(self, filename: str) -> bool:
    return filename != self.baseFilename

To use this handler, configure it with the following values in a dictionary (using logging.config.dictConfig():

version: 1
formatters:
  simple:
    format: '%(asctime)s %(name)s %(levelname)s %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
  file:
    class: my_package.my_module.FileHandlerWithOneFilePerPeriod
    level: DEBUG
    formatter: simple
    filename_pattern: my_logging-%Y%m%d.log
root:
  level: DEBUG
  handlers: [console, file]

This will log to console and to file. One file per day is used. Change my_package and my_module to match the module where you put the handler. Change my_logging to a more appropriate name.

By changing the date pattern in filename_pattern you actually control when new files are created. Each time the pattern applied to the datetime a log message is created differs from the previous applied pattern, a new file will be created.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!