数据采集与清洗:日志采集、指标采集与数据标准化

聊到运维数据可视化,第一步其实不是画图,而是把数据搞进来。我见过太多团队,图表做得花里胡哨,结果数据源是脏的、缺的、延迟的——那还不如不看。今天咱们就聊聊数据采集与清洗这层地基。

日志采集:Filebeat 与 Logstash 的配合

日志采集,说白了就是把服务器上散落的日志文件,安全、高效地送到中央存储里。我个人习惯用 Filebeat 做轻量采集,Logstash 做集中处理。为什么这么拆?

Filebeat 负责「搬砖」。它是个 Go 写的 agent,资源占用极低。我曾在 512MB 的云服务器上跑过,内存常驻也就 20MB 左右。它只做一件事:监控日志文件变化,读到新行就发出去。

核心配置示例(filebeat.yml):

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/nginx/access.log
    - /var/log/nginx/error.log
  fields:
    service: nginx
    env: production

output.logstash:
  hosts: ["192.168.1.100:5044"]

嗯,这里要注意:fields 字段特别有用。我习惯给每条日志打上服务名和环境标签,这样到了 Logstash 端就不用再猜了。

Logstash 负责「精加工」。它接收 Filebeat 传来的数据,做解析、过滤、格式化。我曾经遇到过一个坑:某团队直接把原始日志塞进 Elasticsearch,结果一个 JSON 字段解析失败,整条日志变成乱码。后来我在 Logstash 里加了 mutategrok 插件,才把数据洗干净。

避坑指南:我曾经在生产环境遇到过 Filebeat 背压导致日志丢失的问题。原因是 Logstash 处理不过来,Filebeat 的发送队列满了就直接丢弃。解决方案是开启 Filebeat 的 queue.mem.events 参数,并设置合理的 output.logstash.worker 数量。

指标采集:Prometheus Exporter 的实战

日志是离散的事件,指标是连续的数值。对于指标采集,Prometheus 生态是事实标准。每个需要监控的服务,都得有个 Exporter 来暴露指标端点。

我常用的 Exporter 清单:

Exporter 名称 监控对象 关键指标示例
node_exporter 服务器硬件/OS CPU 使用率、内存、磁盘 IO
blackbox_exporter 网络探测 HTTP 状态码、SSL 证书过期时间
mysqld_exporter MySQL 数据库 连接数、慢查询数、QPS
kube-state-metrics Kubernetes 集群 Pod 状态、Deployment 副本数

你想想看,如果指标采集频率太高,Exporter 本身会成为性能瓶颈。我建议对于常规指标(如 CPU、内存),采集间隔设为 15 秒;对于业务指标(如订单量),可以缩短到 5 秒。但别低于 1 秒,否则 Prometheus 的存储压力会剧增。

注意:自定义 Exporter 时,一定要遵循 Prometheus 的指标命名规范。比如用 _total 后缀表示计数器,用 _seconds 表示耗时。我见过有人把延迟指标命名为 request_latency_ms,结果在 Grafana 里做单位换算时搞混了——嗯,这种低级错误其实挺常见的。

数据清洗与标准化:从脏数据到可用数据

数据采集进来之后,你会发现一个残酷的现实:不同来源的数据,格式千奇百怪。有的用 JSON,有的用 CSV,有的干脆是纯文本。这时候就需要清洗和标准化。

清洗的核心步骤:

  1. 去重:网络抖动可能导致同一条日志被发送两次。我习惯在 Logstash 里用 fingerprint 过滤器生成唯一 ID,然后在 Elasticsearch 里做去重。
  2. 补全:比如日志里只有 IP 地址,没有地理位置。我会用 GeoIP 插件把 IP 转成城市和经纬度。
  3. 类型转换:字符串形式的数字要转成整数或浮点数,否则没法做聚合计算。
  4. 异常值过滤:比如某个指标突然变成负数,或者日志时间戳是 1970 年——这些明显是错误数据,直接丢弃。

标准化后的数据格式示例(JSON):

{
  "timestamp": "2025-03-20T14:30:00Z",
  "source": "nginx",
  "host": "web-01",
  "level": "error",
  "message": "connect() failed (111: Connection refused)",
  "metrics": {
    "response_time_ms": 2500,
    "status_code": 502
  },
  "tags": ["production", "web"]
}

为什么这么设计?timestamp 统一用 ISO 8601 格式,方便排序和时区转换。sourcehost 是必填字段,用于定位问题。metrics 里只放数值型数据,便于后续做数学运算。说白了,标准化就是给数据定个「规矩」,让所有工具都能理解它。

我的个人经验:清洗规则不要写得太死。我曾经在 Logstash 里写了一个严格的 JSON 校验,结果某个服务升级后多了一个字段,整条日志被丢弃了。后来我改成「宽松模式」——未知字段保留但不处理,只对关键字段做校验。这样既保证了数据质量,又不会因为小变动导致数据丢失。

总结一下

数据采集与清洗,说白了就是「把脏活干好」。Filebeat 和 Logstash 的组合,能搞定 90% 的日志场景;Prometheus Exporter 是指标采集的标配;而清洗标准化,决定了后续可视化的下限。我见过太多团队在可视化上花了大价钱,结果数据源一塌糊涂——嗯,地基没打好,楼盖得再高也白搭。

下一章咱们聊聊数据存储与索引,到时候会讲到 Elasticsearch 的 mapping 设计和时序数据库的选择。到时候见。