ELK Stack 系列第 05 篇。前一篇 Kibana 可视化入门 已经说明如何在 Kibana 中验证日志、字段和仪表板;本文把视角前移到业务主机,建立从日志文件到 Elasticsearch 的轻量采集链路。

一、Filebeat 解决的不是“复制文件”,而是持续可靠地发布事件

在少量服务器上,管理员可以用 scp、定时脚本或共享目录集中日志。但当主机数量增加、日志持续轮转、网络偶尔中断、应用产生多行异常堆栈时,简单复制很快失效。真正的日志采集需要解决一组状态问题:

  • 哪些文件需要跟踪,哪些文件应排除。
  • 每个文件读到什么位置,进程重启后从哪里继续。
  • 文件重命名、删除和新建后,如何区分旧文件与新文件。
  • 一条业务事件跨多行时,如何在源端合并。
  • 输出端变慢或不可用时,采集端如何背压、缓存和恢复。
  • 数据成功交付后,什么时候提交读取偏移。
  • 如何添加主机、服务、环境和数据集元数据。
  • 如何在不暴露密码的前提下建立 TLS 与认证。
  • 如何证明日志没有因为配置错误、权限、时间戳或索引视图而“消失”。

Filebeat 是 Elastic Beats 家族中的轻量日志采集器。它通常部署在产生日志的主机或节点上,持续监视文件或其他受支持输入,把日志事件发送到 Elasticsearch、Logstash 或其他支持的输出。它不以复杂转换见长,优势在于资源占用低、状态持久化、背压处理、模块化配置以及与 Elastic Stack 的字段、模板、数据流和安全能力协同。

这篇文章以 Linux 文件日志为主,使用当前官方文档推荐的 filestream input 展开。旧资料中常见的 log input 和 container input 已进入迁移路径,不应继续作为新部署默认选择。现有环境升级前必须阅读对应版本迁移说明,验证 input 标识、registry 状态和文件身份策略,避免升级后重复采集或漏采。

二、Filebeat 的运行模型

这张图展示日志源、输入扫描、Harvester、Processors、队列、Registry 和两种输出路径之间的关系。理解这张图后,排障时就能判断问题发生在“没有发现文件”“没有读取新行”“队列没有发布”“输出没有确认”还是“数据已到但 Kibana 看不到”。

2.1 Input:定义要监视什么

Input 描述数据从哪里进入 Filebeat。对普通文件日志,本文使用 filestream。每个 filestream input 必须有唯一且稳定的 id,这个标识参与状态管理;复制配置时若多个 input 共用同一个 ID,或者随意修改 ID,都可能造成状态冲突或重新读取。

最小示例:

