Reporting 同样借助 Task Manager 排队执行,但 PDF/PNG 与 CSV 走的是两条不同链路。前者需要 headless Chromium 打开页面并截图,后者直接执行搜索并写出数据。第 12 篇会回到共用的任务调度器,这里只处理报表生成自身的边界。

两条完全不同的生成路径

Kibana Reporting 对外提供两类产物,但底层实现路径截然不同:

1
2
3
4
5
6
7
8
类型          触发源         生成方式                存储
─────────────────────────────────────────────────────────────────
PDF / PNG Dashboard headless Chromium .kibana + blob
Visualize 截图 → PDF 合并
Canvas

CSV Saved Search ES PIT + search_after .kibana + job data
Discover 纯数据,无渲染

CSV 路径不涉及浏览器,CPU 和内存消耗远低于 PDF/PNG 路径。两条路径都通过 Task Manager 异步执行,请求方通过轮询获取任务状态。

headless Chromium 渲染链路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
用户点击 "Generate PDF"


Kibana server 接收请求
→ 创建 reporting job Saved Object (status: pending)
→ 提交 Task Manager task


Task Manager 分配 worker 执行 task


ReportingPlugin 启动 headless Chromium
├── 以 Kibana 内部 URL 导航到目标 Dashboard
│ URL 携带 session cookie (kibana_reported_user)
├── 注入 waitForRenderComplete hook
│ 轮询 window.__renderComplete === true
├── 截图(每个 panel 或整页)
└── puppeteer-core → PDF 合并 / PNG 输出


将结果写入 reporting job 记录 + 下载产物
更新 job status: completed

waitForRenderComplete 是 Kibana 客户端在所有 Embeddable 渲染完成后设置的全局标志,Chromium 端通过 page.evaluate() 轮询该标志,超时(默认 60 秒)则报错。

