算法代码日志单独写入独立文件

一 分模块解读

1.1 导入模块

  • logging: Python 标准库中的日志模块,用于记录日志。
  • RotatingFileHandler: logging.handlers 中的类,用于创建滚动日志文件。
  • os: 用于处理文件和目录操作。
import logging
from logging.handlers import RotatingFileHandler
import os

1.2 设置过滤条件 (LoggerFilter 类)

  • init: 初始化过滤器,接受三个参数 log_name, total_log, 和 data_log

    • log_name: 该过滤器应用于的日志名称。
    • total_log: 记录总日志的日志名称。
    • data_log: 记录数据日志的日志名称。
  • filter: 根据日志记录的名称进行过滤。

    • 如果 log_nametotal_log,则过滤掉 data_log 的日志记录。
    • 否则,只保留 data_log 的日志记录。
class LoggerFilter(logging.Filter):
    def __init__(self, log_name, total_log, data_log):
        super().__init__(log_name)
        self.log_name = log_name
        self.total_log = total_log
        self.data_log = data_log

    def filter(self, record):
        if self.log_name == self.total_log:
            return record.name != self.data_log
        return record.name == self.data_log

1.3 filter_logging 函数

  • log_folder: 日志文件存储目录。如果目录不存在,则创建该目录。
def filter_logging(total_log, data_log, log_level=logging.INFO):
    """
    初始化日志配置,将日志输出到文件和控制台
    """
    log_folder = './log_file'
    if not os.path.exists(log_folder):
        os.makedirs(log_folder)

log_formatter: 配置日志格式。

  • %(asctime)s: 日志事件的时间戳。
  • %(msecs)03d: 毫秒部分,3位数字。
  • %(levelname)s: 日志级别名称。
  • %(name)s: 日志记录器的名称。
  • %(lineno)d: 产生日志记录的代码行号。
  • %(filename)s: 产生日志记录的文件名。
  • %(message)s: 日志消息。
    log_formatter = logging.Formatter(
        '[%(asctime)s.%(msecs)03d] [%(levelname)s] [%(name)s] [line:%(lineno)d] '
        '%(filename)s: \t%(message)s', datefmt='%Y-%m-%d %H:%M:%S'
    )

console_handler: 配置控制台日志处理器。

  • 设置日志格式。
  • 设置日志级别。
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(log_formatter)
    console_handler.setLevel(log_level)
  • loggers: 包含总日志和数据日志的文件路径。
  • file_handlers: 用于存储文件处理器。
    loggers = {
        total_log: f'{log_folder}/{total_log}.log',
        data_log: f'{log_folder}/{data_log}.log'
    }

    file_handlers = []
  • RotatingFileHandler: 创建滚动日志文件处理器。
    • log_file: 日志文件路径。
    • mode='a': 追加模式。
    • maxBytes=int(1e7): 每个日志文件最大10MB。
    • backupCount=7: 保留7个旧文件。
  • addFilter: 为文件处理器添加过滤器。
  • file_handlers.append: 将文件处理器添加到列表中
    for logger_name, log_file in loggers.items():
        file_handler = RotatingFileHandler(log_file, mode='a', maxBytes=int(1e7), backupCount=7)
        file_handler.setFormatter(log_formatter)
        file_handler.setLevel(log_level)
        file_handler.addFilter(LoggerFilter(logger_name, total_log, data_log))
        file_handlers.append(file_handler)

logging.basicConfig: 配置全局日志系统。

  • 设置日志级别。
  • 设置日期格式。
  • 添加处理器(控制台和文件处理器)。
    logging.basicConfig(level=log_level,
                        datefmt='%Y-%m-%d %H:%M:%S',
                        handlers=[console_handler] + file_handlers
                        )
  • main_logger: 获取或创建名为 total_log 的日志记录器实例。
  • logging.info: 记录一条 "Start write logging" 信息。
    main_logger = logging.getLogger(total_log)
    logging.info("Start write logging")
    return main_logger

1.4 示例

  • filter_logging: 调用 filter_logging 函数,初始化日志系统。
  • total_logger: 获取或创建名为 total_log 的日志记录器实例,记录不同级别的日志消息。
  • data_logger: 获取或创建名为 data_log 的日志记录器实例,记录不同级别的日志消息。

这个代码配置了一个日志系统,能够将日志消息按不同的名称过滤到不同的文件中,同时在控制台输出。

if __name__ == "__main__":
    main_logger = filter_logging("total_log", "data_log", logging.INFO)

    total_logger = logging.getLogger("total_log")
    total_logger.info("This is an info message for total_log")
    total_logger.debug("This is a debug message for total_log")
    total_logger.error("This is an error message for total_log")

    data_logger = logging.getLogger("data_log")
    data_logger.info("This is an info message for data_log")
    data_logger.debug("This is a debug message for data_log")
    data_logger.error("This is an error message for data_log")

二 完整日志写入格式代码

为了确保将基础配置应用到全局日志系统,可以在 filter_logging 函数中使用 logging.basicConfig 方法进行配置。需要注意的是,basicConfig 只能配置一次,所以要确保在首次配置时包括所有必要的处理程序。

import logging
from logging.handlers import RotatingFileHandler
import os

class LoggerFilter(logging.Filter):
    def __init__(self, log_name, total_log, data_log):
        super().__init__(log_name)
        self.log_name = log_name
        self.total_log = total_log
        self.data_log = data_log

    def filter(self, record):
        if self.log_name == self.total_log:
            return record.name != self.data_log
        return record.name == self.data_log

def filter_logging(total_log, data_log, log_level=logging.INFO):
    """
    初始化日志配置,将日志输出到文件和控制台
    """
    log_folder = './log_file'
    # 如果文件夹不存在,创建文件夹
    if not os.path.exists(log_folder):
        os.makedirs(log_folder)

    # 配置日志格式
    log_formatter = logging.Formatter(
        '[%(asctime)s.%(msecs)03d] [%(levelname)s] [%(name)s] [line:%(lineno)d] '
        '%(filename)s: \t%(message)s', datefmt='%Y-%m-%d %H:%M:%S'
    )

    # 创建控制台日志处理器
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(log_formatter)
    console_handler.setLevel(log_level)

    # 配置文件日志处理器
    loggers = {
        total_log: f'{log_folder}/{total_log}.log',
        data_log: f'{log_folder}/{data_log}.log'
    }

    file_handlers = []

    for logger_name, log_file in loggers.items():
        file_handler = RotatingFileHandler(log_file, mode='a', maxBytes=int(1e7), backupCount=7)
        file_handler.setFormatter(log_formatter)
        file_handler.setLevel(log_level)
        file_handler.addFilter(LoggerFilter(logger_name, total_log, data_log))
        file_handlers.append(file_handler)

    # 将配置应用到全局日志系统
    logging.basicConfig(level=log_level,
                        datefmt='%Y-%m-%d %H:%M:%S',
                        handlers=[console_handler] + file_handlers  # encoding='utf-8'
                        )

    main_logger = logging.getLogger(total_log)
    logging.info("Start write logging")
    return main_logger

# 示例
if __name__ == "__main__":
    main_logger = filter_logging("total_log", "data_log", logging.INFO)

    total_logger = logging.getLogger("total_log")
    total_logger.info("This is an info message for total_log")
    total_logger.debug("This is a debug message for total_log")
    total_logger.error("This is an error message for total_log")

    data_logger = logging.getLogger("data_log")
    data_logger.info("This is an info message for data_log")
    data_logger.debug("This is a debug message for data_log")
    data_logger.error("This is an error message for data_log")

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值