Filebeat/ELK 如何为不同日志配置不同的索引
Filebeat 给不同日志源打自定义字段(fields.type),Logstash 用条件判断路由到不同 ES 索引。本文给出 filebeat.yml 与 logstash.conf 的分流配置片段。
一句话回答:分两步:Filebeat 端为每个输入源加自定义字段(如 fields: {log_type: app1} 配合 fields_under_root: true)标记日志来源;Logstash 端用 if [log_type] == "app1" 条件判断,在 elasticsearch output 里分别指定 index => "app1-%{+yyyy.MM.dd}"。走 Logstash 时由其 output 决定索引;Filebeat 直连 ES 时可通过 output 的 index/indices 条件选择。下面采用传统索引示例,不是可直接用于任意 ILM/data stream 部署的完整配置。
第一步:Filebeat 打标记
filebeat.inputs:
- type: filestream
id: app1-logs
paths:
- /var/log/app1/*.log
fields:
log_type: app1
fields_under_root: true # 字段提升到顶层,Logstash 里用 [log_type] 引用
- type: filestream
id: app2-logs
paths:
- /var/log/app2/*.log
fields:
log_type: app2
fields_under_root: true
output.logstash:
hosts: ["localhost:5044"]
fields_under_root: true 是关键——否则字段在 fields.log_type 下,条件写法要相应改成 [fields][log_type]。
第二步:Logstash 按标记路由
input {
beats {
port => 5044
}
}
filter {
# 按类型做各自的解析
if [log_type] == "app1" {
grok { match => { "message" => "%{COMBINEDAPACHELOG}" } }
}
}
output {
if [log_type] == "app1" {
elasticsearch {
hosts => ["http://localhost:9200"]
ilm_enabled => false
data_stream => false
index => "app1-%{+yyyy.MM.dd}"
}
} else if [log_type] == "app2" {
elasticsearch {
hosts => ["http://localhost:9200"]
ilm_enabled => false
data_stream => false
index => "app2-%{+yyyy.MM.dd}"
}
} else {
elasticsearch {
hosts => ["http://localhost:9200"]
ilm_enabled => false
data_stream => false
index => "unknown-%{+yyyy.MM.dd}" # 兜底索引,暴露未打标的日志
}
}
}
兜底分支建议保留——忘记打标记的日志会流进 公开资料未说明-*,一眼就能发现配置遗漏。
Filebeat 直连 ES 的场景
不经过 Logstash 时,Filebeat 自己也能条件路由:
output.elasticsearch:
hosts: ["http://localhost:9200"]
index: "unknown-%{[agent.version]}-%{+yyyy.MM.dd}"
indices:
- index: "app1-%{[agent.version]}-%{+yyyy.MM.dd}"
when.equals:
log_type: app1
- index: "app2-%{[agent.version]}-%{+yyyy.MM.dd}"
when.equals:
log_type: app2
自定义 indices 会关闭 Filebeat 的 ILM 管理,而启用 ILM 时自定义单个 index 可能被忽略,两种路径不要混用。以上片段还需匹配的索引模板及保留策略;Filebeat 经 Logstash 时模板不会由该输出自动安装。生产环境须补充 TLS、凭据与最小权限,localhost 明文仅用于本地演示。
为什么要分索引
- 保留策略不同:应用日志留 30 天,审计日志留 1 年——分索引后 ILM 按索引模式分别管理
- 权限隔离:Kibana/ES 索引级权限按业务分派
- 查询性能:只扫需要的索引,避免全局搜索
- 爆炸半径:单个索引损坏/误删不影响其他日志
常见问题(FAQ)
Q:条件判断没生效,所有日志都进了一个索引?
A:按顺序查:fields_under_root: true 加没加;Logstash 里字段引用层级对不对(用 stdout { codec => rubydebug } 输出一条看实际结构);Filebeat 改配置后有没有重启。
Q:按天分索引(index => "app1-%{+yyyy.MM.dd}")有什么讲究?
A:这里的旧式 %{+...} 使用 Joda 格式,示例采用日历年 yyyy.MM.dd;不要与 Java Time 的 %{{...}} 格式混淆。按天命名本身不会自动删除索引,须另配匹配模板与生命周期/保留任务。低流量可考虑按月或 rollover 减少小分片。
Q:索引多了分片爆炸怎么办?
A:分片总数取决于每个索引的主分片数与副本数,模板可改变默认值;不能一律按索引数乘二。日志种类多但量小时,合并低频索引(如 app-others-*)、调大单索引容量、按周分索引,都是常用手段。
核查依据
本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。
- Elastic:elasticsearch output
- Elastic:plugins outputs elasticsearch
- Elastic:filebeat input filestream