第二章:运维数据采集——日志、指标、调用链、事件数据的采集方法与工具

聊到智能运维,很多人第一反应就是“上模型”、“搞算法”。但我得说句实在话——数据采不好,后面全是白搭。模型再牛,喂进去的是脏数据、残缺数据,出来的结果你敢信吗?

这一章,咱们就聊聊运维数据的四大金刚:日志、指标、调用链、事件。这四类数据,说白了就是运维的“眼耳鼻舌身意”。我个人的习惯是,每到一个新团队,第一件事就是看他们的数据采集链路通不通。不通?那后面的告警、巡检、根因分析,全是空中楼阁。

2.1 日志采集:最古老也最核心的数据源

日志这东西,又爱又恨。爱它是因为它最详细,恨它是因为它太能“生”了。一个高并发系统,一天能吐出几个TB的日志。怎么采?怎么存?怎么用?

2.1.1 日志采集的典型架构

我个人比较推崇的架构是“Agent + 缓冲 + 传输 + 存储”四层模型。你想想看,如果让应用直接写数据库,那数据库早就被写爆了。

# 一个典型的Filebeat配置示例
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.kafka:
  hosts: ["kafka1:9092", "kafka2:9092"]
  topic: "app-logs"
  partition.round_robin:
    reachable_only: true

嗯,这里要注意一个坑。我曾经遇到过,日志里有多行异常栈,结果Filebeat默认按行切割,一条异常被拆成了几十条。排查问题时,看着那叫一个头疼。所以多行合并这个配置,一定要加上。

2.1.2 常用日志采集工具对比

工具 语言 资源消耗 适用场景
Filebeat Go 轻量级采集,适合容器和物理机
Logstash Java 中高 需要复杂过滤和转换的场景
Fluentd Ruby/C 插件丰富,适合多云环境
Vector Rust 极低 高性能场景,替代Logstash

我个人习惯,采集端用Filebeat或Vector,中间加一层Kafka做缓冲。为什么?因为一旦下游的ES挂了,日志不会丢。这个教训,是我在一次大促压测时用真金白银换来的。

2.2 指标采集:量化一切

指标数据,说白了就是“数字化的心跳”。CPU用了多少?QPS多少?延迟多少?这些数据,是判断系统健康状态最直接的依据。

2.2.1 指标的类型

你想想看,指标其实就三种:

  • Counter(计数器):只增不减,比如请求总数
  • Gauge(仪表盘):可增可减,比如当前连接数
  • Histogram(直方图):分布统计,比如请求延迟的P99

我在项目中遇到过,有人把Counter当Gauge用,结果算出来的QPS曲线跟心电图似的,完全没法看。记住:Counter适合算速率,Gauge适合看瞬时值

2.2.2 Prometheus + Exporter 生态

现在指标采集,基本是Prometheus的天下了。它的核心思想是“拉模式”——由Prometheus Server主动去拉取目标的数据。

# 一个自定义Exporter的示例(Python)
from prometheus_client import start_http_server, Gauge
import psutil
import time

# 定义指标
cpu_usage = Gauge('cpu_usage_percent', 'Current CPU usage')

if __name__ == '__main__':
    start_http_server(8000)
    while True:
        cpu_usage.set(psutil.cpu_percent())
        time.sleep(15)

这个代码很简单,但很实用。我经常用它来采集一些“非标”指标,比如业务订单量、排队长度等。Prometheus的拉模式有个好处:采集端不需要关心存储在哪,只管暴露端口就行。

小技巧: 如果你的服务是短生命周期的(比如K8s Job),拉模式可能来不及采集。这时候可以考虑用Pushgateway做中转。但我建议慎用,因为它容易成为单点。

2.3 调用链采集:追踪每一次请求

微服务架构下,一个请求可能经过十几个服务。出了问题,你怎么知道是哪个环节慢了?调用链就是干这个的。

2.3.1 调用链的核心概念

说白了,调用链就是给每个请求发一个“身份证”(TraceID),然后在每个服务节点上记录“什么时候进来、什么时候出去、干了什么”。

  • Trace:一次完整的请求链路
  • Span:链路中的一个步骤
  • SpanContext:传递TraceID和SpanID的上下文

2.3.2 采集工具选型

目前主流的有三个:

工具 协议 侵入性 社区活跃度
Jaeger OpenTracing
Zipkin OpenTracing
SkyWalking OpenTelemetry 极低(Java Agent)

我个人比较推荐SkyWalking。为什么?因为它支持Java Agent无侵入接入。我曾经在一个老项目上,代码改不动,但又要做调用链监控。SkyWalking的Agent一挂,啥都不用改,链路数据就出来了。那种感觉,真爽。

避坑指南: 调用链采集是有采样率的。我曾经见过有人把采样率设成100%,结果高并发下Agent直接把CPU打满了。建议生产环境采样率控制在1%~10%,问题排查时再临时调高。

2.4 事件采集:告警与变更的记录

事件数据,很多人会忽略。但我觉得,事件是运维的“病历本”。什么时候发了告警?谁改了配置?什么时候重启的?这些信息,对于根因分析至关重要。

2.4.1 事件的来源

  • 告警事件:来自监控系统(Prometheus Alertmanager、Zabbix等)
  • 变更事件:来自CMDB、发布系统、K8s事件
  • 操作事件:来自堡垒机、审计日志

2.4.2 事件采集的标准化

我建议,所有事件统一采用CloudEvents规范。这样不管来源是什么,格式都是一致的,后续做关联分析就方便了。

{
  "specversion": "1.0",
  "type": "com.example.alert.cpu_high",
  "source": "/monitoring/prometheus",
  "subject": "host-01",
  "id": "event-12345",
  "time": "2024-01-15T10:30:00Z",
  "datacontenttype": "application/json",
  "data": {
    "severity": "critical",
    "metric": "cpu_usage",
    "value": 95.2,
    "threshold": 90
  }
}

嗯,这里有个经验。事件数据一定要带上时间戳和来源。我曾经排查一个故障,发现告警时间和实际故障时间差了5分钟。为什么?因为采集Agent的时间没同步。从那以后,我强制所有采集节点都跑NTP。

2.5 知识体系总览

说了这么多,咱们用一张图来总结一下这四类数据的采集链路。这张图是我自己画的一个框架,每次做数据治理时都会拿出来对照。

运维数据采集知识体系 数据源层 📝 日志文件 📊 系统指标 🔗 调用链 🔔 事件 采集层 Filebeat / Vector Prometheus Exporter SkyWalking Agent Webhook / API 传输与缓冲层 Kafka Redis Stream RabbitMQ NATS 存储与分析层 Elasticsearch Prometheus Jaeger/ES ClickHouse

这张图展示了从数据源到存储的完整链路。你想想看,每一层都有不同的工具和策略。但核心思想只有一个:数据要采得全、传得稳、存得下

2.6 我的建议

最后,给各位几个实操建议:

  1. 先做标准化,再做采集。日志格式、指标命名、事件结构,先定好规范。不然数据采上来也是垃圾。
  2. 采集链路一定要有缓冲。Kafka是标配,别让采集端直接写存储。
  3. 关注数据量。我曾经见过一个团队,日志采集量一天涨了10倍,结果Kafka集群直接挂了。做好限流和采样。
  4. 监控你的采集系统本身。采集链路挂了,你都不知道。我习惯给采集Agent加一个健康检查接口,用Prometheus盯着。

好了,这一章就聊到这儿。数据采好了,下一章咱们就可以开始聊怎么用这些数据训练模型了。


专注资料整理