CSV 导出链路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
用户触发 "Export as CSV"(来自 Discover 或 Saved Search


Kibana server 接收请求
→ 读取 Saved Searchindex pattern + query + filter + sort
→ 创建 reporting job Saved Object (status: pending)
→ 提交 Task Manager task


Task Manager 分配 worker


CsvSearchSourceExportType.runTask()
├── 构建 SearchSource(index, query, fields, sort
├── 调用 ES PIT + search_after 分页
│ 每页 500 行(scroll 仅在显式切换策略时使用)
├── 逐行转换为 CSV(含表头、日期格式化、值转义)
└── 写入 blob 存储


job status: completed,客户端 download link 可用

CSV 无 Chromium 依赖,在内存受限环境中是安全替代方案。字段顺序来自 Saved Search 中配置的列顺序,未配置时按 index pattern 字段顺序输出。

报表任务的生命周期状态

1
2
pending → processing → completed
└→ failed (可重试)

状态存在 .kibana 索引中 type=reporting-job 的 Saved Object 字段 statuscompleted 后 blob 可下载;failedoutput.content 字段含错误信息。

存储后端

配置项 默认值 说明
xpack.reporting.encryptionKey 随机 加密报表 content
xpack.reporting.kibanaServer.* 继承主配置 Chromium 回连的 Kibana URL
xpack.screenshotting.capture.timeouts.waitForElements 1m 等待面板渲染完成
xpack.screenshotting.capture.timeouts.renderComplete 2m 等待渲染完成
xpack.reporting.csv.scroll.strategy pit CSV 分页策略;scroll 仅作兼容回退
xpack.reporting.csv.maxSizeBytes 250mb CSV 最大字节数

报表产物由 Reporting job 管理,不要再把它理解成单机临时目录里的文件。

实验:生成 PDF 并观察 Task Manager

以下实验需要 Kibana 8.x,且已有至少一个 Dashboard。

第一步:触发 PDF 报表生成

1
2
3
4
POST kbn:/api/reporting/generate/printablePdfV2
{
"jobParams": "(browserTimezone:Asia/Shanghai,layout:(dimensions:(height:768,width:1280),id:preserve_layout),objectType:dashboard,relativeUrls:!('/app/dashboards#/view/<dashboard_id>?_g=()'),title:'My Dashboard')"
}

返回字段 path 即报表任务路径,例如 /api/reporting/jobs/download/kjo_...,以及 job.id

第二步:轮询状态

1
GET kbn:/api/reporting/jobs/info/<job_id>

status 字段从 pendingprocessingcompletedcompleted 时出现 output.size

第三步:查看 Task Manager 任务

1
2
3
4
5
6
GET .kibana_task_manager/_search
{
"query": {
"term": { "task.taskType": "report:printablePdfV2" }
}
}

任务文档包含 task.runAttask.attemptstask.state 字段。报表任务是一次性任务(task.schedule 为空),与 Alerting 的循环任务不同。

第四步:下载报表

1
GET kbn:/api/reporting/jobs/download/<job_id>

响应 Content-Type 为 application/pdf,Content-Disposition 含文件名。

映射到内部对象

实验观测 内部对象
POST /generate 响应 .kibana 中 type=reporting-job 的 Saved Object 被创建
Task Manager 执行报表 .kibana_task_manager 中 taskType=report:* 的 task 文档
PDF/PNG 文件内容 Reporting job 记录和下载产物
CSV 数据来源 ES PIT + search_after,不经过 Chromium
渲染超时 waitForRenderComplete 全局标志超时,job 状态变 failed

模式提炼

Kibana Reporting 的设计原则是"报表即异步任务"。同步生成 PDF 对 Kibana 服务器影响过大,异步队列让用户可以提交后离开、稍后下载,且多个报表任务可以在容量范围内并发执行。

headless Chromium 路径的本质是"让 Kibana 自己访问自己":Chromium 以内部 URL 导航,携带服务账户 cookie,等待客户端 JavaScript 完成渲染后截图。这意味着报表中看到的内容与浏览器中看到的内容完全一致,包括所有 Embeddable 插件的渲染效果。

CSV 路径绕过渲染层,直接从 Elasticsearch 拉取原始数据,适合数据分析场景而不适合视觉报告。

工程迁移表

需求 方案
定时发送 PDF 报表给管理层 Reporting + Alerting 联动(Alerting action 调用 reporting API),或外部 cron 调用 API
导出百万行数据 CSV 导出,调大 csv.maxSizeBytes;超出限制需分批
多 Kibana 实例共享报表产物 依赖同一个 Elasticsearch 后端和报表 job 记录,不要假定本地目录可共享
Chromium 内存不足导致报表失败 减少 Dashboard panel 数量;或调高 xpack.screenshotting.capture.timeouts.renderComplete
报表中中文字符乱码 确保 Chromium 运行环境包含 CJK 字体

常见误解

CSV 导出与 PDF 导出共用同一个"报表"入口,但内部实现完全不同。CSV 不使用 Chromium,也不受 capture.timeouts 影响;超时或截图失败的排查方向不适用于 CSV。

Kibana Reporting 的 PDF 中看不到 panel 的原因通常是 waitForRenderComplete 超时,而不是 Chromium 问题。增大 renderComplete 超时是第一步排查手段。

报表 Saved Object 与实际文件内容是分开存储的。删除 Saved Object 不会释放文件系统空间;8.x 提供 xpack.reporting.cleanupInterval 自动清理过期报表。

练习

  1. 通过 API 触发 CSV 报表,在 .kibana_task_manager 中确认 task 类型与 PDF 报表的 task 类型不同。
  2. 修改 xpack.reporting.csv.maxSizeBytes 为 1024(1KB),触发一个结果集较大的 CSV,观察 job 状态和 output.content 中的截断提示。
  3. 在 Dashboard 中添加一个渲染较慢的自定义 Vega panel,观察 PDF 生成时间与 waitForRenderComplete 超时的关系。
  4. 查询 .kibana/_search 过滤 type=reporting-job,对比 pending 和 completed 状态的 Saved Object 字段差异。

系列导航

篇目 主题
00 导读:Kibana 的状态存在 Elasticsearch 里
01 架构:浏览器、Node.js server 与 New Platform
02 Saved Object:一切状态的统一模型
03 Data View:查询之前的字段抽象
04 Search Source 与查询翻译
05 Discover:交互式检索的执行模型
06 聚合式可视化:Visualize 与 bucket/metric
07 Lens:拖拽背后的自动聚合推断
08 TSVB、Timelion 与 Vega
09 Dashboard 与 Embeddable
10 Alerting:Rule、Connector 与 Action
11 Reporting:从 Dashboard 到 PDF/PNG
12 Task Manager:分布式任务调度
13 Spaces 与安全:RBAC、Feature Controls 与多租户
14 插件体系:setup/start 生命周期
15 性能模型:bundle、bootstrap 与异步搜索会话
16 Kibana vs Grafana:两种平台的设计取舍
17 演进:从纯前端到 Platform 再到 Serverless

参考资料

  1. Elastic 官方文档,Reporting settings in Kibana - Reporting settings in Kibana
  2. Elastic 官方文档,Share and export dashboards - Share and export dashboards
  3. Elastic 官方文档,Reporting API - Reporting API