15、日志与监控:日志系统搭建、实时监控面板、告警通知(邮件/微信)、性能指标采集

做市系统跑起来之后,你最怕什么?

我最怕半夜手机突然响了——不是告警,而是交易员打电话说「系统好像不动了」。你想想看,等你打开电脑连上VPN,再翻日志,黄花菜都凉了。

所以这一章,咱们就把日志和监控彻底搞定。说白了,就是给系统装上「黑匣子」和「仪表盘」。

15.1 日志系统搭建:别再用 print 了

我见过不少新手,调试时用 print,上线了还留着 print。这在做市系统里是致命的——print 没有级别,没有时间戳,没有轮转,跑几天磁盘就满了。

注意:生产环境严禁使用 print 记录日志。一定要用结构化日志库。

我个人习惯用 Python 的 loguru,比标准 logging 好用十倍。安装就一行:

pip install loguru

然后配置一个全局日志器:

from loguru import logger
import sys

# 移除默认 handler
logger.remove()

# 添加控制台输出(开发用)
logger.add(sys.stderr, level="DEBUG", format="{time} | {level} | {message}")

# 添加文件输出(生产用)
logger.add(
    "logs/做市系统_{time:YYYY-MM-DD}.log",
    rotation="1 day",      # 每天轮转
    retention="30 days",   # 保留30天
    compression="zip",     # 压缩旧日志
    level="INFO",
    format="{time} | {level} | {name}:{function}:{line} | {message}"
)

这里有个关键点:日志级别要分清楚。DEBUG 记录细节,INFO 记录正常流程,WARNING 记录异常但可恢复的情况,ERROR 记录需要人工介入的问题。

我的习惯:每个订单的完整生命周期用一条日志记录,包含订单ID、价格、数量、状态变化。这样查问题的时候,grep 一下订单ID就能看到全过程。

15.2 实时监控面板:Grafana + Prometheus

日志是事后查的,监控面板是实时看的。我推荐用 Prometheus 采集指标,Grafana 展示面板。这套组合在量化圈几乎是标配。

先看整体架构:

日志与监控系统架构图 做市交易系统 日志模块 (loguru) 指标采集 (Prometheus) 存储层 Grafana 面板 告警通知 数据流方向:系统 → 采集 → 存储 → 展示/告警

在代码里暴露 Prometheus 指标,我习惯用 prometheus_client 库:

from prometheus_client import start_http_server, Gauge, Counter, Histogram
import random
import time

# 定义指标
order_counter = Counter('orders_total', '总订单数', ['symbol', 'side'])
position_gauge = Gauge('position_size', '当前持仓量', ['symbol'])
latency_histogram = Histogram('order_latency_seconds', '订单延迟分布', buckets=[0.001, 0.005, 0.01, 0.05, 0.1])

# 启动 HTTP 服务(Prometheus 会来抓取)
start_http_server(8000)

# 在交易逻辑中更新指标
def on_order_filled(order):
    order_counter.labels(symbol=order.symbol, side=order.side).inc()
    position_gauge.labels(symbol=order.symbol).set(order.position)
    latency_histogram.observe(order.latency)
核心指标清单:
  • 订单延迟:从发单到成交的时间,超过100ms就要警惕
  • 成交率:已成交订单 / 总发单数,太低说明报价策略有问题
  • 库存敞口:当前持仓偏离目标的程度,超过阈值要触发对冲
  • 系统资源:CPU、内存、网络延迟,防止硬件瓶颈

15.3 告警通知:邮件 + 微信

光有面板不够,你不可能24小时盯着屏幕。告警才是最后的防线。

我曾经有一次,因为交易所API改了字段格式,系统连续报错半小时我才发现。从那以后,我给自己定了个规矩:任何ERROR级别的日志,必须通知到手机

邮件告警用 smtplib 就能搞定:

import smtplib
from email.mime.text import MIMEText

def send_email_alert(subject, body):
    msg = MIMEText(body, 'plain', 'utf-8')
    msg['Subject'] = f'[做市系统告警] {subject}'
    msg['From'] = 'alert@yourdomain.com'
    msg['To'] = 'ops@yourdomain.com'
    
    with smtplib.SMTP('smtp.yourdomain.com', 587) as server:
        server.login('alert@yourdomain.com', 'password')
        server.send_message(msg)

微信通知稍微麻烦点。我推荐用 企业微信机器人,免费且稳定。建一个群,添加机器人,拿到 Webhook URL:

import requests
import json

def send_wechat_alert(message):
    url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY"
    data = {
        "msgtype": "text",
        "text": {
            "content": f"⚠️ 做市系统告警\n{message}"
        }
    }
    requests.post(url, json=data)
告警分级策略:
  • P0(紧急):系统宕机、资金异常 → 微信 + 电话
  • P1(重要):订单延迟飙升、成交率骤降 → 微信
  • P2(一般):某个交易所连接断开 → 邮件
  • P3(通知):每日成交统计、收益报告 → 邮件

15.4 性能指标采集:别等出事了再查

性能指标是「预防性」的。等用户说系统卡了,再去看指标就晚了。我习惯每5秒采集一次系统级指标:

import psutil
import time

def collect_system_metrics():
    while True:
        cpu_percent = psutil.cpu_percent(interval=1)
        memory_percent = psutil.virtual_memory().percent
        net_io = psutil.net_io_counters()
        
        # 上报到 Prometheus
        system_cpu_gauge.set(cpu_percent)
        system_memory_gauge.set(memory_percent)
        system_network_bytes_gauge.set(net_io.bytes_sent + net_io.bytes_recv)
        
        time.sleep(5)

除了系统指标,业务指标更重要。我建议至少采集这些:

指标名称 类型 说明 告警阈值
订单处理延迟 Histogram 从收到行情到发出订单的时间 P99 > 50ms
交易所连接状态 Gauge 0=断开, 1=连接 0 持续10秒
订单簿深度 Gauge 买卖各档位的挂单量 某档位为0
资金余额 Gauge 各币种可用余额 低于安全线
网络丢包率 Gauge 与交易所之间的网络质量 > 1%
避坑指南:我曾经把指标采集频率设成了每秒一次,结果 Prometheus 服务器压力太大,反而拖慢了交易系统。后来改成5秒一次,数据量降了80%,趋势图一样清晰。记住:监控是辅助交易的,不能影响交易本身。

15.5 整合:一个完整的监控循环

把上面这些串起来,就是一个完整的闭环:

  1. 采集层:loguru 写日志,Prometheus client 暴露指标
  2. 存储层:日志存文件(按天轮转),指标被 Prometheus 拉取存储
  3. 展示层:Grafana 连接 Prometheus,画出实时面板
  4. 告警层:Grafana 或 Prometheus 触发告警规则,发邮件/微信
  5. 响应层:收到告警后,查日志定位问题,修复后恢复

嗯,这套体系搭好之后,我晚上睡觉踏实多了。手机偶尔响一下,看一眼告警内容,心里就有数——是哪个模块出了问题,严重不严重,要不要爬起来处理。

说白了,日志和监控不是为了「好看」,而是为了让你在出问题的时候,能比别人快5分钟定位到根因。这5分钟,可能就是几万块钱的差距。

一句话总结:日志记录「发生了什么」,监控展示「正在发生什么」,告警告诉你「该做什么」。三者缺一不可。

无相订单流研究社 微信Lucian808555