You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python产品数据管道需终端与文件双输出的彩色日志工具

解决Python日志终端彩色输出+文件写入的方案

首先纠正一个误区:Python标准库的logging模块完全支持同时输出日志到终端和文件,只是默认没有配置彩色终端输出而已。下面分两种方案给出实现方式,你可以根据需求选择或自行封装。

一、原生logging模块实现双端输出+终端彩色

1. 自定义彩色终端Handler

通过继承logging.StreamHandler,重写format方法来添加颜色控制码:

import logging

class ColorStreamHandler(logging.StreamHandler):
    # 定义日志级别对应的颜色
    COLORS = {
        logging.DEBUG: '\033[94m',    # 蓝色
        logging.INFO: '\033[92m',     # 绿色
        logging.WARNING: '\033[93m',  # 黄色
        logging.ERROR: '\033[91m',    # 红色
        logging.CRITICAL: '\033[95m'  # 紫色
    }
    RESET = '\033[0m'

    def format(self, record):
        # 给日志级别名称添加颜色
        record.levelname = f"{self.COLORS.get(record.levelno, self.RESET)}{record.levelname}{self.RESET}"
        return super().format(record)

2. 配置双Handler(终端+文件)

创建日志器,同时添加彩色终端Handler和文件Handler:

def setup_logger(name="data_pipeline"):
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    logger.handlers.clear()  # 避免重复添加Handler

    # 1. 彩色终端Handler
    console_handler = ColorStreamHandler()
    console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    console_handler.setFormatter(console_formatter)
    logger.addHandler(console_handler)

    # 2. 文件Handler(无颜色,纯文本)
    file_handler = logging.FileHandler('pipeline.log', encoding='utf-8')
    file_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s')
    file_handler.setFormatter(file_formatter)
    logger.addHandler(file_handler)

    return logger

3. 使用示例

logger = setup_logger()
logger.debug("调试信息,终端显示蓝色")
logger.info("普通信息,终端显示绿色")
logger.warning("警告信息,终端显示黄色")
logger.error("错误信息,终端显示红色")
logger.critical("严重错误,终端显示紫色")

二、第三方库简化实现

如果不想自己写Handler,可以用成熟的第三方库,以下两个比较常用:

1. colorlog

基于标准logging扩展,直接支持彩色终端输出,同时可以配合FileHandler实现文件写入:

import logging
import colorlog

def setup_colorlog():
    logger = logging.getLogger("data_pipeline")
    logger.setLevel(logging.DEBUG)
    logger.handlers.clear()

    # 彩色终端配置
    console_handler = colorlog.StreamHandler()
    console_formatter = colorlog.ColoredFormatter(
        '%(log_color)s%(asctime)s - %(levelname)s - %(message)s',
        log_colors={
            'DEBUG': 'blue',
            'INFO': 'green',
            'WARNING': 'yellow',
            'ERROR': 'red',
            'CRITICAL': 'purple'
        }
    )
    console_handler.setFormatter(console_formatter)
    logger.addHandler(console_handler)

    # 文件Handler
    file_handler = logging.FileHandler('pipeline.log', encoding='utf-8')
    file_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s')
    file_handler.setFormatter(file_formatter)
    logger.addHandler(file_handler)

    return logger

2. loguru

更简洁的日志库,默认支持彩色终端输出,一行代码就能同时输出到文件:

from loguru import logger

# 配置:同时输出到终端(彩色)和文件(无颜色)
logger.add(
    "pipeline.log",
    format="{time} - {level} - {module}:{line} - {message}",
    level="DEBUG"
)

# 使用示例
logger.debug("调试信息")
logger.info("普通信息")
logger.warning("警告信息")
logger.error("错误信息")
logger.critical("严重错误")

三、封装统一类(按需自定义)

如果你想封装成自己的统一日志类,可以参考以下结构:

import logging
from typing import Optional

class PipelineLogger:
    def __init__(self, name: str = "data_pipeline", log_file: str = "pipeline.log"):
        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.DEBUG)
        self.logger.handlers.clear()

        # 初始化彩色终端Handler
        self._setup_console_handler()
        # 初始化文件Handler
        self._setup_file_handler(log_file)

    def _setup_console_handler(self):
        class ColorStreamHandler(logging.StreamHandler):
            COLORS = {
                logging.DEBUG: '\033[94m',
                logging.INFO: '\033[92m',
                logging.WARNING: '\033[93m',
                logging.ERROR: '\033[91m',
                logging.CRITICAL: '\033[95m'
            }
            RESET = '\033[0m'

            def format(self, record):
                record.levelname = f"{self.COLORS.get(record.levelno, self.RESET)}{record.levelname}{self.RESET}"
                return super().format(record)

        console_handler = ColorStreamHandler()
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        console_handler.setFormatter(formatter)
        self.logger.addHandler(console_handler)

    def _setup_file_handler(self, log_file: str):
        file_handler = logging.FileHandler(log_file, encoding='utf-8')
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s')
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)

    def debug(self, msg: str):
        self.logger.debug(msg)

    def info(self, msg: str):
        self.logger.info(msg)

    def warning(self, msg: str):
        self.logger.warning(msg)

    def error(self, msg: str):
        self.logger.error(msg)

    def critical(self, msg: str):
        self.logger.critical(msg)

# 使用示例
pl = PipelineLogger()
pl.info("数据管道启动")
pl.error("数据读取失败")

内容的提问来源于stack exchange,提问作者B1smuth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 18:37:28