上一篇把 Logstash 和 Fluentd、Vector 放在一起横向对比。这一篇转向纵向:Logstash 自 2009 年诞生以来历经哪些关键演进,Elastic Agent 和 OpenTelemetry Collector 的出现又如何重新划定了它的边界。

核心问题:持久队列、DLQ、pipeline-to-pipeline 一路补齐的是什么——当 Elastic Agent 分走了边缘采集场景、OTel 提供了厂商中立的替代方案,Logstash 今天的定位是什么。

本篇的版本坐标截至 2026-08:Logstash 的最新发布版本是 9.5.2,8.19 分支仍在维护。下面时间线里每一行的版本归属,取自官方 release notes 的原文,或该功能文档在各发布分支上的首次出现;发布日期取自对应 tag 的提交时间。全系列统一的版本前提见第 01 篇。

演进时间线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
版本   发布      关键变化
────────────────────────────────────────────────────────────────────────
1.x 2009 诞生,Ruby 实现,内存队列,单管道
2.x 2014 性能改进,引入 pipeline worker 概念
5.1 2016-12 持久队列(PQ)引入,文档带 beta 警告
5.4 2017-04 PQ 转 GA(release notes:"generally available (GA) now")
5.5 2017-06 死信队列(DLQ)
6.0 2017-11 多管道配置(pipelines.yml)
6.1 2017-12 Java 执行引擎首次可用,需 --experimental-java-execution 开启
6.3 2018-06 pipeline-to-pipeline(P2P)引入,文档标题带 Beta
6.5 2018-11 Java 执行引擎从 experimental 转 beta
7.0 2019-04 Java 执行引擎成为默认引擎
7.4 2019-09 P2P 转 GA(文档标题去掉 Beta)
8.0 2022-01 移除 Ruby 执行引擎(breaking change:Ruby Execution Engine removed)
8.5 2022-10 flow metrics 进入 Node Stats API
9.2 2025-10 PQ 支持 ZSTD 压缩(queue.compression)
9.4 2026-04 管道崩溃自动恢复(pipeline.recovery)、batch 分块、batch 直方图指标
9.5 2026-07 通过 OTLP 导出内部运行指标(技术预览)

每个版本的变化都在解决一个具体的可靠性或运维痛点,而不是纯粹的功能堆砌。值得注意的是几处常被记错的边界:PQ 的引入与转正差了三个小版本,DLQ 比多管道更早,Java 执行引擎从可用到成为默认跨了三年、到彻底移除 Ruby 引擎又是三年。

各阶段解决了什么

1.x–2.x:能用,但脆

内存队列意味着进程崩溃丢数据;单管道意味着所有 input/filter/output 共享同一条链,互相影响;Ruby 实现使得性能上限低,大流量下 GC 停顿明显。这个阶段的 Logstash 适合原型和小流量场景,不适合生产级别的高可靠需求。

5.x:两条兜底路径落地

PQ 把队列从内存移到磁盘,引入检查点机制,崩溃重启后从检查点恢复,把可靠性从"尽力而为"提升到 at-least-once(在源可重放的前提下)。它在 5.1 带着 beta 警告进来,5.4 才转正,这三个小版本的间隔说明落盘队列的正确性不是一次就做对的。紧接着 5.5 的 DLQ 补上另一条路径:解析失败的事件不再直接丢弃或让整条管道卡住,而是写入独立的死信队列文件,允许事后检查和重放修复。这两件事一起把 Logstash 从"玩具"推到了"可信赖生产组件"。

6.x–7.x:结构解耦与执行引擎换代

6.0 的 pipelines.yml 让不同数据流能隔离运行,解决了大型部署里"一个慢 pipeline 拖死全局"的问题。6.3 引入的 pipeline-to-pipeline 让多个逻辑管道可以用 pipeline input/output 互相传递事件、形成有向图,不必每条管道都独立从源读到目标写;它同样走了一段 beta,7.4 才转 GA。同期 Java 执行引擎分三步换代:6.1 需要命令行开关才能试用,6.5 转 beta,7.0 成为默认。这一步把 filter 和 output 的执行从 JRuby 解释器切换到 Java 原生实现。

