第23章:风控日志与审计——交易日志规范、风控事件日志、审计追踪、日志存储与查询
做市商系统跑起来之后,什么最重要?
不是策略赚了多少,而是出了问题你能不能在5分钟内定位到根因。我见过太多团队,系统崩了,一群人围着屏幕干瞪眼,日志里全是乱码和空行。嗯,这种场面,经历过一次就够了。
这一章,咱们就聊聊风控日志和审计追踪。说白了,就是给系统装一个“黑匣子”。
23.1 交易日志规范——别让日志变成垃圾
日志不是写得越多越好。我曾经接手过一个项目,单台机器一天写20GB日志,结果查问题的时候,grep 一下要等半小时。为什么?因为开发人员把 debug 级别的日志全打出来了,连循环里的每次迭代都记录。
我个人习惯,日志分三级:
| 级别 | 用途 | 示例 |
|---|---|---|
| INFO | 记录关键业务节点 | 订单提交、成交、撤单 |
| WARN | 异常但不致命 | 网络抖动、延迟超阈值 |
| ERROR | 系统级故障 | 数据库连接失败、风控规则执行异常 |
你想想看,如果每个订单的每一步都打日志,那日志量会爆炸。我建议只记录“状态变更”事件。比如:
// 订单状态变更日志示例
{
"timestamp": "2025-03-15T10:30:00.123Z",
"level": "INFO",
"trade_id": "TXN20250315001",
"event": "ORDER_STATUS_CHANGE",
"from": "PENDING",
"to": "FILLED",
"price": 0.0032,
"quantity": 10000,
"latency_ms": 2.3
}
这里有个坑:时间戳一定要用 UTC,别用本地时间。我遇到过某交易所因为服务器时区没统一,日志时间错乱,排查跨天问题的时候差点崩溃。
核心原则:每条日志必须能唯一标识一笔交易,并且能还原出完整的生命周期。
23.2 风控事件日志——谁触发了什么规则
风控事件日志和交易日志不一样。交易日志记录“发生了什么”,风控日志记录“为什么没发生”。
举个例子:一个订单因为价格偏离过大被拒绝。交易日志里可能只有一条“订单被拒”,但风控日志要记录:
- 触发了哪条规则(比如:价格偏离阈值 > 5%)
- 当前市场数据(最新买一价、卖一价)
- 订单参数(报价、数量、方向)
- 规则执行耗时
我个人习惯,风控事件日志用单独的文件存储,不要和交易日志混在一起。为什么?因为审计的时候,监管只看风控日志,你给他一堆交易流水,他反而觉得你不专业。
// 风控事件日志示例
{
"timestamp": "2025-03-15T10:30:01.456Z",
"event_type": "RISK_REJECT",
"rule_id": "PRICE_DEVIATION_001",
"rule_name": "价格偏离风控",
"threshold": 0.05,
"actual_deviation": 0.073,
"order": {
"side": "BUY",
"price": 0.0035,
"qty": 5000
},
"market_snapshot": {
"best_bid": 0.0032,
"best_ask": 0.0033
},
"latency_ns": 150000
}
注意:风控日志里不要记录敏感信息,比如用户密钥、API Token。我曾经见过有人把私钥明文打在日志里,结果日志文件被运维误传到公开服务器……嗯,后果你懂的。
23.3 审计追踪——谁在什么时候做了什么
审计追踪和日志的区别是什么?
日志是机器看的,审计追踪是人看的。审计追踪要回答三个问题:
- 谁(操作人/系统模块)
- 什么时候(精确到毫秒)
- 做了什么(操作前后的状态对比)
我建议审计追踪采用“不可变记录”的方式。说白了,就是写进去就不能改。可以用什么方案?
- 方案一:写入专门的审计数据库,只追加,不更新
- 方案二:用区块链的思想,每条记录包含上一条的哈希值
- 方案三:最简单的,日志文件设置只读权限,定期归档
我个人偏向方案一。为什么?因为方案二虽然安全,但性能开销太大。做市商系统每秒可能处理上千笔订单,你让每笔都算哈希,延迟受不了。
小技巧:审计追踪里加一个“操作原因”字段。比如“管理员手动撤单,原因:市场异常波动”。这样事后复盘的时候,不用猜当时为什么这么做。
23.4 日志存储与查询——别让日志变成死数据
日志存了,查不出来,等于没存。
我见过最离谱的案例:某团队把所有日志压缩后扔到 HDFS 上,结果要查一周前的数据,得先解压 200GB 文件,再写 MapReduce 任务。等结果出来,黄花菜都凉了。
我建议的存储架构是这样的:
实时查询层(Elasticsearch) ← 近7天数据
↓
近线存储层(ClickHouse) ← 7-90天数据
↓
归档存储层(S3/OSS) ← 90天以上数据
为什么要分层?因为成本。热数据存在 SSD 上,查询快但贵;冷数据存在对象存储上,便宜但慢。你想想看,90天前的日志,一年也查不了几次,没必要浪费钱。
查询方面,我建议提供三个维度的检索:
| 维度 | 字段 | 说明 |
|---|---|---|
| 时间 | timestamp | 支持范围查询,精确到毫秒 |
| 交易ID | trade_id | 精确匹配,用于单笔追踪 |
| 事件类型 | event_type | 支持模糊匹配,比如查所有 RISK_REJECT |
避坑指南:我曾经因为没给日志加分区,导致查询全表扫描,一个简单的时间范围查询跑了 3 分钟。后来按天分区,查询时间降到 200 毫秒。所以,日志表一定要按时间分区,这是铁律。
23.5 知识体系总览
下面这张图,是我对风控日志与审计体系的整体理解。你可以把它当作一个检查清单:
这张图从下往上看,就是数据从产生到消费的完整链路。你搭建系统的时候,可以对照着检查:每一层是不是都覆盖到了?有没有遗漏?
最后说一句:日志系统不是一天建成的。我建议先跑起来,再优化。别一开始就追求完美,结果搞了三个月还没上线。先保证“能查”,再追求“查得快”。