3、日志采集技术:Filebeat原理与部署、Logstash配置实战、Fluentd入门
日志采集是整个监控体系的起点。你想想看,如果连日志都收不上来,后面再牛的分析工具也是白搭。这一章我重点讲三个主流采集工具:Filebeat、Logstash 和 Fluentd。它们各有各的脾气,用对了地方就是神器。
3.1 Filebeat 原理与部署
Filebeat 是 Elastic 家的轻量级采集器。说白了,它就是专门干「读文件、发数据」这一件事的。为什么我推荐它做第一道采集层?因为它够轻、够稳、够省资源。
3.1.1 核心原理
Filebeat 的工作流程其实很简单:
- Harvester(收割者):每个日志文件对应一个 Harvester,负责逐行读取内容
- Spooler(缓存池):Harvester 读到的数据先放到内存缓存里
- Publisher(发送器):Spooler 攒够一批数据后,批量发送到输出端
嗯,这里要注意一个关键点:Filebeat 会记录每个文件的读取偏移量。它把偏移量存在 registry 文件里。就算进程重启了,它也能从上次断掉的地方继续读。我在项目中遇到过一台服务器意外断电,重启后 Filebeat 自动续读,一条日志都没丢。
避坑指南:我曾经遇到过 Filebeat 重复发送日志的情况。查了半天,发现是 registry 文件被误删了。所以,千万别手贱去删 registry。如果非要重置,先停掉 Filebeat 再删。
3.1.2 部署实战
部署 Filebeat 其实就三步:下载、配置、启动。我习惯用 RPM 包安装,方便管理。
# 1. 下载并安装
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.17.0-x86_64.rpm
rpm -ivh filebeat-7.17.0-x86_64.rpm
# 2. 配置 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.elasticsearch:
hosts: ["192.168.1.10:9200", "192.168.1.11:9200"]
username: "elastic"
password: "your_password"
# 3. 启动并设置开机自启
systemctl start filebeat
systemctl enable filebeat
我个人习惯在 fields 里加上服务名和环境标签。这样到了 Elasticsearch 里,一眼就能看出日志来自哪个服务。你想想看,几十台服务器同时发日志,没有标签怎么区分?
小技巧:Filebeat 支持多行日志合并。比如 Java 的堆栈异常,一行是报错信息,后面跟着好几行堆栈。用 multiline.pattern 和 multiline.negate 就能把它们合并成一条完整日志。
3.2 Logstash 配置实战
Logstash 是 ELK 栈里的「数据加工厂」。Filebeat 只管采集,Logstash 负责解析、过滤、转换。说白了,它就是个管道:输入 → 过滤 → 输出。
3.2.1 核心配置结构
一个标准的 Logstash 配置文件长这样:
input {
beats {
port => 5044
ssl => true
ssl_certificate => "/etc/logstash/certs/logstash.crt"
ssl_key => "/etc/logstash/certs/logstash.key"
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "@timestamp"
}
mutate {
remove_field => ["message", "original"]
}
}
output {
elasticsearch {
hosts => ["192.168.1.10:9200"]
index => "nginx-access-%{+YYYY.MM.dd}"
}
stdout { codec => rubydebug }
}
这里我重点说几个实战经验:
- grok 是核心:它用正则表达式解析非结构化日志。我建议先用 Grok Debugger 在线调试,别直接上生产环境试
- date 插件很重要:很多日志的时间格式跟系统时间不一样。用 date 插件把日志里的时间戳转成
@timestamp,这样在 Kibana 里才能按正确时间排序 - mutate 用来瘦身:去掉不需要的字段,减少存储压力。我曾经见过有人把整个 message 字段原封不动存进去,那叫一个浪费
性能警告:Logstash 是 Java 写的,吃内存大户。我建议给 Logstash 至少分配 2GB 堆内存。如果日志量特别大(每天几百 GB),可以考虑用 pipeline.workers 参数调整并发数。
3.2.2 实战案例:解析 Nginx 日志
我记得有一次帮客户处理 Nginx 日志解析。他们的日志格式是自定义的,标准 grok 模式匹配不上。怎么办?自己写正则呗。
filter {
grok {
match => {
"message" => "%{IPORHOST:client_ip} - %{DATA:user} \[%{HTTPDATE:timestamp}\] \"%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}\" %{NUMBER:status} %{NUMBER:bytes} \"%{DATA:referrer}\" \"%{DATA:agent}\" %{NUMBER:response_time}"
}
}
# 把响应时间转成浮点数
mutate {
convert => { "response_time" => "float" }
}
# 如果响应时间超过 3 秒,打上慢查询标签
if [response_time] > 3.0 {
mutate {
add_tag => ["slow_request"]
}
}
}
你看,解析完还能做条件判断。响应时间超过 3 秒的请求,自动打上 slow_request 标签。到了 Kibana 里直接过滤慢查询,排查问题快多了。
3.3 Fluentd 入门
Fluentd 是另一个日志采集利器,在 Kubernetes 生态里用得特别多。它跟 Logstash 最大的区别是:Fluentd 用 Ruby 写的,插件生态更丰富,资源占用更小。
3.3.1 核心概念
Fluentd 的配置思路跟 Logstash 很像,也是 Input → Buffer → Output。但它的配置语法更简洁:
<source>
@type tail
path /var/log/nginx/access.log
pos_file /var/log/td-agent/nginx-access.log.pos
tag nginx.access
<parse>
@type nginx
</parse>
</source>
<match nginx.access>
@type elasticsearch
host 192.168.1.10
port 9200
logstash_format true
<buffer>
@type file
path /var/log/td-agent/buffer/nginx
flush_interval 5s
</buffer>
</match>
我个人觉得 Fluentd 的 Buffer 机制 设计得特别好。它把数据先缓存到磁盘,再批量发送。这样就算 Elasticsearch 挂了,数据也不会丢。我曾经测试过,把 ES 停掉 10 分钟,Fluentd 的缓冲区稳稳地存着数据,恢复后自动续传。
3.3.2 什么时候用 Fluentd?
我建议这样选型:
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 纯日志采集,不需要复杂处理 | Filebeat | 最轻量,资源占用最低 |
| 需要大量解析、过滤、转换 | Logstash | grok 插件强大,处理能力强 |
| Kubernetes 环境,需要高可靠 | Fluentd | DaemonSet 部署方便,缓冲机制可靠 |
| 数据需要发往多个目的地 | Fluentd | Output 插件丰富,支持路由复制 |
我的建议:别纠结「哪个最好」。实际项目中往往是组合使用:Filebeat 采集 → Kafka 缓冲 → Logstash 解析 → Elasticsearch 存储。各取所长,才是架构师的思路。
3.4 本章小结
日志采集这块,说白了就是三个要点:
- Filebeat:轻量采集,适合做第一道关卡
- Logstash:强力解析,适合做数据加工厂
- Fluentd:高可靠缓冲,适合做数据中转站
嗯,下一章我会讲日志存储和索引优化。到时候你会看到,采集上来的数据怎么存才能查得快、省空间。咱们下章见。