8.x–9.x:清掉历史包袱,补上可观测性

8.0 移除了 Ruby 执行引擎,核心执行路径上不再有两套实现并存——这是 7.0 换默认三年之后的收尾动作,而不是换默认本身。8.5 起 flow metrics 进入 Node Stats API,把每秒事件数、队列增长速率这类运行时速率做成了现成字段,不必再自己对累计值做差,这是第 13 篇判读主线的由来。9.x 继续在边角收紧:9.2 给 PQ 加上 ZSTD 压缩,9.4 补了管道崩溃自动恢复与 batch 直方图指标,9.5 让 Logstash 能把自己的运行指标通过 OTLP 导出。

Elastic Agent 的出现

Elastic Agent 是 Elastic 在 7.9 版本引入、8.x 版本全面推广的新一代统一代理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Elastic Agent 架构
┌──────────────────────────────────────────────────────┐
│ Elastic Agent │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ │
│ │ Beats │ │ Elastic │ │Security │ │APM │ │
│ │ inputs │ │ Defend │ │module │ │agent │ │
│ └─────────┘ └─────────┘ └─────────┘ └────────┘ │
│ │
│ 由 Fleet(集中管理平台)统一下发配置、升级、监控 │
└──────────────────────────────────────────────────────┘


Elasticsearch(直接写入)
+ Ingest Pipeline(轻量变换)

Elastic Agent 把 Filebeat、Metricbeat、Auditbeat、Elastic Endpoint 等多个 Beats 合并到单一进程里,由 Fleet 服务器统一管理配置和升级。对运维人员而言,不再需要在每台机器上分别配置和维护多个 Beats 进程;对开发人员而言,集成模块(integration)提供了预打包的字段映射、Ingest Pipeline 和 Kibana 仪表板,开箱即用。

Elastic Agent 直连 ES + Ingest Pipeline,绕过了 Logstash 在边缘采集和简单解析场景中的位置。

Elastic Agent 带走了什么

Elastic Agent 把以下场景从 Logstash 典型用例中分走:

1
2
3
4
5
6
7
场景                          Elastic Agent 之前    Elastic Agent 之后
──────────────────────────────────────────────────────────────────
每台机器部署日志采集 Filebeat → Logstash Elastic Agent → ES
Kubernetes 日志采集 Filebeat DaemonSet Elastic Agent DaemonSet
预打包的 Nginx/Apache 解析 Logstash + 配置 Elastic Agent integration
指标采集(CPU/内存/磁盘) Metricbeat + 配置 Elastic Agent(内置)
安全事件采集 Auditbeat + 配置 Elastic Agent + Defend

简单来说:当目的地是 Elasticsearch、变换逻辑不超过 Ingest Pipeline 能力范围、且不需要写多个目标时,Elastic Agent 提供了比 Beats → Logstash → ES 更低的运维复杂度。

Logstash 保留了什么

Elastic Agent 冲击之后,Logstash 的核心价值集中在三类场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
场景一:复杂多目标路由
Logstash 可以同时写 ES + Kafka + S3 + 文件,
Elastic Agent 只能写 Elastic 生态目标。

场景二:非 Elastic 数据源的重量级处理
JDBC input(从数据库定时拉取)
Kafka input + 复杂 Grok 解析 + 多 ES 集群路由
遗留系统的 TCP/UDP syslog 接入 + 归一化
这些场景没有 Elastic Agent integration 可用。

场景三:PQ 兜底的高可靠场景
数据源不可重放(UDP、某些遗留推送协议)
需要在 ES 集群临时不可用期间缓冲数据
Elastic Agent 没有 PQ 等价物。

