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-*)、调大单索引容量、按周分索引,都是常用手段。

核查依据

本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。


延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台