3. 日志采集基础:Rsyslog、Filebeat、Flume 等采集工具对比与实践

日志采集,说白了就是把散落在各个服务器、容器、应用里的日志聚起来。你想想看,要是没有这步,后面什么告警、分析、审计全部白搭。我刚开始搞运维时试过直接用 scp 拉文件,后来就再也没那么干过了——太蠢,太慢,还容易丢。

3.1 为什么不能用 “cat /var/log/*” 搞定?

我见过不少新手直接写个 shell 脚本:tail -f /var/log/syslog >> /central/log。嗯,简单是简单,但问题一堆:

  • 网络断了,日志就丢了
  • 源端挂了,没人重启采集
  • 格式不统一,下游解析累死
  • 性能开销,大流量时 CPU 打满

我在项目中遇到过一家创业公司,用 rsync 每分钟同步一次日志,结果高峰时把数据库搞死了。所以,专业的事交给专业的工具——Rsyslog、Filebeat、Flume 就是干这个的。

3.2 Rsyslog:老牌守护者,稳如磐石

Rsyslog 是 Linux 系统自带的 syslog 加强版。它走的是 UDP/TCP 传输,天然适合系统日志、防火墙日志这类传统场景。

特点:

  • 原生支持 syslog 协议,零改造
  • 模块化设计(imfile 可以读文件)
  • 可以在服务端做简单过滤、重写
  • 资源占用低,但吞吐量上限约 10 万 EPS(事件/秒)
适用场景: 服务器系统日志、网络设备日志(Cisco、Fortinet)、中小规模集中采集。

配置示例: 在客户端发送 auth.log 到中央日志服务器。

# /etc/rsyslog.conf 追加
*.* @@192.168.1.100:514   # @@ 表示 TCP,@ 表示 UDP
# 或者用 imfile 模块采集指定文件
module(load="imfile")
input(type="imfile"
      File="/var/log/app/application.log"
      Tag="app-log"
      Severity="info"
      Facility="local7")
小技巧: 生产环境建议用 TCP + 磁盘队列,防止突增流量丢日志。我习惯加一句 $ActionQueueType LinkedList。

3.3 Filebeat:轻量级采集新贵

如果你用 ELK 栈,那 Filebeat 几乎是标配。它由 Golang 编写,单个二进制文件,资源极低(内存通常 20~50 MB)。

特点:

  • 自动感知日志变动(类似 tail -F)
  • 支持多行合并(比如 Java 异常栈)
  • 内置模块(Nginx、MySQL、Docker 等一键启用)
  • 可靠传输:确认机制 + 重试 + 保证至少一次
  • 上报 ES 时可加小处理(用 processors)
注意: Filebeat 不是万能的。它不会对日志做复杂转换(那是 Logstash 的事)。如果你需要字段提取、路由过滤,要在 Filebeat 之后加个中间处理层。

配置示例: 采集访问日志发到 Logstash。

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/nginx/access.log
  fields:
    type: nginx_access

output.logstash:
  hosts: ["192.168.1.101:5044"]
适用场景: 容器化环境、微服务日志、高吞吐应用(可达 10万 EPS+)、与 Elasticsearch 结合紧密。

3.4 Flume:大数据管道,重器

Flume 是 Apache 的日志采集框架,从 Hadoop 生态里长出来的。架构比前两个复杂:Source → Channel → Sink,全都在一个配置里定义。

特点:

  • 强大的容错机制(Channel 可以是文件、内存、JDBC)
  • 支持各种自定义 Source/Sink(Kafka、HDFS、HBase…)
  • 不需要消费端是实时流,可以批量写 HDFS
  • 配置比较重,依赖 Java 运行时
  • 吞吐上限高(几十万 EPS),但延迟稍大

配置示例: 采集日志文件写到 Kafka。

agent.sources = src1
agent.channels = ch1
agent.sinks = sink1

agent.sources.src1.type = spooldir
agent.sources.src1.spoolDir = /var/log/flume
agent.sources.src1.channels = ch1

agent.channels.ch1.type = memory
agent.channels.ch1.capacity = 10000

agent.sinks.sink1.type = org.apache.flume.sink.kafka.KafkaSink
agent.sinks.sink1.kafka.topic = logs
agent.sinks.sink1.kafka.bootstrap.servers = kafka1:9092
agent.sinks.sink1.channel = ch1
我在项目里踩过的坑: 用 memory channel 如果挂掉会丢日志。曾经有一次 Kafka 集群抖动,memory 里的日志全丢,从此我全部换成了 file channel 或 Kafka Channel 本身。

3.5 三剑客横向对比

维度 Rsyslog Filebeat Flume
协议/输入 syslog、imfile、UDP/TCP 文件、Stdin、TCP/UDP 插件 Avro、Spooldir、Kafka 等
可靠性 磁盘队列,至少一次 确认 + 重试,至少一次 事务型,Exactly Once 可配
吞吐量 中等(~10万 EPS) 高(~20万 EPS) 最高(30万+ EPS)
资源占用 低 极低 中等(JVM 开销)
运维复杂度 简单 简单 中高
典型下游 ELK、Remote Syslog Elasticsearch、Logstash Kafka、HDFS
日志采集工具对比 —— 架构 vs 场景 日志源 - 系统日志 /var/log - Nginx 访问日志 - 应用日志 (Java 栈) - 容器 stdout - 网络设备 syslog 采集层 Rsyslog 系统日志、网络设备 Filebeat 容器、微服务、文件 Flume 大数据管道、HDFS 目标端 Elasticsearch Logstash / Kafka HDFS / HBase 中央 Syslog 服务器 选型口诀:传统系统用 Rsyslog,容器微服用 Filebeat,大数据批用 Flume

3.6 实战选型建议与避坑

说得再多不如动手试。我一般这样选:

  • 采集系统日志或网络设备日志 → 直接用 Rsyslog,零改造,稳。
  • 容器环境或 Java 应用 → Filebeat,资源省,对接 ES 爽。
  • 要写 HDFS/Kafka 且对可靠性要求极高 → Flume,哪怕重一点也值得。
我曾经踩过的坑: 用 Filebeat 采集超多小日志文件(比如每一个 Pod 一个文件),结果 inotify 耗尽。解决方法是增大 max_procs 和 close_inactive,或者改成按目录 tail。
另一个经验: 生产环境一定要测试断网恢复。我习惯在实验室先模拟 kill 掉目标端口,观察工具能否自动重连且不丢日志。Rsyslog 的磁盘队列、Filebeat 的 registry 文件、Flume 的 file channel,都是救命稻草。

好了,采集层稳定了,下一站就是怎么把日志安全合规地传送到处理中心。这部分咱们后面聊工具链的时候再说。