深入 Logstash 03 - codec:字节流与 event 的边界转换
multiline 只能是 codec,不能是 filter。这不是历史包袱留下的形状,是成帧这件事本身不可逆决定的:字节流一旦被切成离散 event 进了队列,行与行之间的先后关系就再没有载体,filter 拿到的每个 event 都是孤立的。 上一篇拆开了 event 的内部结构。这一篇往前退一步,看 event 是怎么被造出来的。顺着 codec 与 filter 的这条边界还会掉出一个大多数人记错的细节:默认的 plain codec 其实根本不按行切,按行切的是 line codec,而流式 input 在注册时会悄悄把前者换成后者。 数据流全景 123456789101112131415161718192021222324252627282930外部数据源 │ 字节流(TCP stream / 文件行 / UDP 包 / ...) ▼┌─ Input Plugin ───────────────────────────────────────────┐│ Codec: decode(字节 → event) ...
深入 Logstash 02 - event 模型:@timestamp、@metadata 与字段引用
在 filter 里写 add_field => { "[@metadata][target_index]" => "logs-web" },output 的 index => 里用 %{[@metadata][target_index]} 能取到值,但写进 Elasticsearch 的 _source 里找不到这个字段。这件事的机制既不在 output 插件里,也不在 codec 里,而在 Event API 上:org.logstash.Event 有两个平级的 ConvertedMap 字段 data 和 metadata,to_hash 返回的只是 data,要连 metadata 一起拿必须改调 to_hash_with_metadata。凡是走 to_hash 的下游,看到的就是一个没有 @metadata 的 event——不需要任何人动手剥离。 上一篇确立了 JRuby/JVM/多 pipeline 的运行形态和本系列的版本前提。这一篇进入 event 的内部结构:...
深入 Logstash 01 - 架构:JRuby、JVM 与 pipeline 的运行形态
.conf 里声明的每个插件都是 Ruby gem,但把这些插件串起来执行的已经不是 Ruby 代码。Logstash 8.x 没有 Ruby 执行引擎——8.0 把它整个移除了。.conf 先由 ConfigCompiler 编译成 PipelineIR,再编译成由 Dataset 节点组成的 Java 执行图,插件的 filter/encode 方法是被这张图通过 JRuby 的 Java 互操作回调的。 上一篇确立了 event 与三段管道(input → filter → output)的核心抽象。这一篇顺着上面这道落差往下看两件事:插件是 Ruby gem 却跑在 JVM 上,在启动开销、线程模型和内存账上分别意味着什么;一个进程里多条 pipeline 的结构又是如何组织的。 版本前提 本系列的示例基于 Logstash 8.x,参数名与默认值以 8.19 分支的源码为准。 有一个设置会影响几乎每一篇的实验输出:pipeline.ecs_compatibility。Logstash 8 起它的默认值是 v8,所有实现了 ECS 兼容模式的插件都按 Elastic Co...
深入 Kibana 17 - 演进:从纯前端到 platform 再到 Serverless
Kibana 从浏览器直连 Elasticsearch 的纯前端应用,逐步演化成带 Node.js 服务、插件平台和 Serverless 交付形态的完整产品。每次架构变化都对应上一阶段无法承受的约束,也引入新的复杂度。收尾篇沿版本脉络回看这些取舍,并标出哪些设计已经退出当前主线。 Kibana 3:无服务端,浏览器直连 Kibana 3 发布于 2014 年,是一个纯前端应用。部署方式是把静态文件丢进任意 Web 服务器或 Elasticsearch 的 site plugin 目录,浏览器直接向 ES 的 REST 接口发 HTTP 请求。 这个架构的优点是极度简单:没有额外运行时依赖,没有状态管理问题,没有服务端语言选型。 它的结构性缺陷有三条。 第一,安全问题。浏览器直连 ES,意味着 ES 的地址和凭据必须暴露给每一个打开页面的用户。任何能看到 Kibana 页面的人都能直接操作 ES。在公网或多用户环境里,这是不可接受的。 第二,状态无处安放。Dashboard 定义存在哪里?Kibana 3 的解法是把 Dashboard JSON 存回 Elasticsearch...
深入 Kibana 16 - Kibana vs Grafana:两种可视化平台的设计取舍
Kibana 与 Grafana 都能做可视化和告警,底层假设却不同。Kibana 仍然围绕 Elasticsearch 深度集成,Grafana 13.x 继续保持 datasource-first。版本号往前走,架构分叉没变。 架构起点的分叉 Kibana 和 Grafana 都是可视化平台,都有 Dashboard、Panel、告警,但它们的架构起点完全不同,导致几乎所有设计决策都走向了不同方向。 Kibana 的起点是"Elasticsearch 的前端"。即使经过多次重构,它的状态(Saved Objects)存在 ES 里,它的查询模型围绕 ES 的 aggregation 体系构建,它的 Data View 是对 ES 索引模式的映射。ES 是 Kibana 唯一的数据后端,也是它的持久化存储。这种深度绑定让 Kibana 能充分利用 ES 的全文检索、嵌套 aggregation、异步搜索、PIT 等特性,但代价是:换掉 ES,Kibana 就什么都不是了。 Grafana 的起点是"不同数据源的统一可视化层"。它自己用 S...
深入 Kibana 15 - 性能模型:bundle、bootstrap 与异步搜索会话
插件数量增长会直接推高前端包体和启动成本,长查询又要求结果能够在页面离开后继续保存。Kibana 的性能治理因此同时覆盖 bundle 拆分、bootstrap 顺序和后台搜索。这里的“搜索会话”在 8.15 起已经进入弃用路径,9.0 默认关闭,9.2 之后由 background search 接棒。本篇把首屏加载与后台查询放在一张性能模型里讨论。 前端 bundle 体系 Kibana 的前端代码量巨大。Discover、Lens、Dashboard、Maps、Security、Observability 加在一起,编译后的 JavaScript 体积以百 MB 计。如果把所有代码打成一个 bundle 让用户一次性下载,首屏时间会无法接受。 Kibana 的解法是三层 bundle 结构。 12345678910111213浏览器请求 Kibana 页面│├── bootstrap.js 核心 shell,极小,总是先加载│ └── 初始化运行时,注册模块加载器,决定加载哪些插件│├── core bundle 平台公共服务│ ...
深入 Kibana 14 - 插件体系:platform 的 setup/start 生命周期
访问控制划定了插件能做什么,插件平台本身还要解决依赖、生命周期和对外契约。Kibana 的 platform/core 体系通过清单声明依赖,并把启动过程拆成 setup、start 和 stop。这个模型取代了旧平台依赖全局对象与任意初始化顺序的做法。 旧平台的问题 Kibana 5 到 7 早期,插件系统是有机生长出来的,没有统一的生命周期模型。每个插件在 init 函数里随意注册路由、随意拉取其他插件的引用、随意访问全局 server 对象。这带来三个结构性问题。 第一是循环依赖。插件 A 拉 B,B 拉 C,C 再拉 A。因为没有强制的声明式依赖,运行时才能发现环。第二是缺乏生命周期。所有插件的 init 在服务器启动时同步跑完,但没有清晰的"配置阶段"和"运行阶段"之分,导致在配置阶段就能访问运行时状态(反过来也是)。第三是没有类型安全。插件暴露给外部的 API 是任意 JavaScript 对象,没有类型约束,外部调用者无法静态感知接口变化。 Kibana platform(旧称 New Platform, NP)从 Kiban...
深入 Kibana 13 - Spaces 与安全:RBAC、Feature Controls 与多租户
多个团队共用同一套 Kibana 时,页面组织、对象可见性和操作权限不能混成一个概念。Spaces 为 Saved Object 提供命名空间,RBAC 决定用户能做什么,Feature Controls 则裁剪可见功能。三层组合后,Kibana 才具备平台级多租户能力。 隔离需求的来源 一个 Elasticsearch 集群承载多个团队的数据是常态。但 Kibana 默认只有一个全局视图——所有 Dashboard、Index Pattern、Saved Search 堆在一起。团队 A 看到团队 B 的运维面板,不是安全问题(数据权限可以通过 ES 索引级别的角色控制),而是噪音问题。Spaces 的出发点是 UI 级别的组织隔离,不是数据安全隔离。安全隔离由 RBAC 叠加在 Spaces 之上实现。 架构总览 12345678910111213141516171819202122232425┌─────────────────────────────────────────────────┐│ Kibana Server ...
深入 Kibana(十二):Task Manager——Kibana 内部的分布式任务调度
Alerting 和 Reporting 已经两次碰到 Task Manager:一个需要周期检查规则,一个需要排队生成报表。Task Manager 是两者共用的进程内分布式调度器,负责任务注册、认领、并发控制和重试。本篇把此前的前向引用收回来,专门分析多 Kibana 实例如何协调后台作业。 Task Manager 的定位 Task Manager 是 Kibana 进程内的分布式任务调度器,7.4 版本引入,解决的问题是:Kibana 需要运行定期或一次性后台任务(告警检查、报表生成、ML 模型同步等),但不依赖外部消息队列或 cron 守护进程。 1234567外部 cron Kibana Task Manager───────────────────────── ──────────────────────────────────运行在 OS 层面 运行在 Kibana 进程内任务状态存在本机 任务状态存在 Elasticsearch多实例需额外协调 ...
深入 Kibana(十一):Reporting——从 Dashboard 到 PDF/PNG 的生成链路
Reporting 同样借助 Task Manager 排队执行,但 PDF/PNG 与 CSV 走的是两条不同链路。前者需要 headless Chromium 打开页面并截图,后者直接执行搜索并写出数据。第 12 篇会回到共用的任务调度器,这里只处理报表生成自身的边界。 两条完全不同的生成路径 Kibana Reporting 对外提供两类产物,但底层实现路径截然不同: 12345678类型 触发源 生成方式 存储─────────────────────────────────────────────────────────────────PDF / PNG Dashboard headless Chromium .kibana + blob Visualize 截图 → PDF 合并 CanvasCSV Saved Search ES PIT + search_after .kibana +...