yaml
filebeat.inputs:
  - type: filestream
    id: app-json-prod
    enabled: true
    paths:
      - /var/log/myapp/*.log

paths 支持通配符,但通配范围越大,误采集、权限失败和扫描开销越难控制。生产环境应为不同日志契约建立独立 input,例如应用 JSON 日志、Java 多行日志、审计日志分别配置,避免一组解析规则误伤所有文件。

2.2 Scanner:发现候选文件

filestream 的 scanner 周期性检查配置路径,发现新文件、变化文件和轮转文件。它只负责发现,不等于已经开始读取。路径拼写、挂载点、符号链接、文件权限和排除规则都会影响候选集合。

当日志位于容器挂载、NFS 或其他网络文件系统时,需要额外谨慎。文件身份、inode 稳定性、挂载重连和轮转行为可能与本地文件系统不同。Filebeat 官方文档对网络卷和文件身份有专门警告;生产前应在真实轮转和重挂载场景中验证,而不是只做一次静态文件读取测试。

2.3 Harvester:逐行读取文件

每个活跃文件通常由一个 Harvester 负责打开并读取。Harvester 持有文件描述符,持续读取新增内容,把事件送入后续解析和队列。大量同时活跃的文件会消耗文件描述符和内存,因此需要根据日志数量、轮转频率和系统限制设置扫描、关闭和清理策略。

Harvester 不会因为文件名变化就简单地把它当成全新内容。Filebeat 使用文件身份识别文件,结合 Registry 中的读取状态决定从哪里继续。错误的轮转方式、跨文件系统移动或复制截断策略会破坏这种判断。

2.4 Processors 与 Parsers:轻量解析和元数据

Filebeat 可以在发送前进行轻量处理,例如:

  • JSON 解码。
  • 多行事件合并。
  • 添加、删除、重命名或转换字段。
  • 添加主机、云、容器、Kubernetes 等元数据。
  • 按条件丢弃事件或字段。
  • 使用 ingest pipeline 在 Elasticsearch 侧进一步解析。

应把“采集端必须完成的处理”和“集中处理更合适的逻辑”分开。多行合并必须尽量靠近源文件,否则异常堆栈在网络上传输前就已被拆散;服务名、环境和日志数据集等稳定元数据也适合在采集端添加。复杂的跨字段转换、外部查询、业务路由和敏感数据治理,通常更适合 Logstash 或 Elasticsearch ingest pipeline。

2.5 Queue:吸收突发并传递背压

事件进入输出前会经过内部队列。默认内存队列适合一般场景;对需要更强本地缓冲、允许磁盘换可靠性的场景,可以评估磁盘队列。队列不是无限仓库,输出持续不可用时最终仍会积压到容量上限,Filebeat 会降低读取速度并把背压传回 Harvester。

队列设计要回答三个问题:

  1. 目标端最长可能不可用多久。
  2. 这段时间每秒产生多少事件、平均事件多大。
  3. 本机能给采集缓冲多少内存或磁盘,磁盘占满会影响什么业务。

不能为了“不丢日志”把队列无限放大。日志磁盘和业务磁盘若共用分区,Filebeat 缓冲占满磁盘反而可能让应用停止。更合理的做法是独立分区、容量阈值、告警、保留分级和清晰的降级策略。

2.6 Output 与确认

Filebeat 常见输出是 Elasticsearch 或 Logstash。事件被输出端确认后,Filebeat 才能推进已确认状态并最终更新 Registry。这里的确认意味着采集管道接收成功,不等于业务字段一定正确,也不等于 Kibana 一定能查到;索引映射、时间字段、权限和 Data View 仍可能让数据不可见。

2.7 Registry:采集连续性的核心状态

Registry 保存文件身份、读取偏移和相关状态。Filebeat 重启后依靠它继续读取,避免每次从头开始。不要把 Registry 当作普通缓存随意删除。删除 Registry 常常会导致所有匹配文件从头重读,产生重复事件;在某些配置下也可能从文件尾开始,造成历史漏采。

确实需要重置状态时,应先停止 Filebeat、备份 Registry、明确目标文件和 ignore_older 等行为,并在隔离索引或测试输出中验证。生产事故中“删 registry 试试”通常会把一个采集问题变成数据重复与容量问题。

三、文件身份、轮转与 Registry

filestream 生命周期与日志轮转

这个流程展示了扫描、文件身份、Harvester、队列确认和 Registry 更新之间的关系,也说明 app.log 重命名为 app.log.1 后再新建 app.log 时,Filebeat 如何继续读完旧文件并跟踪新文件。

3.1 推荐轮转:重命名后新建

常见安全模式是:

  1. 应用正在写 app.log
  2. 轮转器把它重命名为 app.log.1
  3. 创建新的空 app.log
  4. 应用重新打开并写入新文件。
  5. Filebeat 继续读完旧文件,同时开始跟踪新文件。

配置路径应覆盖当前文件和需要继续读取的轮转文件,但要避免压缩归档被重复纳入:

yaml
filebeat.inputs:
  - type: filestream
    id: myapp-prod
    paths:
      - /var/log/myapp/app.log
      - /var/log/myapp/app.log.*
    prospector.scanner.exclude_files:
      - '\.gz$'

具体配置键随版本可能调整,部署前应以目标 Filebeat 版本的 filestream 参考页为准,并用 filebeat test config 验证。

3.2 谨慎使用 copytruncate

copytruncate 先复制当前文件,再把原文件截断为零。它保留原文件路径和身份,但复制与截断之间存在竞争窗口:应用可能继续写入,导致少量内容既没有进入副本,也被截断;Filebeat 也可能在偏移大于截断后文件大小时需要重新判断。对高价值日志,优先让应用支持重开文件或采用重命名轮转。

如果无法避免 copytruncate,必须通过高频写入压测和轮转测试评估重复与漏失风险,并把结果写入日志可靠性说明。不要只因为“logrotate 默认模板能工作”就假定它适合所有应用。

3.3 close 与 clean 参数

close.* 类设置控制 Harvester 何时关闭文件,clean.* 类设置控制 Registry 状态何时清理。设置太激进可能在文件仍会继续写时关闭或移除状态,设置太保守则会长期占用文件描述符和 Registry 空间。

设计时遵循:

  • 先理解应用轮转和延迟写入行为。
  • clean 清理时间必须晚于相关忽略和关闭条件。
  • 对偶尔才写一行的审计日志,不要按普通高频日志设置过短关闭时间。
  • 对大量短生命周期文件,避免 Registry 无限增长。
  • 每次修改都用轮转、重启、延迟写入和历史文件场景验证。

官方文档对这些参数之间的约束有明确说明,配置时不应凭名称猜测。

3.4 文件身份策略

本地 Linux 文件通常可以基于 inode 和 device 识别,但云盘、容器、网络卷、备份恢复和跨文件系统移动会改变身份。filestream 支持不同文件身份策略,选择取决于存储行为。默认策略并非在所有环境都安全。

验证方法不是观察一次正常采集,而是执行:

  1. 正常追加日志。
  2. 重命名轮转。
  3. 新建同名文件。
  4. Filebeat 重启。
  5. 主机重启。
  6. 文件跨目录或跨挂载移动。
  7. 网络卷断开再挂载。
  8. 归档恢复到原路径。

对比 Elasticsearch 中的业务唯一键、源文件标识和偏移相关元数据,确认没有重复和断点。

四、安装与版本策略

4.1 版本对齐原则

Filebeat、Logstash、Elasticsearch 和 Kibana 应遵循 Elastic 官方支持矩阵与升级顺序。最稳妥的做法是使用同一主版本,并在升级前检查 Beats breaking changes。不要把某篇旧教程中的 8.x 仓库地址或配置直接用于 9.x 环境,也不要假设跨主版本输出永远兼容。

本文不固定某个补丁版本。2026-06-11 的实施应从 Elastic 官方下载或软件仓库页面确认当前稳定版本、仓库地址、签名密钥和支持平台,再把实际版本写入变更单。

4.2 Debian/Ubuntu 软件包安装

以下流程展示安装结构,仓库主版本占位符必须替换为目标版本:

bash
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch \
  | sudo gpg --dearmor -o /usr/share/keyrings/elastic-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/elastic-keyring.gpg] https://artifacts.elastic.co/packages/MAJOR.x/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/elastic-MAJOR.x.list

sudo apt update
sudo apt install filebeat

安装后先不要立即大范围启用。确认文件位置:

bash
filebeat version
sudo filebeat export config | less
sudo systemctl status filebeat --no-pager

常见路径:

text
主配置:/etc/filebeat/filebeat.yml
扩展配置:/etc/filebeat/conf.d/ 或项目约定目录
数据目录:/var/lib/filebeat
日志目录:/var/log/filebeat
服务单元:filebeat.service

实际路径受安装方式和版本影响,应以服务参数与 path.* 配置为准。

4.3 RPM、容器与 Kubernetes

RPM 包适用于 RHEL 系发行版,安装后同样通过 systemd 管理。容器化运行需要把日志目录、配置、证书和数据目录挂载进容器,尤其要持久化 Filebeat 数据目录,否则容器重建可能丢失 Registry 状态。

Kubernetes 场景通常以 DaemonSet 在每个节点运行采集器,读取容器日志并添加 Kubernetes 元数据。此时需要特别关注:

  • 容器运行时日志路径。
  • Pod/容器 ID 与日志轮转。
  • 节点磁盘压力。
  • RBAC 权限。
  • 元数据 API 压力。
  • 多租户数据隔离。
  • 与 Elastic Agent/Fleet 的方案边界。

本文不展开 Kubernetes 清单,部署时应优先参考当前官方 Kubernetes 与 Filebeat 文档。

五、建立日志契约

安装采集器之前,先定义日志契约。没有契约,采集端只能不断猜测格式。

建议至少确定:

项目 约定
文件路径 稳定目录,不使用临时目录
文件编码 UTF-8
事件边界 单行 JSON,或明确多行起始规则
时间字段 ISO 8601,含时区
服务字段 service.nameservice.versionservice.environment
日志级别 统一枚举
关联字段 trace.idtransaction.id、业务请求 ID
错误字段 error.typeerror.message、堆栈
敏感数据 禁止记录密码、令牌、完整身份证号等
轮转策略 重命名新建、保留周期、压缩时点
权限 Filebeat 用户可读,其他用户最小化
保留责任 本机短期保留,集中平台长期保留

单行 JSON 是最容易稳定解析的格式。示例:

json
{"@timestamp":"2026-06-11T14:30:00+08:00","log.level":"ERROR","service.name":"order-api","service.environment":"prod","trace.id":"abc123","message":"database timeout","error.type":"TimeoutException"}

不要把 JSON 嵌在一段前缀文本后面,也不要同一个文件同时混用 JSON 与纯文本。日志契约一旦变化,应通过版本字段、独立路径或灰度 input 管理,避免集中平台突然出现字段类型冲突。

六、filestream 配置实战

6.1 单行 JSON 日志

yaml
filebeat.inputs:
  - type: filestream
    id: order-api-json-prod
    enabled: true
    paths:
      - /var/log/order-api/*.json

    parsers:
      - ndjson:
          target: ""
          add_error_key: true
          message_key: message

    fields_under_root: true
    fields:
      service.name: order-api
      service.environment: prod
      event.dataset: order-api.application

    prospector.scanner.exclude_files:
      - '\.gz$'
      - '\.tmp$'

ndjson 适用于每行一个 JSON 对象。target: "" 表示把解码字段放到事件根部,但必须防止应用字段覆盖采集器关键字段。更保守的方式是放到子对象,再由 processor 或 ingest pipeline 显式映射。配置键和覆盖行为要在目标版本上验证。

6.2 Java 多行堆栈

多行日志的目标是把异常首行和后续堆栈合并为一个事件。一个常见思路是:以时间戳开头的行作为新事件,其余行并入前一事件。

yaml
filebeat.inputs:
  - type: filestream
    id: payment-java-prod
    paths:
      - /var/log/payment/application.log

    parsers:
      - multiline:
          type: pattern
          pattern: '^:space:*[0-9]{4}-[0-9]{2}-[0-9]{2}'
          negate: true
          match: after

    fields_under_root: true
    fields:
      service.name: payment
      service.environment: prod
      event.dataset: payment.application

多行规则必须用真实样本验证。常见错误包括:

  • 首行并不总以时间戳开始。
  • 应用启动横幅被合并成超大事件。
  • 两种日志格式混在一个文件。
  • 异常堆栈超过默认最大行数或超时。
  • 正则过于宽泛,正常日志被错误合并。

可以准备包含普通日志、嵌套异常、并发线程和超长堆栈的测试文件,在隔离环境观察输出事件数量与边界。不要直接在生产主机上边改正则边重启。

6.3 排除噪声文件和事件

文件级排除适合压缩包、临时文件和明确不需要的日志;事件级丢弃适合健康检查等低价值事件。

yaml
processors:
  - drop_event:
      when:
        and:
          - equals:
              http.request.method: GET
          - equals:
              url.path: /health

丢弃策略要有业务确认和采样证据。健康检查日志可能在网络故障和负载均衡异常时非常有价值,完全丢弃会降低可观测性。更稳妥的做法可能是降低采样比例、缩短保留期或进入低成本数据集。

6.4 添加标准元数据

yaml
processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - add_fields:
      target: labels
      fields:
        owner: platform
        region: cn-east
        criticality: high

元数据应尽量符合 Elastic Common Schema(ECS),避免自造大量同义字段。例如主机名使用 host.name,服务使用 service.name,环境使用 service.environment,数据集使用 event.dataset。自定义字段放入明确命名空间,如 labels.* 或企业自定义对象。

标签不能替代资产治理。主机责任人、环境和重要性最好从部署系统、CMDB 或编排变量注入,而不是每台机器手工填写,否则很快漂移。

七、两种输出架构

7.1 直写 Elasticsearch

适合日志格式较规范、Filebeat processors 或 Elasticsearch ingest pipeline 足以处理、希望减少中间层的场景。

yaml
output.elasticsearch:
  hosts:
    - "https://es01.example.com:9200"
    - "https://es02.example.com:9200"
  username: "${ES_USER}"
  password: "${ES_PASSWORD}"
  ssl.certificate_authorities:
    - /etc/filebeat/certs/ca.crt

不要把密码明文提交到配置仓库。Filebeat keystore 可以保存敏感值:

bash
sudo filebeat keystore create
sudo filebeat keystore add ES_USER
sudo filebeat keystore add ES_PASSWORD
sudo filebeat keystore list

直写路径优点是组件少、延迟低、运维简单;缺点是复杂转换和多目标路由能力有限,采集端配置可能变重。若使用官方 module,通常还需要在具备权限的环境执行 setup,以加载索引模板、ingest pipeline 和 Kibana 资产。生产主机的运行账号不应长期拥有 setup 所需高权限。

7.2 经 Logstash 输出

适合复杂解析、跨数据源丰富、集中脱敏、条件路由、多目标输出或希望把处理逻辑集中管理的场景。

Filebeat:

yaml
output.logstash:
  hosts:
    - "ls01.example.com:5044"
    - "ls02.example.com:5044"
  loadbalance: true
  ssl.enabled: true
  ssl.certificate_authorities:
    - /etc/filebeat/certs/logstash-ca.crt

Logstash input:

ruby
input {
  beats {
    port => 5044
    ssl_enabled => true
    ssl_certificate_authorities => ["/etc/logstash/certs/ca.crt"]
    ssl_certificate => "/etc/logstash/certs/server.crt"
    ssl_key => "/etc/logstash/certs/server.pkcs8.key"
    ssl_client_authentication => "optional"
  }
}

插件参数会随版本演进,特别是旧文档中的 TLS 参数名称可能已弃用。上线前应针对安装的 Logstash beats input 插件版本查阅官方参考并运行配置测试。

经 Logstash 时,Filebeat 的模板和 ingest pipeline 不会自动通过 Logstash 加载。需要单独规划 setup:由受控管理主机连接 Elasticsearch/Kibana 执行,或通过基础设施代码管理模板、数据流、生命周期策略和仪表板。

7.3 如何选择

条件 直写 Elasticsearch 经 Logstash
格式 已结构化、规则简单 多格式、复杂解析
路由 单目标或简单数据集 多目标、条件路由
脱敏 简单字段处理 复杂集中治理
延迟 更低 多一跳
运维 组件少 需要 Logstash 集群
处理弹性 ingest pipeline Logstash worker/PQ
故障域 ES 故障直接背压采集端 Logstash 可提供额外缓冲

不要为了“架构完整”强行加入 Logstash,也不要为了少维护一个组件把复杂业务规则分散到数百台 Filebeat。选择依据是日志契约、处理复杂度、组织责任和可靠性需求。

八、数据流、模板与索引策略

Elastic 的现代日志方案大量使用 data stream。数据流适合持续追加的时序数据,背后由多个 backing index 管理,并与索引模板和生命周期策略协同。使用 Filebeat module 或 Elastic 集成时,命名、模板和 ingest pipeline 可能自动按约定建立;自定义日志则需要明确数据流命名与字段映射。

8.1 为什么不要每天手工拼索引名

旧教程常配置:

yaml
index: "app-logs-%{+yyyy.MM.dd}"

这种方式直观,但会带来大量小索引、模板漂移、生命周期管理困难和分片浪费。新设计应优先评估 data stream 与生命周期策略,按数据集、命名空间和类型组织日志。例如:

text
logs-order_api.application-prod

实际命名必须遵循 Elastic 数据流规则和企业规范。

8.2 字段映射冲突

同一字段今天是数字、明天变成字符串,会导致写入失败或查询异常。常见冲突:

  • http.response.status_code 有时写 200,有时写 "OK"
  • event.duration 有的服务使用毫秒,有的使用纳秒。
  • host 旧日志是字符串,新 ECS 中是对象。
  • user 既被当用户名字符串,又被当对象。

预防方式:

  1. 建立日志契约和 ECS 映射。
  2. 在测试数据流验证模板。
  3. 使用版本化 pipeline。
  4. 对无法修复的旧格式隔离数据集。
  5. 监控 Filebeat、Logstash 和 Elasticsearch 的拒写与解析错误。

8.3 setup 与运行权限分离

Filebeat setup 可能需要创建模板、生命周期策略、ingest pipeline、Data View 和 Dashboard。日常采集账号只需要写入目标数据流或索引,以及必要的监控权限。把二者分离可以降低主机凭证泄露后的影响。

建议:

  • 管理流水线使用短期高权限凭证执行 setup。
  • 生产 Filebeat 使用最小权限 API key 或专用账号。
  • 不同环境、业务域或租户使用独立权限边界。
  • 定期轮换凭证并监控认证失败。

九、生产部署与验证流程

生产环境 Filebeat 部署与验证

这条交付链把日志契约、安装、配置、解析、元数据、TLS、测试、灰度、Kibana 验证和持续监控放在同一个流程里,同时强调密钥、版本控制和回滚三条护栏。任何一步失败都应停止扩大发布范围。

9.1 配置静态检查

bash
sudo filebeat test config -e

这一步检查 YAML 和配置结构,但不能证明文件存在、权限正确、正则边界合理或输出一定可用。

9.2 输出连通性

bash
sudo filebeat test output -e

它用于检查 DNS、网络、TLS 和认证。失败时需要区分:

  • DNS 无法解析。
  • 防火墙或路由阻断。
  • 端口不监听。
  • CA 不受信。
  • 证书主机名不匹配或已过期。
  • 用户名、密码或 API key 错误。
  • Logstash TLS 参数或客户端认证不匹配。

不要用关闭证书验证作为长期修复。测试环境临时绕过也必须在上线前恢复完整校验。

9.3 前台调试

在测试主机上停止服务后,可以前台运行并启用选择性 debug:

bash
sudo systemctl stop filebeat
sudo filebeat -e -d "input,harvester,publisher"

debug 日志量很大,应限定时间和组件。不要长期在生产开启全量 * debug,否则 Filebeat 自身日志可能造成磁盘压力并掩盖真正问题。

9.4 预览输出

如果使用直写 Elasticsearch,可以在隔离环境临时输出到 console 检查事件结构;也可以让 Logstash 临时加 stdout { codec => rubydebug }。生产数据可能包含敏感信息,调试输出必须受控并及时删除。

需要确认:

  • 一条源日志对应几个事件。
  • @timestamp 是否来自业务时间,时区是否正确。
  • 多行堆栈是否完整。
  • 服务、环境、主机和数据集字段是否存在。
  • 敏感字段是否被正确处理。
  • JSON 解码失败是否产生错误标记。

9.5 灰度上线

先选一台非关键或代表性主机:

  1. 记录源文件大小和当前增长速率。
  2. 启动 Filebeat。
  3. 观察 CPU、内存、文件描述符和磁盘。
  4. 检查 Filebeat 日志中的 publish、harvester 和 output 错误。
  5. 在 Elasticsearch 查看文档增长。
  6. 在 Kibana 检查时间、字段和重复。
  7. 执行一次日志轮转。
  8. 重启 Filebeat,确认从正确偏移继续。
  9. 模拟短时断网,确认积压与恢复。
  10. 通过后再逐批扩展。

9.6 回滚

回滚配置不等于删除 Registry。安全回滚通常是:

  • 停止新配置或恢复上一版本配置。
  • 保留数据目录和 Registry。
  • 确认旧配置中的 input ID 与路径是否一致。
  • 若切换输出,确认队列中事件的处理策略。
  • 在隔离数据流检查是否重复。
  • 记录切换时间,便于后续对账。

只有在明确需要重采历史且已经规划去重、容量和隔离目标时,才重置状态。

十、可靠性、背压与“至少一次”

Filebeat 的交付模型应按至少一次理解:在输出确认边界、网络中断或进程崩溃等情况下,系统优先避免静默丢失,但可能产生重复。下游必须具备处理重复的意识。

10.1 重复从哪里来

  • 事件已被 Elasticsearch 接收,但确认未返回,Filebeat 重试。
  • Logstash 接收后重启,持久化队列和上游重试边界重叠。
  • Registry 被删除或损坏。
  • input ID 或文件身份策略变化。
  • 归档文件被复制回匹配路径。
  • 多个 Filebeat 实例同时读取同一文件。

可以用业务唯一键或 fingerprint 构造稳定文档 ID,实现一定程度去重,但这会增加处理复杂度,也不是所有日志都有天然唯一键。更重要的是防止无计划重置状态,并监控重复率。

10.2 背压的表现

当 Elasticsearch 或 Logstash 变慢时:

  • 输出重试增加。
  • 内部队列占用上升。
  • Harvester 读取速度下降。
  • 源日志文件继续增长。
  • 本机日志保留和磁盘压力加大。
  • Kibana 中数据延迟增加。

排障时不能只重启 Filebeat。重启可能短暂清空连接状态,但目标端不恢复,积压仍会回来。应沿输出端、网络、TLS、队列、磁盘和源文件增长一起判断。

10.3 磁盘队列设计

评估磁盘队列时需要:

  • 独立目录或分区。
  • 容量和最大使用率告警。
  • 写入延迟和磁盘寿命评估。
  • 异常关机恢复测试。
  • 与业务日志分区隔离。
  • 输出恢复后的追赶速度验证。

如果日志产生速度长期高于输出处理速度,再大的队列也只是推迟失败。容量治理必须同时调整输出集群、批量、处理规则、日志量和保留策略。

十一、安全基线

11.1 最小权限

Filebeat 进程只需要读取目标日志和访问必要证书、keystore、数据目录。不要用 root 运行来掩盖权限设计问题。软件包服务可能以专用用户运行;需要读取的日志可以通过用户组、ACL 或日志目录权限授权。

示例思路:

bash
sudo setfacl -m u:filebeat:rX /var/log/myapp
sudo setfacl -m d:u:filebeat:rX /var/log/myapp

是否使用 ACL 取决于组织规范。还要验证新轮转文件继承正确权限,否则上线当天正常,第一次轮转后采集停止。

11.2 TLS 与证书

Filebeat 到 Logstash 或 Elasticsearch 的链路应启用 TLS,并验证 CA、主机名和有效期。私钥只授予必要进程读取。证书轮换需要演练,避免到期当天批量采集失败。

监控至少包括:

  • 证书剩余有效期。
  • TLS 握手失败。
  • 认证失败。
  • 被拒绝的索引写入。
  • API key 或用户轮换结果。

11.3 敏感信息

最好的脱敏位置是应用产生日志之前。采集端正则脱敏容易漏掉格式变化,也会消耗 CPU。若必须在 Filebeat 或 Logstash 处理,应建立测试样本、规则版本和误删评估。

Filebeat 自身日志也可能打印目标地址、证书路径和错误上下文。调试级别日志应按敏感数据处理,限制访问与保留。

11.4 配置治理

配置文件进入版本控制,但秘密不进入版本控制。每次变更应包含:

  • 变更原因。
  • 目标主机或主机组。
  • input ID、路径和解析变化。
  • 预期新增字段或数据集。
  • 测试证据。
  • 灰度批次。
  • 回滚版本。
  • 是否影响 Registry 与重复风险。

自动化分发应使用原子替换和配置测试,避免写到一半被服务读取。大规模环境可评估 Fleet/Elastic Agent,但这属于采集治理模式的变化,需单独规划,不应在 Filebeat 故障时临时切换。

十二、监控 Filebeat 本身

日志采集器是可观测性链路的一部分,也必须被监控。建议建立端到端指标:

层级 指标
源文件 文件增长、最后写入时间、磁盘使用率
Input 活跃 input、发现文件数、扫描错误
Harvester 活跃数量、启动/关闭、读取字节与事件
Parser JSON/多行错误、被丢弃事件
Queue 入队、出队、占用、阻塞
Output 成功、失败、重试、延迟、批量大小
Registry 状态数量、偏移推进、数据目录容量
目标端 接收率、拒写、pipeline 错误、索引延迟
业务端 源事件数与目标文档数对账

仅监控 Filebeat 进程存活远远不够。进程可以正常运行,但路径不匹配、权限失效、输出认证失败或时间戳错误。真正有效的 SLI 是“源日志产生后,在目标数据流中按约定时间可查询”。

可以为每个关键服务周期性写入一条可识别的采集探针日志,在 Elasticsearch 侧检查到达延迟。探针不能包含敏感内容,并应与业务日志清晰区分。

十三、故障排查 runbook

Filebeat 日志未到达排障

这张图按源文件、服务、路径、Harvester/Registry、队列、输出、目标端和 Kibana 的顺序逐层检查。顺序很重要:先证明上游有数据,再证明采集状态推进,最后处理展示问题,避免在错误层级反复修改。

13.1 第一步:源文件是否真的增长

bash
sudo stat /var/log/myapp/app.log
sudo tail -n 20 /var/log/myapp/app.log
sudo lsof /var/log/myapp/app.log

确认应用写的是你认为的文件。容器、软链接、日志框架和轮转配置可能让实际路径不同。检查时间戳、文件大小和打开进程,不要只看文件存在。

13.2 第二步:服务是否运行

bash
sudo systemctl status filebeat --no-pager
sudo journalctl -u filebeat -n 100 --no-pager

关注启动失败、配置错误、权限、重复 ID、证书和输出重试。服务“active”不代表采集正常,要继续检查 Harvester 和输出。

13.3 第三步:路径和权限

bash
sudo -u filebeat test -r /var/log/myapp/app.log
sudo namei -l /var/log/myapp/app.log

目录链上的每一级都需要可遍历权限。新轮转文件可能拥有不同用户组或权限。若使用符号链接,确认目标路径和版本配置对符号链接的处理。

13.4 第四步:Harvester 与 Registry 是否推进

临时开启相关 debug:

bash
sudo filebeat -e -d "input,harvester,registrar"

检查是否发现目标文件、是否启动 Harvester、是否读取新增行、是否提交状态。Registry 的内部格式属于实现细节,不应依赖手工编辑;可以备份后只读检查,但不要在运行中修改。

若文件增长而偏移不动,常见原因包括权限、编码、行尾、超大单行、关闭条件、文件身份误判或队列背压。

13.5 第五步:队列是否阻塞

检查 Filebeat 日志中的 publish、queue、blocked、retry 等信息,并同时看磁盘和目标端。磁盘队列满时,清理业务不相关文件或扩容只能缓解,根因仍可能是 Logstash/Elasticsearch 不可用或处理能力不足。

13.6 第六步:输出测试

bash
sudo filebeat test output -e

若失败,按 DNS、TCP、TLS、认证、权限逐层检查。可以使用 openssl s_client 辅助查看证书链,但不要把跳过校验当修复。

13.7 第七步:Logstash 或 Elasticsearch 是否接收

经 Logstash 时检查 beats input 监听、pipeline 状态、持久化队列、filter 错误和 Elasticsearch output。直写时检查 Elasticsearch 认证、索引权限、数据流、模板和拒写。

bash
sudo ss -lntp | grep 5044
sudo journalctl -u logstash -n 100 --no-pager
curl -s http://127.0.0.1:9600/_node/stats/pipelines?pretty

Elasticsearch 可使用目标环境允许的认证方式检查数据流和最近文档。不要在共享终端历史中直接写密码。

13.8 第八步:数据已到但 Kibana 看不到

检查:

  • Kibana 时间范围是否覆盖事件时间。
  • @timestamp 是否解析为正确时区。
  • Data View 是否匹配目标数据流或索引。
  • 当前用户是否有读取权限。
  • 查询过滤器是否残留。
  • 文档是否因 ingest pipeline 改写到其他数据集。
  • 字段映射是否冲突。

直接通过 Elasticsearch 查询最近文档,可以区分采集问题与展示问题。若 Elasticsearch 有数据而 Kibana 无数据,不要重启 Filebeat。

十四、典型事故复盘

14.1 第一次轮转后停止采集

现象: 上线数小时正常,凌晨轮转后 Kibana 无新日志。

证据: Filebeat 进程正常,新 app.log 权限变为仅应用用户可读,Filebeat 用户无权限。

修复: 调整 logrotate 的 create 用户组和权限,或用 ACL 保证新文件继承可读权限;执行轮转测试。

预防: 上线验收必须包含一次真实轮转,不能只追加测试行。

14.2 删除 Registry 后数据暴增

现象: 为解决“日志不更新”删除数据目录,随后 Elasticsearch 写入量和存储激增。

证据: 历史轮转文件仍匹配 paths,Filebeat 从头读取。

修复: 停止 Filebeat,隔离重复流量,恢复 Registry 备份或调整历史文件匹配;评估使用稳定 ID 去重。

预防: 将 Registry 重置列为高风险操作,必须备份、审批和指定隔离目标。

14.3 Java 堆栈被拆成数百条

现象: Kibana 中一条异常变成大量 at ... 单行,告警数量暴增。

证据: 多行规则仍使用旧 log input 写法,迁移到 filestream 后 parser 层级不正确。

修复: 按当前 filestream parser 语法配置并用样本验证;新数据进入版本化数据集。

预防: 版本升级时对多行、JSON 和时间戳做契约测试。

14.4 Filebeat 正常但延迟越来越大

现象: Filebeat 无明显错误,日志可以到达,但延迟从秒级增加到小时级。

证据: Logstash filter CPU 饱和,持久化队列持续增长;Filebeat 输出重试和批次耗时增加。

修复: 优化 filter、增加处理能力、拆分管道或降低无价值日志;验证追赶速度。

预防: 监控端到端到达延迟和队列斜率,而不是只看失败数。

14.5 所有日志时间都晚八小时或早八小时

现象: Elasticsearch 有文档,但 Kibana 当前时间范围看不到。

证据: 应用时间没有时区,解析器按 UTC 或本地时区错误解释。

修复: 从应用侧输出带时区 ISO 8601;过渡期在 ingest pipeline/Logstash 明确时区并记录来源。

预防: 日志契约强制时间字段含时区,测试跨日和夏令时场景。

十五、生产验收清单

配置与版本

  • [ ] Filebeat 与 Elastic Stack 版本符合官方支持矩阵。
  • [ ] 新部署使用 filestream,每个 input 有唯一稳定 ID。
  • [ ] 配置通过 filebeat test config
  • [ ] 输出通过 filebeat test output
  • [ ] 旧 input 迁移已评估 Registry 与重复风险。

日志契约

  • [ ] 文件路径、编码、时间戳和轮转策略明确。
  • [ ] JSON 或多行规则使用真实样本验证。
  • [ ] ECS 字段、服务、环境和数据集命名统一。
  • [ ] 敏感信息策略经过安全评审。

可靠性

  • [ ] Filebeat 重启后从正确偏移继续。
  • [ ] 日志轮转不重复、不漏采。
  • [ ] 短时断网后能够恢复并追赶。
  • [ ] 队列容量、磁盘阈值和告警明确。
  • [ ] Registry 重置有受控流程。

安全

  • [ ] 进程使用最小文件读取权限。
  • [ ] TLS 完整验证,证书轮换可执行。
  • [ ] 密钥存入 keystore 或外部秘密系统。
  • [ ] setup 权限与运行写入权限分离。
  • [ ] 配置和调试日志不泄露秘密。

数据质量

  • [ ] Elasticsearch 中目标数据流或索引存在。
  • [ ] @timestamp 和时区正确。
  • [ ] 关键字段类型符合模板。
  • [ ] Kibana Data View 可查到数据。
  • [ ] 源事件量与目标文档量抽样对账。

运维

  • [ ] 监控 Harvester、队列、输出、延迟和磁盘。
  • [ ] 关键服务有端到端采集探针。
  • [ ] 变更采用灰度、版本控制和回滚。
  • [ ] Runbook 能区分采集、处理、存储与展示问题。
  • [ ] 负责人、升级窗口和容量评审周期明确。

十六、总结

Filebeat 的价值不只是轻量。它把文件发现、持续读取、偏移持久化、轮转识别、事件处理、队列背压和输出确认组织成一个可恢复的采集状态机。掌握 Filebeat,关键不是记住更多 YAML,而是理解每个状态发生在哪里、由什么证据证明、失败后如何恢复。

生产落地应坚持几条原则:

  1. 新部署优先使用 filestream,并为每个 input 设置稳定唯一 ID。
  2. 在采集前建立日志契约,优先单行 JSON、明确时区和 ECS 字段。
  3. 多行合并靠近源端,复杂转换集中到 Logstash 或 ingest pipeline。
  4. Registry 是连续性状态,不是可以随意删除的缓存。
  5. 日志轮转、重启、断网和目标端背压必须进入上线测试。
  6. 直写与经 Logstash 没有绝对优劣,应按处理复杂度和组织责任选择。
  7. setup 高权限与日常写入权限分离,链路启用 TLS,秘密不写明文。
  8. 监控端到端到达延迟,而不是只监控 Filebeat 进程。

完成本篇后,这一组 ELK 入门链路已经闭合:Elasticsearch 提供存储和查询底座,Logstash 负责中心化解析与治理,Kibana 负责验证和可视化,Filebeat 把采集责任前移到业务主机。后续如果继续扩展生产环境架构、容量、生命周期和高可用,需要在这条链路稳定运行的基础上推进,而不是跳过采集与字段质量直接堆集群规模。

参考资料

  1. Elastic, Filebeat Reference,访问日期:2026-06-11。
  2. Elastic, Configure inputs,访问日期:2026-06-11。
  3. Elastic, filestream input,访问日期:2026-06-11。
  4. Elastic, Configure the Elasticsearch output,访问日期:2026-06-11。
  5. Elastic, Configure the Logstash output,访问日期:2026-06-11。
  6. Elastic, Multiline messages,访问日期:2026-06-11。
  7. Elastic, Filebeat and systemd,访问日期:2026-06-11。
  8. Elastic, Filebeat keystore,访问日期:2026-06-11。