0%

ELKF

ELKF 日志系统:Filebeat+ELK 的轻量日志采集方案详解

ELKF(Elasticsearch + Logstash + Kibana + Filebeat)是在传统 ELK 基础上引入 Filebeat 的增强方案。由于 Logstash(基于 JVM)资源消耗较高,不适合在海量应用节点上直接部署,而 Filebeat(轻量级 Go 语言工具)能以极低的 CPU / 内存占用实现日志采集,形成 “应用日志→Filebeat 采集→Logstash 处理→Elasticsearch 存储→Kibana 可视化” 的完整链路,成为分布式系统日志管理的主流架构。

ELKF 核心架构与组件分工

ELKF 的核心价值在于解耦日志采集与处理,通过 Filebeat 实现 “轻量采集”,Logstash 实现 “复杂处理”,两者协同解决传统 ELK 在大规模部署时的资源占用问题。

架构链路图

1
2
[应用服务器]                [中间件服务器]                [存储与可视化服务器]
应用日志 → Filebeat采集 → Logstash过滤清洗 → Elasticsearch存储 → Kibana可视化

组件分工对比

组件 角色定位 核心优势 部署位置
Filebeat 日志采集器 轻量(<10MB 内存)、高可靠(断点续传) 应用服务器节点
Logstash 日志处理管道 支持 200 + 插件、复杂过滤(解析 / 脱敏 / 转换) 独立中间件集群
Elasticsearch 日志存储与检索引擎 分布式、实时索引、全文搜索 存储集群(3 + 节点)
Kibana 日志可视化平台 检索界面、仪表盘、告警配置 前端服务节点

Filebeat 核心配置与实战

Filebeat 是 ELKF 的 “入口”,负责从应用服务器采集日志并发送到 Logstash(或直接到 Elasticsearch)。其核心配置文件为filebeat.yml,需重点关注日志输入源(Inputs)输出目的地(Outputs)

1. 基础配置:采集文件日志并发送到 Logstash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# ============================== Filebeat Inputs ===============================
filebeat.inputs:
- type: log # 输入类型:文件日志(其他类型:stdin、tcp、udp等)
enabled: true # 启用该输入配置
paths: # 日志文件路径(支持通配符,可配置多个)
- /var/log/nginx/access.log # Nginx访问日志
- /opt/app/logs/*.log # 自定义应用日志(如Java应用日志)
- /home/user/app/*.log # 其他路径日志
exclude_lines: ['^#'] # 排除以#开头的注释行(可选)
include_lines: ['ERROR', 'WARN'] # 仅采集包含ERROR/WARN的日志(可选,缩小范围)
ignore_older: 72h # 忽略72小时未修改的旧日志(避免采集历史冗余日志)
scan_frequency: 10s # 扫描日志文件变化的频率(默认10秒,可根据日志生成频率调整)
harvester_buffer_size: 16384 # 读取日志的缓冲区大小(默认16KB,大日志可增大)

# 自定义字段:用于区分不同应用/环境的日志(后续Logstash/Kibana可基于该字段筛选)
fields:
app: user-service # 应用名称
env: prod # 环境(生产/测试)
fields_under_root: false # 自定义字段是否放在顶层(false表示放在fields子对象下)

# 处理多行日志(如Java堆栈信息、异常日志)
multiline:
pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}' # 匹配日志开头的日期格式(如2024-08-23)
negate: true # 不匹配pattern的行(即非日期开头的行)
what: previous # 合并到上一行(解决堆栈日志被拆分为多行的问题)
max_lines: 1000 # 单个多行日志的最大行数(避免内存溢出)
timeout: 5s # 多行日志合并超时时间

# ============================== Filebeat Outputs ==============================
output.logstash:
hosts: ['192.168.1.100:5044'] # Logstash地址(格式:IP:端口,多节点用逗号分隔)
worker: 2 # 发送日志的并发worker数量(建议等于CPU核心数的1/2)
bulk_max_size: 2048 # 批量发送的最大日志条数(默认2048,大日志可减小)
compression_level: 3 # 压缩级别(0-9,3为平衡性能与压缩率)

# ============================== Filebeat Logging ==============================
logging.level: info # Filebeat自身日志级别(info/debug/warn,生产环境用info)
logging.to_files: true # 输出到文件
logging.files:
path: /var/log/filebeat/ # Filebeat日志路径
name: filebeat.log
rotateeverybytes: 10485760 # 日志滚动阈值(10MB)
keepfiles: 7 # 保留7个滚动日志文件

2. 关键配置解析

(1)Inputs 核心参数
  • paths:日志路径是核心,支持通配符(匹配任意字符,*递归匹配子目录)。例如:
    • /opt/app/logs/**/*.log:采集logs目录及其所有子目录下的.log文件;
    • /var/log/nginx/access.log*:采集access.log及滚动文件(如access.log.1)。
  • multiline:解决 “多行日志拆分” 问题(如 Java 异常堆栈、JSON 日志跨行吗)。核心是通过pattern定义 “日志起始行规则”,将非起始行合并到上一行。
  • ignore_older:避免 Filebeat 启动时采集历史久远的日志(如服务器重启后,不采集 3 天前的旧日志),减少初始数据量。
