TradingAgents-CN 统一日志改造:print 转 logger 的规模化迁移实践与实现解析
【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN
导读
TradingAgents-CN 是基于多智能体 LLM 的中文金融交易框架,其代码库横跨核心交易代理(tradingagents/)、Web 界面(web/)、CLI(cli/)、脚本工具(scripts/)与示例(examples/)等大量模块。随着模块数量膨胀,散落各处的print()调试输出不仅污染终端、无法分级过滤,也无法被统一采集与分析。本文基于仓库中的 print_to_log_conversion_report.md 与配套的 convert_prints_to_logs.py 转换器实现,完整讲解本次「print 转日志」批量迁移的统计结果、转换规则、日志器命名规范,以及底层 logging_manager.py 与 logging.toml 构成的统一日志体系。读完本文,你将掌握如何在一个多模块 Python 仓库中安全、自动化地把 print 替换为分级日志输出,并理解其背后的配置机制。
一、迁移概览:一次覆盖 100 个文件的自动化改造
本次 print 转日志改造以「批量扫描 + 规则化转换 + 报告留痕」的方式执行,转换器由PrintToLogConverter类实现(见 scripts/convert_prints_to_logs.py)。官方报告记录的最终结果为:
- 成功转换文件:100
- 错误数量:0
报告全文以「转换统计 + 转换的文件清单」两部分构成,文件清单覆盖了项目内从入口到工具脚本的全部 Python 代码,按目录归类主要包括:
| 目录 | 代表性文件 | 职责 |
|---|---|---|
| 根目录 | main.py、quick_syntax_check.py、syntax_checker.py | 主入口与语法检查工具 |
cli/ | cli/main.py、cli/utils.py | 命令行接口 |
examples/ | examples/batch_analysis.py、examples/cli_demo.py | 演示与集成示例 |
scripts/ | scripts/log_analyzer.py、scripts/setup-docker.py | 运维与构建脚本 |
tradingagents/ | tradingagents/dataflows/akshare_utils.py、tradingagents/graph/trading_graph.py | 核心数据流与交易图 |
web/ | web/app.py、web/components/analysis_form.py | Web 界面 |
utils/ | utils/check_version_consistency.py | 工具函数 |
可以看到,这次改造不是局部修补,而是对全仓库日志基建的一次系统性收口,目的是让所有模块统一走 logging_manager.py 提供的get_logger()通道。
二、转换器的核心实现:规则驱动的 print 检测与改写
转换器以PrintToLogConverter为核心类(scripts/convert_prints_to_logs.py#L13-L45),工作流程分为三步:跳过规则判定 → 注入日志导入 → 改写 print 语句。
2.1 安全的文件过滤规则
迁移必须避免误伤测试与虚拟环境,因此转换器维护了两套排除清单(should_skip_file):
- 排除目录:
tests、env、.env、__pycache__、.git、.github - 排除文件模式:
test_*.py、*_test.py、conftest.py、setup.py,以及转换器自身convert_prints_to_logs.py
这一设计保证了测试代码中的print辅助输出不受影响,同时避免转换器处理自身导致无限递归式改写。
2.2 自动注入统一日志导入
对每个待转换文件,转换器会在所有 import 语句结束后插入日志导入与 logger 初始化(add_logging_import):
# 导入日志模块 from tradingagents.utils.logging_manager import get_logger logger = get_logger('default')其中 logger 名称并非写死,而是根据文件相对路径自动推导(脚本 L109-L129),规则如下:
| 路径特征 | logger 名称 |
|---|---|
含web | web |
含tradingagents且含agents | agents |
含tradingagents且含dataflows | dataflows |
含tradingagents且含llm_adapters | llm_adapters |
含tradingagents且含utils | utils |
含tradingagents(其他) | tradingagents |
含cli | cli |
含scripts | scripts |
| 其他 | default |
该命名规范与 config/logging.toml 中[logging.loggers]各命名空间(tradingagents、web、dataflows、llm_adapters等)一一对应,从而保证每个模块的日志可以被按命名空间独立调节级别。
2.3 print 语句的匹配与级别判定
转换器通过正则匹配四种 print 形态(convert_print_statements):
print_patterns = [ r'print\s*\(\s*f?"([^"]*?)"([^)]*)\)', # print("...") r"print\s*\(\s*f?'([^']*?)'([^)]*)\)", # print('...') r'print\s*\(\s*f?"""([^"]*?)"""([^)]*)\)', # print("""...""") r"print\s*\(\s*f?'''([^']*?)'''([^)]*)\)", # print('''...''') ]匹配到消息内容后,调用 get_log_level_from_message 依据消息中的关键词推断日志级别:
| 判定关键词 | 映射级别 |
|---|---|
❌、错误、ERROR、Error、失败、Failed、Exception | error |
⚠️、警告、WARNING、Warning、注意 | warning |
🔍、DEBUG、Debug、[DEBUG] | debug |
✅、成功、完成、Success、Complete | info |
| 其余 | info(默认) |
随后按原缩进改写为logger.<level>(f"<message>"),若原 print 带额外参数(如sep=)则保留在调用括号内:
# 转换前 print(f"✅ 分析完成 - {symbol}") # 转换后 logger.info(f"✅ 分析完成 - {symbol}")得益于仓库源码里大量使用 emoji 前缀作为状态标识(这与logging_manager.py内置的log_analysis_complete等语义化日志风格一脉相承),这套关键词推断在真实代码上命中率很高。
三、统一日志体系的底层支撑
print 转 logger 之所以能落地,是因为项目已具备一套完整的统一日志基础设施,转换后的get_logger()调用最终都汇入这里。
3.1 统一日志管理器:TradingAgentsLogger
tradingagents/utils/logging_manager.py 定义了TradingAgentsLogger类与两个关键入口:
get_logger(name):获取/创建命名日志器(脚本 L439-L441),所有模块统一通过它取 logger;setup_logging(config):可传入自定义配置重建日志系统(脚本 L444-L448)。
类内部实现了四类处理器:
| 处理器 | 输出目标 | 默认级别 | 说明 |
|---|---|---|---|
| console | 标准输出 | INFO | 支持 ANSI 彩色(ColoredFormatter,DEBUG 青、INFO 绿、WARNING 黄、ERROR 红、CRITICAL 紫),仅 TTY 下着色 |
| file | ./logs/tradingagents.log | DEBUG | RotatingFileHandler轮转,默认 10MB×5 |
| error | ./logs/error.log | WARNING | 只收 WARNING/ERROR/CRITICAL,便于单独盯异常 |
| structured | ./logs/tradingagents_structured.log | INFO | 默认关闭,产出 JSON 结构化日志 |
其中StructuredFormatter(脚本 L43-L69)会把session_id、analysis_type、stock_symbol、cost、tokens等业务字段一并序列化为 JSON,为后续检索分析提供机器可读数据。
3.2 TOML 配置文件驱动的运行期行为
日志行为全部由 config/logging.toml 控制,加载逻辑位于_load_config_file(脚本 L139-L160),加载顺序为:
config/logging_docker.toml(当环境变量DOCKER_CONTAINER=true时)config/logging.toml./logging.toml- 兜底环境变量配置(
TRADINGAGENTS_LOG_LEVEL、TRADINGAGENTS_LOG_DIR)
关键配置项(config/logging.toml):
[logging] level = "INFO" # 全局级别:DEBUG/INFO/WARNING/ERROR/CRITICAL [logging.format] console = "%(asctime)s | %(name)-20s | %(levelname)-8s | %(message)s" file = "%(asctime)s | %(name)-20s | %(levelname)-8s | %(module)s:%(funcName)s:%(lineno)d | %(message)s" file_json = true # 启用文件日志 JSON 输出(webapi.log 与 worker.log) [logging.handlers.file] enabled = true level = "DEBUG" max_size = "10MB" # 单个日志文件上限,支持 KB/MB/GB 后缀 backup_count = 5 # 轮转保留份数 directory = "./logs" [logging.handlers.error] enabled = true level = "WARNING" # 错误日志专用文件 filename = "error.log"此外还包含三级环境预设:
- Docker 环境(logging.docker):可切换为只输出 stdout、禁用文件日志;
- 开发环境(logging.development):可对
tradingagents.graph、tradingagents.llm_adapters等模块开 DEBUG 并保存调试文件; - 生产环境(logging.production):可启用纯结构化日志与错误通知,并放大单文件上限至 100MB。
另有一份专为容器准备的 config/logging_docker.toml,将日志目录固定为/app/logs,并细分出webapi.log、worker.log等独立文件,配合file_json = true让后端与 Worker 的日志分别以 JSON 落盘,便于在 Docker 部署场景下做集中采集。
四、从报告到工程实践:本次改造的经验沉淀
报告本身是一份「迁移留痕」文档,但从其结构与配套脚本可以提炼出可复用的工程方法论:
- 先立规范,再动代码:
get_logger()命名空间与logging.toml中 logger 段一一对应,保证迁移后日志归属清晰; - 自动化 + 人工复核:转换器承担全部机械改写,报告自动生成
成功转换文件/错误数量统计,方便审计;报告中「错误数量: 0」说明规则转换在目标代码上无失败案例; - 保留语义级别:通过消息关键词自动分级,使历史 print 文本在转换后依然能按级别过滤,而不是全部落入 info;
- 配套修复闭环:本次 print 迁移并非孤立动作,仓库中还有
scripts/fix_duplicate_loggers.py(移除重复 logger 定义,对应 duplicate_logger_fix_report.md,累计修复 98 个文件、移除 108 处重复定义)与 scripts/migrate_to_unified_logging.py(把logging.getLogger(__name__)、traceback.print_exc()等旧式调用统一收编),三者共同构成「print 转日志 → 去重 → 统一 API」的完整治理链路。
4.1 迁移后的日志查看方式
完成转换后,运行任意模块(如python cli/main.py或 Web 服务)即可看到分级彩色输出;常规运行日志落在./logs/tradingagents.log,错误与警告单独沉淀在./logs/error.log。在 Docker 部署下则统一写入/app/logs/下各命名文件。开发者可用grep、日志采集器或直接解析 JSON 行完成排障与监控。
五、小结
本次「print 转日志」改造以零错误的成绩覆盖 100 个 Python 文件,将分散的print()统一收敛到 logging_manager.py 提供的分级日志体系之下:转换器 convert_prints_to_logs.py 负责规则化改写,config/logging.toml 与 config/logging_docker.toml 负责运行期行为,get_logger()命名空间规范负责模块归属。对于任何正在演进的多模块 Python 项目,这套「脚本批量转换 + 命名空间规范 + TOML 驱动 + 报告留痕」的组合都是一份可直接借鉴的日志基建治理样板。
【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考