如何使用logging模块每天创建一个日志文件?

问题描述 投票:0回答:6

我是Python 日志模块的新手。我想在我的应用程序处于运行状态时每天创建一个新的日志文件。

log file name - my_app_20170622.log
log file entries within time - 00:00:01 to 23:59:59

第二天我想创建一个包含第二天日期的新日志文件:

log file name - my_app_20170623.log
log file entries within time - 00:00:01 to 23:59:59

我正在使用Python的日志记录模块。

我正在使用如下:

log_level = int(log_level)
logger = logging.getLogger('simple')
logger.setLevel(log_level)
fh = logging.FileHandler(log_file_name)
fh.setLevel(log_level)
formatter = logging.Formatter(log_format)
fh.setFormatter(formatter)
logger.addHandler(fh)

他们在Python的日志模块中是否有任何配置来每天创建日志?

python logging python-logging
6个回答
63
投票

你必须创建一个

TimedRotatingFileHandler
:

from logging.handlers import TimedRotatingFileHandler
logname = "my_app.log"
handler = TimedRotatingFileHandler(logname, when="midnight", backupCount=30)
handler.suffix = "%Y%m%d"
logger.addHandler(handler)

这段代码将创建一个

my_app.log
,但当当天午夜结束时,日志将被移动到名为
my_app.log.20170623
的新日志文件中。

我希望这有帮助。


14
投票

旋转文件处理程序

class RotatingFileHandler(  filename[, mode[, maxBytes[, backupCount]]])

返回

RotatingFileHandler
class 的新实例。指定的文件将打开并用作日志记录流。如果未指定模式,则使用
a
。默认情况下,文件无限增长。

A

RotatingFileHandler
允许我们在每次当前日志文件达到一定大小时将日志语句轮换到新文件中。

在此示例中,我们将对其进行设置,以便当它达到 500 字节时,我们将轮换到一个新文件,最多可有 2 个备份。

import logging
import logging.handlers as handlers
import time

logger = logging.getLogger('my_app')
logger.setLevel(logging.INFO)

logHandler = handlers.RotatingFileHandler('app.log', maxBytes=500, backupCount=2)
logHandler.setLevel(logging.INFO)
logger.addHandler(logHandler)

def main():
    while True:
        time.sleep(1)
        logger.info("A Sample Log Statement")

main()

执行此操作后,您应该注意到,每当

app.log
超过 500 字节时,它就会被关闭并重命名为
app.log.x
,其中
x
的值会递增,直到达到我们设置的
backupCount
的值。

定时旋转文件处理程序

class TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])

返回

TimedRotatingFileHandler
class 的新实例。指定的文件将打开并用作日志记录流。旋转时它还会设置文件名后缀。旋转根据时间和间隔的乘积发生。

您可以使用when来指定interval的类型。可能值的列表是,请注意它们不区分大小写:

|   Value  |    Type of interval   |
|:--------:|:---------------------:|
|     S    |        Seconds        |
|     M    |        Minutes        |
|     H    |         Hours         |
|     D    |          Days         |
|     W    |  Week day (0=Monday)  |
| midnight | Roll over at midnight |

TimedRotatingFileHandler
允许我们按时间片捕获日志文件。

import logging
import logging.handlers as handlers
import time

logger = logging.getLogger('my_app')
logger.setLevel(logging.INFO)

logHandler = handlers.TimedRotatingFileHandler('timed_app.log', when='M', interval=1)
logHandler.setLevel(logging.INFO)
logger.addHandler(logHandler)

def main():
    while True:
        time.sleep(1)
        logger.info("A Sample Log Statement")

main()

运行此代码将无限期地每分钟创建新的日志文件。我们可以在

backupCount
实例上设置
logHandler
参数,它将限制我们创建的日志文件的数量。

使用适当的日志级别

使用

TimedRotatingFileHandler
RotatingFileHandler
可以执行以下操作,例如将所有错误消息记录到旋转文件,但将所有正常日志文件记录到 TimedRotatingFileHandler,因为我们希望我们可以期望它们比错误消息。

两个级别的记录被拆分为两个不同的日志级别:

INFO
ERROR
到两个不同的地方。

import logging
import logging.handlers as handlers
import time

logger = logging.getLogger('my_app')
logger.setLevel(logging.INFO)

## Here we define our formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logHandler = handlers.TimedRotatingFileHandler('normal.log', when='M', interval=1, backupCount=0)
logHandler.setLevel(logging.INFO)
logHandler.setFormatter(formatter)

errorLogHandler = handlers.RotatingFileHandler('error.log', maxBytes=5000, backupCount=0)
errorLogHandler.setLevel(logging.ERROR)
errorLogHandler.setFormatter(formatter)

logger.addHandler(logHandler)
logger.addHandler(errorLogHandler)

def main():
    while True:
        time.sleep(1)
        logger.info("A Sample Log Statement")
        logger.error("An error log statement")

main()

您应该注意到,运行此命令时会创建 3 个日志文件。

error.log
将仅包含级别为
ERROR
或更高级别的日志。
normal.log
将包含从我们的应用程序中注销的所有日志消息的组合。

这些只是我认为在实现自己的日志系统时很重要的一些事情。


7
投票

终于,我得到了正确的答案,我想分享这个答案。

基本上,需要创建一个 TimedRotatingFileHandler 如下 -

log_format = "%(asctime)s - %(levelname)s - %(message)s"
log_level = 10
handler = TimedRotatingFileHandler("my_app.log", when="midnight", interval=1)
handler.setLevel(log_level)
formatter = logging.Formatter(log_format)
handler.setFormatter(formatter)

# add a suffix which you want
handler.suffix = "%Y%m%d"

#need to change the extMatch variable to match the suffix for it
handler.extMatch = re.compile(r"^\d{8}$") 

# finally add handler to logger    
logger.addHandler(handler)

上面的代码将生成当天的 my_app.log 和前一天的 my_app.log.20170704 之类的文件。

希望有帮助。


3
投票

TimedRotatingFileHandler 可用于此目的。请参考以下代码。

from logging.config import dictConfig
import logging

dictConfig({
    'version': 1,
    'formatters': {
        'standard': {
            'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
        }
    },
    'handlers': {
        'myapp_handler': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': './my_app.log',
            'when': 'd',
            'interval': 1,
            'backupCount': 30,
            'level': 'DEBUG',
            "encoding": "utf8",
            'formatter': 'standard'
        },
    },
    'loggers': {
        'simple': {
            'level': 'DEBUG',
            'handlers': ['myapp_handler']
        }
    },
})


logger = logging.getLogger("simple")

logger.error("This is a test error")

在上面的示例中,我使用 dictConfig 来配置记录器。请参考链接:https://docs.python.org/3/library/logging.config.html了解其他配置方式。

一旦日期更改,记录器模块就会通过在当前文件后加上日期后缀来创建一个新文件。


1
投票

我建议你看看

logging.handlers.TimedRotatingFileHandler
。 我想这就是你要找的。


0
投票

如果您在创建日志文件时仅使用默认附加选项,请在文件名中的某处使用今天的日期

YYYYMMDD
。它只会附加到已创建的日志文件中,否则它将创建该文件。当然,如果您希望日志在午夜开始和结束,则此方法有效,如果您希望日志在一天中的特定时间切换,则此方法将不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.