深入 Kibana(十一):Reporting——从 Dashboard 到 PDF/PNG 的生成链路
上一篇展示了 Task Manager 调度的一种用途——驱动 Alerting Rule 周期执行。这一篇进入 Reporting,核心问题是:headless Chromium 渲染、报表任务队列、CSV 导出走的是搜索而非截图。
两条完全不同的生成路径
Kibana Reporting 对外提供两类产物,但底层实现路径截然不同:
1 | |
CSV 路径不涉及浏览器,CPU 和内存消耗远低于 PDF/PNG 路径。两条路径都通过 Task Manager 异步执行,请求方通过轮询获取任务状态。
headless Chromium 渲染链路
1 | |
waitForRenderComplete 是 Kibana 客户端在所有 Embeddable 渲染完成后设置的全局标志,Chromium 端通过 page.evaluate() 轮询该标志,超时(默认 60 秒)则报错。
CSV 导出链路
1 | |
CSV 无 Chromium 依赖,在内存受限环境中是安全替代方案。字段顺序来自 Saved Search 中配置的列顺序,未配置时按 index pattern 字段顺序输出。
报表任务的生命周期状态
1 | |
状态存在 .kibana 索引中 type=reporting-job 的 Saved Object 字段 status。completed 后 blob 可下载;failed 时 output.content 字段含错误信息。
存储后端
| 配置项 | 默认值 | 说明 |
|---|---|---|
xpack.reporting.encryptionKey |
随机 | 加密报表 content |
xpack.reporting.kibanaServer.* |
继承主配置 | Chromium 回连的 Kibana URL |
xpack.reporting.capture.timeouts.waitForElements |
30000ms | 等待 DOM 元素超时 |
xpack.reporting.capture.timeouts.renderComplete |
60000ms | 等待渲染完成超时 |
xpack.reporting.csv.maxSizeBytes |
10485760 (10MB) | CSV 最大字节数 |
8.x 默认将报表文件存在 Kibana 本地文件系统的临时目录,生产环境建议配置 S3 外部存储(xpack.reporting.s3.*)以支持多实例共享。
实验:生成 PDF 并观察 Task Manager
以下实验需要 Kibana 8.x,且已有至少一个 Dashboard。
第一步:触发 PDF 报表生成
1 | |
返回字段 path 即报表任务路径,例如 /api/reporting/jobs/download/kjo_...,以及 job.id。
第二步:轮询状态
1 | |
status 字段从 pending → processing → completed。completed 时出现 output.size。
第三步:查看 Task Manager 任务
1 | |
任务文档包含 task.runAt、task.attempts、task.state 字段。报表任务是一次性任务(task.schedule 为空),与 Alerting 的循环任务不同。
第四步:下载报表
1 | |
响应 Content-Type 为 application/pdf,Content-Disposition 含文件名。
映射到内部对象
| 实验观测 | 内部对象 |
|---|---|
| POST /generate 响应 | .kibana 中 type=reporting-job 的 Saved Object 被创建 |
| Task Manager 执行报表 | .kibana_task_manager 中 taskType=report:* 的 task 文档 |
| PDF/PNG 文件内容 | Kibana 本地 FS 或 S3(xpack.reporting.output.*) |
| CSV 数据来源 | ES 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 实例共享报表文件 | 配置 S3 外部存储 |
| Chromium 内存不足导致报表失败 | 减少 Dashboard panel 数量;或调高 capture.browser.chromium.inspect 选项进行诊断 |
| 报表中中文字符乱码 | 确保 Kibana server 的字体配置包含 CJK 字体(xpack.reporting.capture.browser.chromium.env.LANG) |
常见误解
CSV 导出与 PDF 导出共用同一个"报表"入口,但内部实现完全不同。CSV 不使用 Chromium,也不受 capture.timeouts 影响;超时或截图失败的排查方向不适用于 CSV。
Kibana Reporting 的 PDF 中看不到 panel 的原因通常是 waitForRenderComplete 超时,而不是 Chromium 问题。增大 renderComplete 超时是第一步排查手段。
报表 Saved Object 与实际文件内容是分开存储的。删除 Saved Object 不会释放文件系统空间;8.x 提供 xpack.reporting.cleanupInterval 自动清理过期报表。
练习
- 通过 API 触发 CSV 报表,在 .kibana_task_manager 中确认 task 类型与 PDF 报表的 task 类型不同。
- 修改
xpack.reporting.csv.maxSizeBytes为 1024(1KB),触发一个结果集较大的 CSV,观察 job 状态和output.content中的截断提示。 - 在 Dashboard 中添加一个渲染较慢的自定义 Vega panel,观察 PDF 生成时间与
waitForRenderComplete超时的关系。 - 查询
.kibana/_search过滤 type=reporting-job,对比 pending 和 completed 状态的 Saved Object 字段差异。
系列导航
- 上一篇:深入 Kibana(十):Alerting 框架——Rule、Connector 与 Action 的三段契约
- 下一篇:深入 Kibana(十二):Task Manager——Kibana 内部的分布式任务调度
参考资料
- Elastic 官方文档,Kibana Reporting - https://www.elastic.co/guide/en/kibana/current/reporting-getting-started.html
- Elastic 官方文档,Reporting settings in Kibana - https://www.elastic.co/guide/en/kibana/current/reporting-settings-kb.html
- Elastic 官方文档,Reporting API - https://www.elastic.co/guide/en/kibana/current/reporting-api.html
- Kibana 源码,
x-pack/plugins/reporting/server/export_types/- https://github.com/elastic/kibana
