为什么python日志模块旋转日志日志搞乱了?

时间:2016-02-23 07:25:03

标签: python logging logrotate

我想在python2.7,uWSGI,master / worker,多个进程中按天轮换两个日志文件。我写了一个名为logger.py的通用记录器。

import yaml

import logging, logging.config
log_conf = yaml.load(open('logger.yaml'))
logging.config.dictConfig(log_conf)

logger = logging.getLogger('access')
exc_logger = logging.getLogger('exception')

其他模块写这样的日志。

from logger import logger, exc_logger
...
logger.error('Req index error | err=%s', e)
exc_logger.exception('Req index error')

这是配置文件logger.yaml。

version: 1
disable_existing_loggers: False

formatters:
    simple:
        format: '%(asctime)s | %(name)8s | %(levelname)s | %(message)s'
        datefmt: '%Y-%m-%d %H:%M:%S'
    detailed:
        format: '%(asctime)s | %(process)d | %(levelname)s | %(filename)s | %(lineno)d | %(funcName)s | %(message)s'
        datefmt: '%Y-%m-%d %H:%M:%S'

handlers:
    console:
        class: logging.StreamHandler
        level: DEBUG
        formatter: detailed
        stream: ext://sys.stdout

    access_file_handler:
        class: logging.handlers.TimedRotatingFileHandler
        level: DEBUG
        formatter: detailed
        filename: log/access.log
        backupCount: 30
        encoding: utf8
        when: D
        interval: 1
        delay: True

    exception_file_handler:
        class: logging.handlers.TimedRotatingFileHandler
        level: ERROR
        formatter: detailed
        filename: log/exception.log
        backupCount: 30
        encoding: utf8
        when: D
        interval: 1
        delay: True

loggers:
    access:
        level: DEBUG
        handlers: [console, access_file_handler]
        propagate: no

    exception:
        level: ERROR
        handlers: [console, exception_file_handler]

问题是日志的日期与文件名的日期不匹配。例如,以下是access.log.2016-02-17的日志。

2016-02-19 09:43:10 | 7065 | INFO | ...
2016-02-19 09:43:10 | 7065 | INFO | ...
...
2016-02-20 09:05:59 | 7065 | INFO | ...
2016-02-20 09:05:59 | 7065 | INFO | ...
...

为什么?我做错了吗?

2 个答案:

答案 0 :(得分:2)

在阅读了TimedRotatingFileHandler的源代码之后,终于弄明白了发生了什么。

when的参数应为midnight,而不是Dmidnight表示午夜轮换。这正是我想要的。

D表示在interval天之后轮换。如果interval的值为1,并且应用程序在10:00开始,那么旋转将在第二天的10:00之后发生。同一日志文件中将有两个日期。如果您在第二天9:00后重新启动应用程序,则在第二天后的第二天之后轮流将延迟到9:00。同一日志文件中将有三个日期。

答案 1 :(得分:0)

在配置文件中设置delay = True。

  

如果延迟为真,则文件打开将推迟到第一次调用   发射()。

https://docs.python.org/2/library/logging.handlers.html#timedrotatingfilehandler

这意味着日志文件从第一条日志消息开始。

可能存在一个问题,即文件名是在实际打开日志文件之前定义的,导致文件名与日志文件中的日期不匹配