第三章:日志采集与传输

日志采集与传输,说白了就是给交易系统装上一套「数据血管」。

我做了这么多年量化运维,见过太多系统崩了却找不到原因的惨案。后来发现,问题往往出在日志没传上来,或者传上来已经晚了。今天咱们就聊聊这套管道怎么搭。

3.1 Filebeat:轻量级采集器配置

Filebeat 这东西,我第一眼看到就觉得顺眼。为啥?因为它轻啊!

你想想看,交易服务器上跑着策略引擎、风控模块、行情网关,CPU 和内存本来就紧张。要是再装个笨重的采集器,那不是给自己找麻烦吗?

Filebeat 的安装配置其实很简单。我习惯用 RPM 包直接装:

# 安装 Filebeat
rpm -ivh filebeat-7.17.0-x86_64.rpm

# 配置文件 /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/trading/*.log
  multiline.pattern: '^\d{4}-\d{2}-\d{2}'
  multiline.negate: true
  multiline.match: after

output.kafka:
  hosts: ["kafka1:9092", "kafka2:9092"]
  topic: "trading-logs"
  partition.round_robin:
    reachable_only: true
  required_acks: 1
  compression: gzip
  max_message_bytes: 10485760

这里有个坑,我踩过。交易日志经常是多行的,比如异常堆栈信息。如果不配 multiline,一行行拆开传过去,你根本看不懂报错。

我的习惯:multiline 的正则一定要匹配时间戳格式。交易日志的时间戳通常是 yyyy-MM-dd HH:mm:ss,SSS,用 ^\d{4}-\d{2}-\d{2} 就能匹配上。

3.2 Logstash:管道处理的艺术

Logstash 就像个数据加工厂。Filebeat 把原木料运进来,Logstash 负责切割、打磨、分类。

我记得有一次,交易系统的日志格式突然变了,运维同事急得团团转。我过去一看,其实就是 Logstash 的 grok 正则没匹配上。

来看一个典型的配置:

input {
  kafka {
    bootstrap_servers => "kafka1:9092,kafka2:9092"
    topics => ["trading-logs"]
    group_id => "logstash-trading"
    consumer_threads => 4
    codec => "json"
  }
}

filter {
  grok {
    match => { 
      "message" => "%{TIMESTAMP_ISO8601:timestamp} \[%{LOGLEVEL:level}\] %{GREEDYDATA:msg}" 
    }
  }
  
  # 解析交易特定字段
  if [level] == "ERROR" {
    mutate {
      add_tag => ["critical"]
    }
  }
  
  date {
    match => ["timestamp", "ISO8601"]
    target => "@timestamp"
  }
}

output {
  elasticsearch {
    hosts => ["http://es1:9200", "http://es2:9200"]
    index => "trading-logs-%{+YYYY.MM.dd}"
    user => "logstash"
    password => "${ES_PWD}"
  }
}
我曾经踩过的坑:Logstash 的 grok 匹配失败时,默认会把原始消息原样保留。但如果你没配 tag_on_failure,这些解析失败的日志会悄悄溜进 ES,你查问题的时候根本找不到。建议加上 tag_on_failure => ["_grok_failure"],方便排查。

3.3 Kafka:日志流的缓冲屏障

Kafka 在日志流里扮演的角色,我打个比方你就懂了。

交易系统每秒产生几千条日志,ES 写入能力可能只有几百。如果没有 Kafka 缓冲,Logstash 直接往 ES 怼,ES 分分钟被打挂。

Kafka 就像个大水池,Filebeat 往里倒水,Logstash 从里面舀水。哪怕 Logstash 处理慢了,水也不会溢出来。

我建议的 Kafka 配置要点:

参数 推荐值 说明
replication.factor 3 日志不能丢,至少三副本
min.insync.replicas 2 至少两个副本同步才算写入成功
retention.ms 604800000 保留7天,方便回溯
compression.type gzip 压缩传输,节省带宽
核心逻辑:Filebeat → Kafka → Logstash → ES。Kafka 在这里起到了削峰填谷的作用。交易高峰期日志量暴增时,Kafka 能扛住,不会丢数据。

3.4 整体架构图

下面这张图,是我自己画的一个简化版日志采集架构。你看一眼就明白了:

日志采集与传输架构图 交易服务器 日志文件 Filebeat 轻量采集 Kafka 集群 缓冲/削峰 Logstash 解析/过滤 Elasticsearch 存储/检索 每台交易服务器部署 3节点集群,副本因子3 按日期滚动索引

3.5 实战中的几个要点

嗯,这里我要多说几句。光搭起来不算完,运维中还有几个地方容易出问题。

  • 磁盘空间:Kafka 的日志保留时间别设太长。我见过有人设了30天,结果磁盘爆了,整个集群挂了。7天足够,真要查更早的日志,从冷备恢复。
  • 网络带宽:交易日志量大的时候,gzip 压缩能省 60%-70% 的带宽。Filebeat 和 Kafka 之间一定要开压缩。
  • 监控告警:Filebeat 的 harvestor 状态、Kafka 的 consumer lag、Logstash 的 pipeline 延迟,这三个指标必须监控。任何一个出问题,日志流就断了。
一个小技巧:我习惯在 Logstash 的 output 阶段加一个 stdout 输出,调试的时候能看到实时日志流。上线前记得关掉,不然控制台会被刷爆。

说白了,日志采集传输这套东西,搭起来不难,难的是让它稳定跑着不出事。你把这些组件当成自己的孩子,每天看看它们的健康状态,该喂饭喂饭,该看病看病,自然就稳了。

专注资料整理