如何在Flask中根据日志级别将日志分开保存到不同文件

文章目录

在 Flask 应用程序中,合理的日志管理对于排查问题和维护应用非常重要。通过将日志根据不同的级别分别保存到不同的文件,可以更有效地管理和分析日志数据。本文将详细介绍如何实现这一功能,包括自定义日志类和处理器的设置。

自定义 Flask 日志处理器:将日志按级别分类存储

1. 自定义日志类

Flask 框架及其底层的 Werkzeug 使用默认的 Logger。为了将日志按级别分开存储,首先需要自定义一个 Logger,并重写callHandlers方法。这样,只有当日志记录的级别等于处理器设置的级别时,处理器才会处理该日志记录。

示例代码

以下是自定义 Logger 的实现代码:

import os
import logging
import logging.handlers
import sys
from logging import raiseExceptions
from logging import Logger

LOG_PATH = '/tmp/'

class AppLogger(Logger):
    '''自定义logger,依据日志级别分配handler'''

    def __init__(self, name, level=logging.NOTSET):
        super(AppLogger, self).__init__(name, level)

    def callHandlers(self, record):
        c = self
        found = 0
        while c:
            for hdlr in c.handlers:
                found += 1
                if hdlr.name == 'console':
                    if record.levelno >= hdlr.level:
                        hdlr.handle(record)
                else:
                    if record.levelno == hdlr.level:
                        hdlr.handle(record)
            if not c.propagate:
                c = None
            else:
                c = c.parent
        if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
            sys.stderr.write("No handlers could be found for logger \"%s\"\n" % self.name)
            self.manager.emittedNoHandlerWarning = 1

def get_logger(logfile_name=__name__, log_path=LOG_PATH):
    '''根据日志级别将日志保存到不同文件,并在控制台打印所有日志'''
    logging.setLoggerClass(AppLogger)
    formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s', '%Y-%m-%d %H:%M:%S')

    log_files = {
        logging.DEBUG: os.path.join(log_path, logfile_name + '-debug.log'),
        logging.INFO: os.path.join(log_path, logfile_name + '-info.log'),
        logging.WARNING: os.path.join(log_path, logfile_name + '-warning.log'),
        logging.ERROR: os.path.join(log_path, logfile_name + '-error.log'),
        logging.CRITICAL: os.path.join(log_path, logfile_name + '-critical.log')
    }

    logger = logging.getLogger('werkzeug')  # 使用Flask默认logger
    logger.setLevel(logging.DEBUG)

    for log_level, log_file in log_files.items():
        file_handler = logging.handlers.TimedRotatingFileHandler(log_file, 'midnight')
        file_handler.setLevel(log_level)
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)

    console_handler = logging.StreamHandler()
    console_handler.name = "console"
    console_handler.setLevel(logging.DEBUG)
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)

    return logger

logger = get_logger()

2. Flask 应用示例

在 Flask 应用中调用上述自定义日志功能的代码示例如下:

from log import logger
from flask import Flask

app = Flask(__name__)
app.debug = True

@app.route("/")
def hello():
    return "Hello World!"

logger.debug('Debug message')
logger.info('Info message')
logger.error('Error message')
logger.warning('Warning message')

if __name__ == '__main__':
    app.run()

3. 日志输出结果

运行 Flask 应用后,可以在控制台看到所有级别的日志信息,同时在指定目录下生成按级别分类的日志文件。例如,所有 DEBUG 级别的日志将保存到/tmp/yourappname-debug.log中,而 INFO 级别的日志将保存到/tmp/yourappname-info.log中,以此类推。

结论

通过上述方法,可以轻松地实现 Flask 日志的分级存储,使得日志管理更为高效。无论是开发阶段还是生产环境,合理的日志策略都将大大提高应用的可维护性。希望本文能帮助您更好地理解和实现 Flask 中的日志管理。


也可以看看