第2章:运维数据采集——日志、指标与链路追踪

数据采集是智能运维的「眼睛」。没有数据,一切分析都是空谈。

我个人习惯把运维数据分成三类:日志、指标、链路。这三者各有侧重,又互相补充。今天我们就来聊聊它们的基础采集方案。

2.1 日志采集:Filebeat 与 Logstash

日志是最传统的运维数据。但说实话,很多人对日志采集的理解还停留在「tail -f」阶段。在分布式系统里,日志采集要解决几个核心问题:怎么不丢?怎么不重?怎么不影响业务?

2.1.1 Filebeat:轻量级日志采集器

Filebeat 是 Elastic 家的轻量级采集器。它用 Go 写的,资源占用极低。我在项目中遇到过一台 4C8G 的机器,跑了 20 多个业务进程,Filebeat 只占了不到 50MB 内存。

它的核心优势是「不丢数据」——内部有个确认机制,日志发送成功后才删除本地缓存。嗯,这里要注意:如果 Logstash 或 ES 挂了,Filebeat 会一直重试,直到磁盘写满。

避坑指南: 我曾经因为没配置 Filebeat 的磁盘空间限制,导致一台日志服务器磁盘写满,业务日志全丢了。后来我养成了习惯:
- 设置 queue.mem.events 限制内存队列大小
- 设置 max_procs 限制 CPU 使用
- 配置 close_inactive 自动关闭空闲文件句柄

Filebeat 的配置其实很简单。你想想看,核心就三件事:读什么文件、怎么处理、发到哪里。

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

output.logstash:
  hosts: ["logstash:5044"]
  loadbalance: true
  compression_level: 6

这里有个小技巧:multiline 配置用来处理 Java 异常堆栈。如果不配,一条异常会被拆成几十条日志,排查问题时会疯掉。

2.1.2 Logstash:数据管道处理器

Logstash 是 ELK 里的「L」。它负责接收、解析、转换日志数据。说白了,它就是个数据管道。

我个人建议:不要在 Logstash 里做复杂的业务逻辑。它擅长的是格式转换和字段提取,不是数据清洗。复杂的清洗逻辑应该交给下游的流处理引擎。

组件 定位 资源消耗 适用场景
Filebeat 轻量采集器 低(~50MB) 边缘节点采集
Logstash 数据管道 中(~500MB) 集中处理、格式转换
Kafka 消息队列 中高 削峰填谷、解耦

Logstash 的 pipeline 配置,我习惯用 grok 做日志解析。举个例子,解析 Nginx 访问日志:

filter {
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
  }
  date {
    match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
    target => "@timestamp"
  }
  geoip {
    source => "clientip"
    target => "geo"
  }
}
我的经验: 如果日志格式不统一,先用 grok debugger 在线调试。别在生产环境里试,我吃过这个亏——写错正则导致 Logstash 内存暴涨。

2.2 指标采集:Prometheus

指标数据是运维的「体温计」。Prometheus 是当前最流行的指标采集方案,没有之一。为什么?因为它简单、高效、生态好。

Prometheus 的核心是「拉模式」——它主动去目标机器上抓数据。这和传统的「推模式」(比如 Zabbix)完全不同。我个人更喜欢拉模式,原因有三:

  • 更容易控制采集频率:想快就快,想慢就慢
  • 天然支持服务发现:新机器上线自动发现
  • 数据一致性更好:不会因为网络抖动导致数据乱序

2.2.1 指标类型与采集方式

Prometheus 定义了四种指标类型。我刚开始学的时候觉得没必要分这么细,后来发现每种类型都有它的设计意图:

类型 说明 典型场景
Counter 只增不减的计数器 请求总数、错误总数
Gauge 可增可减的测量值 CPU使用率、内存使用量
Histogram 直方图,统计分布 请求延迟分布
Summary 分位数统计 P99延迟

采集方式有两种:一种是业务代码里埋点,用 Prometheus 客户端 SDK 暴露 /metrics 接口;另一种是用 Exporter 采集系统或中间件的指标。

举个例子,用 Node Exporter 采集服务器指标:

# prometheus.yml 配置
scrape_configs:
- job_name: 'node'
  static_configs:
  - targets: ['localhost:9100']
  metrics_path: '/metrics'
  scrape_interval: 15s
  scrape_timeout: 10s
