第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 审计追踪——谁在什么时候做了什么

审计追踪和日志的区别是什么?

日志是机器看的,审计追踪是人看的。审计追踪要回答三个问题:

  1. (操作人/系统模块)
  2. 什么时候(精确到毫秒)
  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 知识体系总览

下面这张图,是我对风控日志与审计体系的整体理解。你可以把它当作一个检查清单:

风控日志与审计体系架构 数据采集层 交易日志(订单状态变更) 风控事件日志(规则触发记录) 审计追踪(操作记录) 存储层(分层架构) 热存储:Elasticsearch 近7天,毫秒级查询 温存储:ClickHouse 7-90天,秒级查询 冷存储:S3/OSS 90天以上,分钟级查询 查询层(三维检索) 时间维度:范围查询 交易ID:精确匹配 事件类型:模糊匹配 应用场景:问题定位 · 监管审计 · 策略复盘 · 风控优化

这张图从下往上看,就是数据从产生到消费的完整链路。你搭建系统的时候,可以对照着检查:每一层是不是都覆盖到了?有没有遗漏?

最后说一句:日志系统不是一天建成的。我建议先跑起来,再优化。别一开始就追求完美,结果搞了三个月还没上线。先保证“能查”,再追求“查得快”。

交易系统化学习资料 微信Strategy888888