(2)Outputs 核心参数
  • hosts:Logstash 的 “Beats 输入” 端口(默认 5044,需在 Logstash 中启用beats输入插件);
  • bulk_max_size:批量发送大小直接影响性能 —— 过小会增加网络请求次数,过大可能导致 Logstash 处理超时,需根据日志大小调整(如单条日志 1KB,2048 条约 2MB,适合大多数场景)。

3. Filebeat 启动与验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 检查配置文件语法(避免配置错误)
filebeat test config -c /etc/filebeat/filebeat.yml

# 2. 测试输出连接(验证能否连接到Logstash)
filebeat test output -c /etc/filebeat/filebeat.yml

# 3. 启动Filebeat(后台运行,生产环境建议用systemd管理)
# 方式1:直接后台运行
filebeat -e -c /etc/filebeat/filebeat.yml &

# 方式2:systemd启动(推荐,支持开机自启)
systemctl enable filebeat # 开机自启
systemctl start filebeat # 启动
systemctl status filebeat # 查看状态

# 4. 验证日志采集(查看Filebeat日志,确认无报错)
tail -f /var/log/filebeat/filebeat.log

Logstash 配置:接收 Filebeat 数据并处理

Logstash 需配置 “Beats 输入” 接收 Filebeat 发送的日志,再通过 Filter 进行清洗,最终输出到 Elasticsearch。以下是 ELKF 场景的典型配置(logstash-filebeat.conf):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# ============================== Input ===============================
input {
# 启用Beats输入,监听5044端口(与Filebeat的output.logstash.hosts对应)
beats {
port => 5044
codec => json # Filebeat默认以JSON格式发送数据,此处需匹配
}
}

# ============================== Filter ===============================
filter {
# 1. 解析Filebeat的自定义字段(如app、env)
if [fields][app] == "user-service" { # 仅处理user-service的日志
# 2. 解析非结构化日志(以Java应用日志为例,格式:[2024-08-23 10:30:00] [ERROR] [traceId:123] 报错信息)
grok {
match => {
"message" => "\[%{TIMESTAMP_ISO8601:log_time}\] \[%{LOGLEVEL:log_level}\] \[traceId:%{DATA:trace_id}\] %{GREEDYDATA:log_content}"
}
remove_field => ["message"] # 解析后删除原始message字段,减少存储
add_field => { "service" => "%{[fields][app]}" } # 提取fields.app到顶层字段service
}

# 3. 转换时间字段(将log_time转为Elasticsearch的@timestamp,用于时间筛选)
date {
match => ["log_time", "yyyy-MM-dd HH:mm:ss"]
target => "@timestamp"
remove_field => ["log_time"] # 转换后删除原log_time
}

# 4. 日志脱敏(如隐藏手机号)
mutate {
gsub => [
"log_content", "1[3-9]\d{9}", "****" # 将手机号替换为****
]
}
}

# 其他应用的日志处理(可新增if分支)
if [fields][app] == "order-service" {
# ... 类似解析逻辑
}
}

# ============================== Output ===============================
output {
# 输出到Elasticsearch,按应用+日期创建索引(便于管理)
elasticsearch {
hosts => ["192.168.1.101:9200", "192.168.1.102:9200"] # Elasticsearch集群地址
index => "%{[fields][app]}-log-%{+YYYY.MM.dd}" # 索引名:应用名-日志-日期(如user-service-log-2024.08.23)
user => "elastic" # Elasticsearch用户名(若启用安全认证)
password => "Elastic@123"
}

# 调试用:输出到控制台(生产环境可注释)
stdout { codec => rubydebug }
}

ELKF 与传统 ELK 的核心差异

