一、日志系统概述:交易系统为什么需要日志?
说实话,我做了十几年交易系统,见过太多因为日志没做好而翻车的案例。
有一次凌晨两点,线上突然报错,交易对不上了。我打开服务器一看——日志只打了「Error occurred」五个字。当时真想摔键盘。你想想看,几百万的交易流水,就靠这几个字去排查?
所以今天咱们聊聊,交易系统为什么离不开日志。说白了,日志就是系统的「黑匣子」。没有它,你连问题出在哪都不知道。
日志的三大价值
我个人习惯把日志的价值归纳为三个词:排障、审计、监控。咱们一个一个说。
1. 排障——出了问题能快速定位
这是日志最基础的价值。系统崩了,交易失败了,你得知道为什么。
我记得有一次,一个高频交易系统突然出现大量超时。查了半天,发现是数据库连接池满了。但如果没有详细的调用链日志,你根本不知道是哪个环节把连接占满了。
排障日志的核心要素:
- 时间戳(精确到毫秒)
- 请求ID(用于串联整个调用链)
- 操作类型(下单、撤单、查询等)
- 输入参数与返回结果
- 异常堆栈(不要只打一句话)
嗯,这里要注意:很多人喜欢在catch里只打e.getMessage()。我建议你打全了,e.printStackTrace()或者用日志框架的完整异常输出。不然到时候查问题,你只能看到「null」或者「连接超时」,一点用都没有。
2. 审计——每一笔交易都有据可查
交易系统跟普通系统不一样。每一笔钱、每一笔资产变动,都得有完整的记录。这不是为了查bug,是为了合规。
我曾经帮一家券商做过审计链改造。他们之前日志打得稀烂,结果监管来检查,问「这笔交易是谁操作的?什么时候?审批流程是什么?」——答不上来。最后被罚了200万。
审计日志的要求比普通日志严格得多:
| 审计要素 | 说明 | 示例 |
|---|---|---|
| 操作人 | 谁做的操作 | user_id=10086, role=trader |
| 操作时间 | 精确到毫秒,且不可篡改 | 2024-01-15 14:23:45.678 |
| 操作内容 | 做了什么,改了哪些字段 | order_id=ORD20240115001, status: PENDING→FILLED |
| 操作结果 | 成功还是失败,失败原因 | status=SUCCESS, affected_rows=1 |
| 审计签名 | 防止日志被篡改 | hash=sha256(prev_log + current_log) |
避坑指南:我曾经见过一个系统,审计日志直接写进数据库的普通表里。结果DBA手滑truncate了,所有审计记录全没了。后来我们改成了「写日志+写数据库+写备份」三重保险。审计日志一定要有防删除、防篡改机制。
3. 监控——系统健康状态的「体温计」
监控日志不是给人看的,是给机器看的。它告诉你系统现在「舒不舒服」。
我习惯把监控日志分成三个等级:
- INFO:正常业务流程,比如「订单已接收」「订单已成交」
- WARN:有异常但还能处理,比如「重试第3次」「响应时间超过500ms」
- ERROR:必须人工介入,比如「数据库连接失败」「交易对账不平」
但这里有个坑:很多人把ERROR当INFO打,或者把INFO当ERROR打。结果监控告警天天响,最后大家直接无视了。我建议你定个规矩:ERROR级别的日志,必须对应一个需要人工处理的故障。否则就降级到WARN。
一张图看懂日志体系
下面这张图是我自己总结的日志分层模型。你可以把它当成设计日志系统的参考框架:
你看,这四层日志各司其职。业务日志和审计日志偏业务,系统日志和监控日志偏技术。但它们是联动的——比如监控发现TPS异常,你得去查系统日志看有没有错误,再查业务日志看是哪类交易出了问题。
我的经验:刚开始做日志系统时,别想着一步到位。先把业务日志和系统日志打好,这是基础。等稳定了,再上审计日志和监控日志。我见过太多团队一上来就搞「全链路追踪」「实时告警」,结果基础日志都没打全,最后全白费。
总结一下
日志不是「写了就行」,而是「写对了才行」。排障日志要详细,审计日志要完整,监控日志要准确。这三者缺一不可。
嗯,最后说一句:别等到出事了才想起日志的重要性。我每次接手新系统,第一件事就是看日志打得好不好。日志好的系统,通常代码质量也不会太差。反过来,日志稀烂的系统,里面大概率藏着不少坑。
公众号:蓝海资料掘金营,微信deep3321