核心要点: 采集间隔和超时时间要匹配。如果超时时间大于采集间隔,会导致采集任务堆积。我建议 scrape_timeout 设为 scrape_interval 的 2/3。

2.2.2 服务发现与高可用

在 Kubernetes 环境里,Prometheus 的服务发现能力特别重要。它会自动发现新 Pod,动态更新采集目标。

高可用方面,我推荐用 Thanos 或 VictoriaMetrics 做长期存储。Prometheus 本身不适合存超过 30 天的数据——它的本地存储是单机的,磁盘满了就写不进去了。

2.3 链路追踪:Jaeger 与 Zipkin

链路追踪解决的是「一个请求经过多个服务,到底慢在哪里」的问题。说白了,就是给每个请求打一个全局唯一的 TraceID,然后记录它经过的每个服务、每个步骤的耗时。

我刚开始做微服务时,遇到线上问题全靠猜。后来上了链路追踪,才发现很多「偶发超时」其实是某个下游服务的慢查询导致的。

2.3.1 Jaeger:CNCF 毕业项目

Jaeger 是 Uber 开源的链路追踪系统,现在是 CNCF 的毕业项目。它的架构分三部分:Agent(采集)、Collector(收集)、Query(查询)。

采集方式有两种:一种是 Agent 模式,每个机器上部署一个 Jaeger Agent,业务进程通过 UDP 发送数据;另一种是直接 HTTP 发送到 Collector。

我个人推荐 Agent 模式。为什么?因为 UDP 不会阻塞业务进程。如果 Collector 挂了,业务进程不会卡住。

# Jaeger Agent 启动命令
jaeger-agent \
  --collector.host-port=collector:14267 \
  --processor.jaeger-compact.server-host-port=0.0.0.0:6831 \
  --processor.jaeger-compact.server-max-packet-size=65000
注意: UDP 有丢包风险。如果链路数据很重要,建议用 HTTP 模式并配置重试。我在生产环境里两种都用:核心服务用 HTTP,非核心服务用 UDP。

2.3.2 Zipkin:Twitter 的开源方案

Zipkin 是 Twitter 开源的链路追踪系统,比 Jaeger 出现得更早。它的架构和 Jaeger 类似,但存储层支持更多后端:Elasticsearch、Cassandra、MySQL。

Zipkin 的客户端库更丰富,支持的语言更多。如果你的团队用 Java 或 Go,Zipkin 的集成会更简单。

说实话,Jaeger 和 Zipkin 的核心功能差不多。选哪个主要看团队的技术栈和运维习惯。我个人更倾向 Jaeger,因为它的 UI 更现代,而且和 Prometheus 的集成更好。

2.4 三种数据的协同

日志、指标、链路,这三者不是孤立的。我见过很多团队只采集一种数据,结果排查问题时总是缺一块。

举个例子:某个接口突然变慢。指标告诉你 CPU 没涨、内存没涨,日志里也没有错误。这时候链路追踪就派上用场了——它告诉你慢在哪个服务、哪个步骤。

反过来,链路追踪发现某个服务频繁超时,但不知道原因。这时候看日志,发现是数据库连接池满了。再看指标,确认连接数确实飙高了。

所以我的建议是:三种数据都要采,但不要一次性全上。先上指标,再上日志,最后上链路。每一步都跑通、验证、优化,再走下一步。

我的习惯: 在 Prometheus 的告警规则里,把链路追踪的 TraceID 也带上。这样告警时可以直接跳转到 Jaeger 查看完整链路,省去手动关联的时间。
运维数据采集体系 日志数据 指标数据 链路数据 Filebeat / Logstash Prometheus / Exporter Jaeger / Zipkin Agent 统一存储层 Elasticsearch / Thanos / Cassandra 告警 / 监控大屏 / 链路分析 / 日志检索

这张图展示了数据采集的整体架构。从下往上看:数据源(日志、指标、链路)→ 采集层(Filebeat、Prometheus、Jaeger Agent)→ 统一存储 → 上层应用。

记住一句话:采集是基础,存储是核心,分析是目的。采集做不好,后面全是白费。


公众号:蓝海资料掘金营,微信deep3321