一条简洁的判断规则:如果数据源、变换逻辑、目标都在 Elastic 生态内,且变换不超过 Ingest Pipeline 能力,用 Elastic Agent;只要有一项超出,就需要评估是否引入 Logstash。

OpenTelemetry Collector 的角色

OpenTelemetry(OTel)是 CNCF 的可观测性标准,OTel Collector 是其数据采集和转发组件:

1
2
3
OTel Collector 架构
receiver ──▶ processor ──▶ exporter
(otlp, jaeger, prometheus, …) (otlp, elasticsearch, kafka, …)

OTel Collector 与 Logstash 的定位有重叠:都能接收多种数据源、做变换、发往多种目标。区别在于:OTel Collector 的设计中心是厂商中立的可观测性数据(traces、metrics、logs),其 processor 能力(transformation、filtering)目前比 Logstash 的 filter 生态弱;Logstash 在日志的复杂文本解析上有更成熟的工具。

但两者目前不能直接串联。Logstash 没有 OTLP receiver:logstash-plugins 下不存在对应的 input 插件,8.x 全部 release notes 里也检索不到 OTLP 相关条目。Elastic 在 Logstash 侧对 OTel 的落点是反方向的——9.5 起 Logstash 可以把自己的内部运行指标通过 OTLP 导出到任意兼容后端(otel.metrics.enabled,默认 false,目前是技术预览)。在 OTel 体系里,Logstash 的角色是被观测的遥测数据源,而不是遥测数据的接收端。

要让 OTel Collector 采集的数据流进 Logstash,得走一个中间协议:Collector 用 kafka exporter 写出,Logstash 用 kafka input 读入。这条路能通,但它是两套系统各自对接一个公共队列,不是原生集成。

定位收敛

把演进历程和外部冲击放在一起,Logstash 的定位从"Elastic Stack 的通用数据接入层"收敛到了"复杂转换与多目标路由的中心聚合节点":

1
2
3
4
5
6
7
8
旧定位(2013–2018):
Logstash 是把所有东西灌进 ES 的通用采集管道

新定位(2019–今):
边缘采集 → Elastic Agent / Beats / Fluent Bit
简单变换 → ES Ingest Pipeline
可观测性标准化 → OTel Collector
复杂 ETL + 多目标 + 高可靠(PQ) → Logstash

这是一个在技术生态里反复出现的模式:通用工具在早期覆盖所有场景,随着专用工具成熟,通用工具逐渐退出它并不擅长的简单场景,聚焦在它有独特优势的复杂场景上。这不是工具的衰落,而是职责的收敛。

模式提炼

1
2
3
4
5
6
7
8
9
10
11
12
13
模式:专业化压缩通用工具的边界,但不消灭它

- 每次有新的专用工具成熟(Beats → Elastic Agent → OTel),
通用工具(Logstash)就失去一批简单场景
- 简单场景被分走后,通用工具的留存价值集中在
"复杂场景 + 跨生态边界 + 需要缓冲可靠性"三类需求上
- 选型的时机:评估当前场景是否超出了专用工具的能力上限,
超出则引入通用工具;未超出则优先用更轻量的专用工具

对应 Logstash 的操作化判断:
"目标超出 ES 生态 OR 变换超出 Ingest Pipeline 能力
OR 需要 PQ 兜底" → 引入 Logstash
否则 → Elastic Agent + Ingest Pipeline

工程迁移表

Logstash 演进特性 解决的问题 对应的通用模式
持久队列(5.1 引入,5.4 GA) 崩溃丢数据 持久化消息队列 + 检查点
死信队列(5.5) 解析失败事件消失 Dead Letter Queue / side output
多管道配置(6.0) 所有数据流共享一条链 按业务拆分部署单元
pipeline-to-pipeline(6.3 引入,7.4 GA) 单管道耦合所有逻辑 管道解耦 / 微服务间通信
Java 执行引擎(6.1 可用,7.0 默认,8.0 移除 Ruby) JRuby 解释器性能瓶颈 从解释器迁移到编译执行
flow metrics(8.5) 运行时状态不可见 实时吞吐指标 / RED 方法
Elastic Agent 替代边缘采集 运维多 Beats 进程复杂 统一代理 / Fleet 管理
OTLP 指标导出(9.5,技术预览) 运行指标绑死在专有 API 上 开放遥测协议 / 监控后端可替换