对比维度 传统 ELK(无 Filebeat) ELKF(Filebeat+ELK)
采集层资源占用 高(Logstash 需 JVM,内存 > 512MB) 极低(Filebeat<10MB 内存,CPU<5%)
部署规模 适合小规模节点(<50 个应用节点) 支持大规模集群(上千个应用节点)
采集可靠性 无断点续传(Logstash 重启后重采全量) 支持断点续传(记录文件读取位置)
日志类型支持 依赖 Logstash 插件 原生支持文件、TCP、UDP、容器日志等
复杂度 低(单组件采集 + 处理) 中(多组件协同,但配置模板化)

ELKF 最佳实践

1. Filebeat 部署建议

  • 每节点部署一个 Filebeat:直接在应用服务器上安装,避免跨节点采集导致的网络延迟;
  • 使用 systemd 管理进程:确保 Filebeat 异常退出后自动重启,提高可靠性;
  • 分环境配置:开发 / 测试 / 生产环境使用不同的filebeat.yml,通过fields.env区分日志来源。

2. Logstash 性能优化

  • 控制 worker 数量:通过pipeline.workers: 4(建议等于 CPU 核心数)调整并发处理线程;
  • 批量处理pipeline.batch.size: 1000(批量处理日志条数,平衡吞吐量与延迟);
  • 过滤无用日志:在 Filebeat 层通过include_lines/exclude_lines过滤,减少 Logstash 处理压力。

3. Elasticsearch 索引管理

  • 按应用 + 日期拆分索引:如user-service-log-2024.08.23,便于按应用筛选和生命周期管理;
  • 启用 ILM(索引生命周期):设置 “热→温→冷→删除” 策略(如热数据保留 7 天,冷数据保留 30 天,30 天后自动删除);
  • 合理设置分片:每个索引分片数 = 节点数(如 3 节点集群,分片数 = 3),每个分片大小不超过 50GB。

4. 日志链路追踪

  • 在 Filebeat 自定义字段中添加trace_id(若应用支持分布式追踪),或通过 Logstash 解析日志中的traceId字段;
  • 在 Kibana 中通过trace_id筛选,实现 “单请求全链路日志” 查询,快速定位分布式问题。

常见问题与解决方案

1. Filebeat 采集不到日志

  • 检查路径权限:Filebeat 运行用户(如 root)是否有日志文件的读权限(chmod 644 /opt/app/logs/*.log);
  • 查看 ignore_older 配置:若日志超过ignore_older时间(如 72h),Filebeat 会忽略,需调整该参数;
  • 检查 multiline 配置:若pattern不匹配日志起始行,会导致日志无法正确合并,需根据实际日志格式调整正则。

2. Logstash 接收不到 Filebeat 数据

  • 检查网络连通性:应用服务器能否 ping 通 Logstash 节点,且 5044 端口未被防火墙拦截(telnet 192.168.1.100 5044);
  • 验证 Logstash 输入配置:确保beats输入的port与 Filebeat 的output.logstash.hosts一致;
  • 查看 Logstash 日志tail -f /var/log/logstash/logstash-plain.log,排查是否有连接报错。

3. Kibana 中看不到日志

  • 检查 Elasticsearch 索引:通过curl http://192.168.1.101:9200/_cat/indices确认索引是否创建;
  • 创建 Kibana 索引模式:在 Kibana“Stack Management→索引模式” 中,创建匹配索引(如user-service-log-*),并指定时间字段@timestamp
  • 时间范围筛选:Kibana 默认筛选 “最近 15 分钟” 日志,若日志时间不在该范围,需调整时间筛选条件。

总结

ELKF 通过引入 Filebeat 解决了传统 ELK 在大规模部署时的资源占用问题,形成 “轻量采集→复杂处理→分布式存储→可视化分析” 的企业级日志方案。核心要点:

  1. Filebeat 配置需聚焦 “日志路径” 和 “多行处理”,确保采集可靠;
  2. Logstash 需通过beats输入接收数据,重点做好日志解析与脱敏;
  3. 索引管理和性能优化是 ELKF 稳定运行的关键,需结合 ILM 和分片策略;
  4. 利用自定义字段(如appenvtrace_id)提升日志筛选与链路追踪能力。

ELKF 不仅适用于中小型应用,也能支撑大规模分布式系统的日志管理需求,是企业级日志平台的首选架构之一

欢迎关注我的其它发布渠道