日志框架选型:Python logging模块深度解析、Loguru库实战、结构化日志与文本日志对比

日志这东西,平时没人关注,一出事它就是救命稻草。我在量化交易系统运维这行干了快十年,见过太多因为日志没配好,排查故障花了一整夜的惨案。今天咱们就聊聊Python世界里几个主流的日志框架,以及它们在实际交易系统里的用法。

Python内置logging模块:老牌劲旅

Python自带的logging模块,说实话,功能很全。但它的配置方式,嗯…有点反人类。我记得刚入行那会儿,第一次配logging,光看文档就花了两小时。

它的核心组件就四个:Logger、Handler、Formatter、Filter。说白了就是:谁在记、记到哪、怎么记、记什么。

核心要点:logging模块的配置方式有两种——基本配置和字典配置。生产环境我强烈建议用字典配置,灵活得多。

import logging
import logging.config

# 字典配置示例
LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'default': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        }
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'INFO',
            'formatter': 'default'
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'trade_system.log',
            'maxBytes': 10485760,  # 10MB
            'backupCount': 5,
            'level': 'DEBUG'
        }
    },
    'root': {
        'level': 'DEBUG',
        'handlers': ['console', 'file']
    }
}

logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)

这里有个坑,我踩过好几次。RotatingFileHandler的备份文件数量,别设太大。我曾经设了50个,结果磁盘爆了。交易系统日志量很大的,一天几个GB很正常。

注意:logging模块的线程安全是没问题的,但多进程环境下要小心。每个进程都会写同一个文件,会乱。解决方案是用QueueHandler+QueueListener,或者干脆用第三方库。

Loguru库:优雅的替代方案

说实话,我第一次用Loguru的时候,感觉就是「这才对嘛」。它把logging那些繁琐的配置全简化了。你想想看,一行代码就能搞定日志初始化,多爽。

from loguru import logger

# 一行配置
logger.add("trade_{time}.log", rotation="500 MB", retention="10 days", level="DEBUG")

# 使用起来更简单
logger.info("订单已提交,订单ID: {}", order_id)
logger.debug("行情数据: {}", market_data)
logger.error("交易执行失败: {}", exc_info=True)

Loguru最让我喜欢的是它的格式化能力。用{}占位符,不用再写%s了。而且它自动捕获异常堆栈,不用手动传exc_info。

我在一个高频交易项目里用过Loguru。当时需要记录每个订单的完整生命周期,从生成到成交。用Loguru的bind方法,可以给每条日志绑定上下文信息,比如订单ID、策略ID。排查问题时,按订单ID一搜,整个链路就出来了。

# 绑定上下文
logger = logger.bind(order_id="ORD20240321001", strategy="momentum_v2")
logger.info("订单创建")
logger.info("订单发送至交易所")
logger.info("订单部分成交")

小技巧:Loguru的rotation参数支持按时间、按大小轮转。我习惯用"00:00"每天切一次,配合retention保留7天。这样日志文件不会太大,查找也方便。

结构化日志 vs 文本日志

这个问题,说白了就是「人看的」和「机器看的」的区别。文本日志适合人眼扫读,结构化日志适合程序分析。

在量化交易系统里,我强烈推荐结构化日志。为什么?因为交易日志量太大了,你不可能一条条看。得用ELK或者Splunk这类工具去分析。而结构化日志,比如JSON格式,天生就是给这些工具吃的。

对比维度 文本日志 结构化日志(JSON)
可读性 高,人眼直接看 低,需要格式化
解析效率 低,需要正则匹配 高,直接解析JSON
查询能力 弱,只能全文搜索 强,可按字段过滤
存储空间 大(约多30%)
适用场景 开发调试、小规模系统 生产环境、大规模系统

来看看实际对比。同样的交易日志,文本格式长这样:

2024-03-21 14:30:01,234 - trade_executor - INFO - 订单成交: 订单ID=ORD20240321001, 价格=123.45, 数量=1000, 方向=买入

JSON格式长这样:

{
  "timestamp": "2024-03-21T14:30:01.234",
  "logger": "trade_executor",
  "level": "INFO",
  "message": "订单成交",
  "order_id": "ORD20240321001",
  "price": 123.45,
  "quantity": 1000,
  "direction": "买入"
}

你看,JSON格式多了字段名,占空间,但查询起来太方便了。在Kibana里直接搜order_id: ORD20240321001,所有相关日志秒出。

我的建议:开发环境用文本日志,方便调试。生产环境用JSON格式,方便分析。用Loguru的话,切换格式就是改一行配置的事。

实战:用Loguru输出结构化日志

下面是我在一个实盘交易系统里用的配置。它同时输出文本日志(给运维看)和JSON日志(给分析系统吃)。

from loguru import logger
import sys

# 移除默认的handler
logger.remove()

# 控制台输出:文本格式,带颜色
logger.add(
    sys.stdout,
    format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level:<8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
    level="INFO",
    colorize=True
)

# 文件输出:JSON格式,按天轮转
logger.add(
    "logs/trade_{time:YYYY-MM-DD}.json",
    format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {extra[order_id]} | {message}",
    serialize=True,  # 输出JSON格式
    rotation="00:00",
    retention="7 days",
    level="DEBUG",
    enqueue=True  # 线程安全
)

# 使用示例
logger.bind(order_id="ORD001").info("订单创建")
logger.bind(order_id="ORD001").info("订单发送成功")

这里有个细节,enqueue=True这个参数。它让日志写入变成异步的,不会阻塞主线程。在高频交易场景下,这个很重要。我曾经见过因为日志I/O阻塞导致订单延迟的案例,那叫一个惨。

知识体系总览

下面这张图,是我对日志框架选型的理解。它涵盖了从基础组件到生产实践的完整链路。

日志框架选型知识体系 日志框架选型 Python logging模块 Loguru库 核心组件 Logger · Handler · Formatter · Filter 配置方式:字典配置 / 文件配置 核心特性 简化配置 · 自动轮转 · 上下文绑定 序列化输出 · 异步写入 输出格式:文本日志 vs 结构化日志(JSON) 生产环境推荐:Loguru + JSON结构化日志 + 按天轮转 + 异步写入

这张图把今天讲的内容串起来了。从框架选型开始,到具体实现,再到输出格式的选择。你想想看,一个完整的日志体系,其实就是这几个环节的组合。

最后说一句:日志框架没有银弹。logging模块功能全但配置繁琐,Loguru简单优雅但灵活性稍差。我的建议是:小项目用Loguru,大项目用logging+结构化日志。关键是要形成规范,团队统一,别今天用这个明天换那个。


公众号:蓝海资料掘金营,微信deep3321