常见误解

误解一:“Elastic Agent 出来之后 Logstash 就没用了”。Elastic Agent 替代的是 Beats 在 Elastic 生态内的边缘采集职责,而不是 Logstash 的复杂变换和多目标路由职责。两者解决的是不同层次的问题,在同一套系统里可以并存。

误解二:“从 Logstash 迁移到 Elastic Agent 不需要改变换逻辑”。迁移时需要把 Logstash filter 逻辑翻译为 Ingest Pipeline processor,这是一次重写,不是配置平移。两者的语法、能力范围和调试方式都不同,迁移成本取决于现有 filter 的复杂程度。

误解三:“OTel Collector 可以直接替换 Logstash”。OTel Collector 的 processor 生态和日志文本解析能力(没有 Grok 等价物)目前不如 Logstash,在需要复杂正则解析非结构化日志的场景下差距明显。两者在 traces/metrics/logs 的标准化采集上有重叠,但在日志复杂处理上不是同等能力的替代。

误解四:“Logstash 的 JRuby 已经完全被移除”。Java 执行引擎替代的是核心 pipeline 的 JRuby 执行路径,Logstash 的插件层(尤其是社区插件)仍然有 Ruby 代码。logstash-core 的主要执行路径已经是 Java,但 Logstash 作为整体仍然依赖 JRuby 运行时来加载和运行 Ruby 插件。

练习

  1. 查阅 Elastic 官方文档,找到 Elastic Agent 的 integration 列表,选一个你常用的数据源(如 Nginx、PostgreSQL、Kubernetes),对比它在 integration 里预打包的 Ingest Pipeline 处理逻辑和你之前可能用 Logstash 写的等价 filter 配置,记录功能覆盖的差距。

  2. 阅读 Logstash 的 flow metrics 文档(/_node/stats/pipelines),找出 flow.filter_throughputflow.queue_backpressureflow.output_throughput 三个指标,解释它们分别反映了管道的哪个阶段的状态,以及如何用它们定位"是 filter 慢还是 output 慢"。

  3. 思考题:给定一个已有生产 Logstash 集群(接收来自 50 台服务器的 Filebeat,做复杂 Grok 解析,写两个 ES 集群),Elastic 要求你评估是否迁移到 Elastic Agent。写出评估框架:哪些部分可以迁移(边缘采集),哪些必须保留 Logstash(双集群写入、复杂 Grok),以及迁移过程中如何保证不丢数据。

系列导航

序号 主题
00 导读:核心对象是 event,骨架是三段管道
01 架构:JRuby、JVM 与 pipeline 的运行形态
02 event 模型:@timestamp、@metadata 与字段引用
03 codec:字节流与 event 的边界转换
04 input 插件:拉取、监听与 Beats 接入
05 Grok 的本质:命名正则加预定义 pattern
06 dissect 与结构化 filter:放弃回溯换吞吐
07 常用 filter 组合:mutate、date、geoip 与条件
08 output 插件:Elasticsearch output 与批量写入
09 pipeline 执行模型:worker、batch 与背压
10 内存队列 vs 持久队列:可靠性的分界线
11 死信队列(DLQ):无法处理的 event 去哪
12 Multiple Pipelines 与 pipeline-to-pipeline
13 监控:Node Stats API、hot threads 与瓶颈定位
14 性能调优:JVM heap、批处理与持久队列磁盘
15 Logstash vs Beats vs Ingest Pipeline:该用谁
16 Logstash vs Fluentd vs Vector:日志管道的三种取舍
17 Logstash 的演进与 Elastic Agent 的冲击(本篇)

参考资料