一、FileBeat 基础概述
1. 定位与作用
Filebeat 是 Elastic 官方推出的轻量级日志采集器,基于 Go 语言开发,无 Java 依赖、资源占用极低,专门用于采集本地文件日志,常作为 ELK/EFK 架构的日志输入端。
- 核心定位:日志轻采集客户端,解决 Logstash 资源开销大的问题;
- 配套生态:输出可对接 Elasticsearch、Logstash、Kafka、Redis、File、Console 等;
- 核心优势:低 CPU / 内存、原生断点续传(registry)、多行合并(multiline)、日志过滤、自动文件发现。
2.EFK/ELK 架构角色
- Filebeat:采集服务器本地日志文件,轻量化;(也可以微处理)
- Logstash(可选):日志清洗、过滤、字段转换(复杂处理用);
- Elasticsearch:日志存储、检索、聚合(存储➕超强检索);
- Kibana:可视化、日志查询、告警面板(面板)。
标准两条链路:
- 简单链路:Filebeat → Elasticsearch → Kibana
- 复杂清洗链路:Filebeat → Kafka → Logstash → Elasticsearch → Kibana
3. 核心组件构成
Filebeat 内部两大核心模块:
- Inputs(输入源):定义要采集哪些文件、采集规则(最常用 filestream input);
- Outputs(输出端):定义日志发往何处(ES/Logstash/Kafka); 配套功能组件:
- Processor:本地轻量日志过滤、字段修改(替代简单 Logstash 逻辑)
- Modules:内置日志解析模板(nginx、mysql、tomcat、systemd 等开箱即用)
- Registry:断点续传注册文件,记录文件偏移量
二、核心工作原理
1. 日志采集流程
- 文件发现:根据 inputs 配置的路径通配符扫描日志文件;
- 状态记录(Registry) :
- 默认路径:
./data/registry/filebeat - 持久化存储每个文件的读取偏移量、inode、设备号;
- 重启 Filebeat 不会重复采集已读日志,实现断点续传;
- 默认路径:
- 逐行读取:打开文件,从 registry 记录的 offset 开始读取;
- 多行合并(Multiline):堆栈日志、Java 异常多行合并为一条日志;
- Processor 本地处理:切割字段、删除无用字段、过滤脏数据;
- 队列缓存:内存队列(mem_queue)缓存日志,批量发送;
- Output 批量推送:批量输出到目标服务,失败自动重试。
2. 文件追踪机制(关键:解决日志切割、文件改名)
通过三元组唯一标识文件:inode + 设备ID + 文件路径
- 日志切割(logrotate)
- 原日志
app.log重命名为app.log.1,新建空app.log; - Filebeat 通过 inode 识别旧文件
app.log.1读完,切换读取新文件app.log;
- 原日志
- 文件删除 / 轮转
- 配置
close_*系列参数,空闲超时后关闭文件句柄,释放资源; - close_inactive关闭文件打开数,clean_inactive去除registry中的offset
- 配置
- 软链接:原生支持软链接日志文件采集。
3. Registry 断点续传机制
- 数据持久化到磁盘 json 文件,不会丢偏移;
- 风险场景:
- 直接删除 registry 目录 → 重启后全量重新采集所有日志;
- 日志文件被清空、inode 不变 → 从原有 offset 继续读,不会重复。
三、完整配置文件详解(filebeat.yml)
配置分为 6 大模块:Inputs、Global、Multiline、Processors、Output、Advanced 调优
1. 全局基础配置(fileabeat自身的配置,比如自己的日志)
# 日志级别:critical/error/warning/info/debug
logging.level: info
# 日志输出位置
logging.to_files: true
logging.files.path: ./logs
logging.files.name: filebeat.log
# 注册文件存储路径(断点续传核心)
filebeat.registry.path: ./data/registry
# 多久持久化一次偏移(默认5s)
filebeat.registry.flush: 5s
# 最大同时打开文件句柄数
filebeat.max_open_files: 64
2. Inputs 输入配置(filestream 主流,替代旧 prospector)
filebeat.inputs:
- type: filestream # 标准文件采集类型
enabled: true
# 日志路径,支持通配符
paths:
- /var/log/nginx/*.log
- /data/app/logs/*.log
- /data/tomcat/catalina.out
# 排除文件
exclude_files: ['.gz$']
# 采集起始模式:
# begin:从头读全部日志;end:只采集新增日志(线上默认)
start_position: end
# ========= 文件关闭策略(释放句柄)=========
# 文件多久无新日志就关闭句柄
close_inactive: 5m
# 文件被重命名/轮转后多久关闭
close_renamed: true
# 文件删除后关闭
close_removed: true
# 强制定时关闭所有文件,避免句柄泄露
close_eof: false
# ========= 扫描文件间隔 =========
scan_frequency: 10s # 多久扫描一次目录找新文件
# ========= 多行合并(Java异常、堆栈必开)=========
multiline.type: pattern
multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}' # 匹配日志开头时间
multiline.negate: true # 不匹配上面规则的行,归为上一条日志
multiline.match: after # 合并到上一行后面
multiline.max_lines: 500 # 最多合并行数,防止超大日志
# 自定义日志标签,用于ES区分业务
tags: ["nginx", "prod"]
# 自定义字段
fields:
app: nginx-service
env: production
# 自定义字段是否顶层存储,false则放入fields子对象
fields_under_root: false
Input 其他类型
tcp:采集 TCP 端口日志;udp:UDP 日志;stdin:标准输入;container:容器标准输出日志(Docker/K8s)。
3. Processors 本地预处理(无依赖,轻量清洗)
所有采集日志统一预处理,无需 Logstash:
processors:
# 1. 删除无用字段
- drop_fields:
fields: ["agent.ephemeral_id", "input.type"]
# 2. 过滤丢弃指定日志(过滤健康检查、垃圾日志)
- drop_event:
when:
contains:
message: "health check"
# 3. 添加自定义字段
- add_fields:
target: ''
fields:
region: hunan
# 4. 日志行裁剪,去除首尾空格
- trim_message:
# 5. 多行日志合并(也可写在input内)
# 6. 时间格式化、IP解析、JSON解码
- decode_json_fields:
fields: ["message"]
overwrite_keys: true # json字段覆盖顶层
add_error_key: true # json解析失败添加error标记
# 7. 切割URL、提取状态码、用户UA等
- dissect:
tokenizer: "%{time} %{status} %{url}"
field: "message"
4. Output 输出配置(4 种主流输出)
(1)输出到 Elasticsearch(直连方案)
output.elasticsearch:
hosts: ["127.0.0.1:9200", "es02:9200"]
# 认证
username: "elastic"
password: "xxxx"
# 索引命名,支持时间变量
index: "filebeat-nginx-%{+YYYY.MM.dd}"
# 批量发送大小
bulk_max_size: 1000
# 并发连接数
worker: 2
# 压缩传输
compression_level: 5
# 失败重试
retry.backoff.init: 1s
retry.backoff.max: 60s
(2)输出到 Kafka(高并发削峰,生产推荐)
output.kafka:
hosts: ["kafka01:9092", "kafka02:9092"]
topic: "log-nginx-prod"
partition.round_robin:
reachable_only: false
# 批量条数
bulk_max_size: 2048
# 压缩
compression: snappy
# kafka认证 sasl/plain
sasl.mechanism: PLAIN
sasl.user: admin
sasl.password: xxx
(3)输出到 Logstash(复杂清洗场景)
output.logstash:
hosts: ["127.0.0.1:5044"]
worker: 2
ssl.enabled: false
(4)输出到控制台(调试)
output.console:
pretty: true
5. 监控配置(Metricbeat 监控 Filebeat 自身)
monitoring.enabled: true
monitoring.elasticsearch:
hosts: ["127.0.0.1:9200"]
6. Modules 内置日志解析模块
Filebeat 内置现成日志解析模板,自动提取字段(nginx、mysql、redis、system、tomcat、docker 等)
# 启用nginx模块
filebeat.modules:
- module: nginx
access:
enabled: true
var.paths: ["/var/log/nginx/access.log"]
error:
enabled: true
启用后自动解析 status、request_time、ip、url、ua 等字段,无需手动 dissect。
四、核心调优参数(生产必配)
1. 发送性能调优
# 内存队列,缓存未发送日志
queue.mem:
events: 4096 # 队列最大日志条数
flush.min_events: 512 # 攒够多少条发送
flush.timeout: 1s # 最多等待多久发送一次,两个条件触发一个即可
output.elasticsearch.bulk_max_size: 1000 # 单次bulk条数,超过这个分多次发送
output.elasticsearch.worker: 4 # 并发发送线程
2. 文件句柄与资源释放
close_inactive: 5m:闲置 5 分钟关闭句柄,避免上千文件占满句柄;scan_frequency: 10s:高频日志可改为 1s,消耗少量 CPU;filebeat.max_open_files:服务器 ulimit 要大于该值,否则报错句柄不足。
3. 防日志丢失 / 重复
-
丢失场景:Filebeat 宕机、队列未刷出 → 开启持久队列(disk queue)
queue.disk:
enabled: true
path: ./data/diskqueue
max_size: 10G
磁盘队列会缓存未发送日志,进程重启不丢数据; 2. 重复采集场景 :删除 registry 目录、日志回滚、ES 重复消费 → 依靠 ES _id 去重(自己实现)或 kafka 幂等(手写代码实现)。
五、常用命令(Linux)
-
配置校验(上线前必执行)
校验yaml语法
filebeat test config -c /etc/filebeat/filebeat.yml
校验输入源能否读取文件
filebeat test inputs -c /etc/filebeat/filebeat.yml
校验输出连通性(ES/Kafka)
filebeat test output -c /etc/filebeat/filebeat.yml
-
前台调试运行(看实时日志)
filebeat -e -c /etc/filebeat/filebeat.yml
3.模块命令
#列出模块
filebeat modules list
#启动
filebeat modules enable nginx
#关闭
filebeat modules disable nginx
4.模板和图标
filebeat setup:
#一次性初始化工具,上传es的模板信息(定义字段类型)、kibana图表(不用自己创造仪表板)
六、高频生产问题与解决方案
1. Filebeat 重复采集日志
原因:registry 被删除、inode 变更、文件被清空、服务异常重启 解决:
- 禁止手动删除 registry;
- start_position: end 线上默认;
- ES 使用文档 ID 做幂等,避免重复索引。
2. 日志丢失(宕机丢日志)
原因:默认内存队列,未发送日志存在内存,进程销毁丢失 解决:开启 queue.disk 磁盘持久队列。
3. 文件句柄泄露,too many open files
原因:close_inactive 时间过长,大量日志文件打开不释放 解决:调小 close_inactive(3-5 分钟),调高系统 ulimit -n。
4. Java 异常堆栈日志拆分成多条
原因:未配置 multiline 多行合并 解决:匹配日志时间开头,negate=true 合并堆栈。
5. 采集日志极慢、堆积严重
优化方案:
- 增大 mem queue、bulk_max_size、worker 并发;
- 缩短 flush.timeout;
- 中间加 Kafka 削峰,避免直连 ES 压力过大;
- 过滤无用日志,减少传输量(drop_event processor)。
6. logrotate 切割日志后不读取新文件
解决:close_renamed: true,scan_frequency 缩短至 5s 内。
7. JSON 日志 message 未解析,全存在 message 字段
解决:添加 decode_json_fields 处理器,自动拆分 json 为独立字段。