kibana-dashboards

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Kibana Dashboards and Visualizations

Kibana仪表板与可视化

Overview

概述

The Kibana dashboards and visualizations APIs provide a declarative, Git-friendly format for defining dashboards and visualizations. Definitions are minimal, diffable, and suitable for version control and LLM-assisted generation.
Key Benefits:
  • Minimal payloads (no implementation details or derivable properties)
  • Easy to diff in Git
  • Consistent patterns for GitOps workflows
  • Designed for LLM one-shot generation
  • Robust validation via OpenAPI spec
Version Requirement: Kibana 9.4+ (SNAPSHOT)
Kibana仪表板和可视化API提供了一种声明式、对Git友好的格式来定义仪表板和可视化。定义内容简洁、可对比差异,适用于版本控制和大语言模型(LLM)辅助生成。
核心优势:
  • 轻量化负载(无实现细节或可推导属性)
  • 在Git中易于对比差异
  • 适配GitOps工作流的一致模式
  • 专为LLM一次性生成设计
  • 通过OpenAPI规范实现可靠验证
版本要求: Kibana 9.4+(SNAPSHOT版本)

Important Caveats

重要注意事项

Inline vs Saved Object References: When embedding Lens panels in dashboards, prefer inline
attributes
definitions over
savedObjectId
references. Inline definitions are more reliable and self-contained.
内联定义 vs 已保存对象引用: 在仪表板中嵌入Lens面板时,优先使用内联
attributes
定义,而非
savedObjectId
引用。内联定义更可靠且具备自包含性。

Quick Start

快速开始

Environment Configuration

环境配置

Kibana connection is configured via environment variables. Run
node scripts/kibana-dashboards.js test
to verify the connection. If the test fails, suggest these setup options to the user, then stop. Do not try to explore further until a successful connection test.
Kibana连接通过环境变量配置。运行
node scripts/kibana-dashboards.js test
验证连接。如果测试失败,向用户建议以下设置选项,然后停止操作。在连接测试成功前,请勿进行进一步操作。

Option 1: Elastic Cloud (recommended for production)

选项1:Elastic Cloud(生产环境推荐)

bash
export KIBANA_CLOUD_ID="deployment-name:base64encodedcloudid"
export KIBANA_API_KEY="base64encodedapikey"
bash
export KIBANA_CLOUD_ID="deployment-name:base64encodedcloudid"
export KIBANA_API_KEY="base64encodedapikey"

Option 2: Direct URL with API Key

选项2:带API密钥的直接URL

bash
export KIBANA_URL="https://your-kibana:5601"
export KIBANA_API_KEY="base64encodedapikey"
bash
export KIBANA_URL="https://your-kibana:5601"
export KIBANA_API_KEY="base64encodedapikey"

Option 3: Basic Authentication

选项3:基础认证

bash
export KIBANA_URL="https://your-kibana:5601"
export KIBANA_USERNAME="elastic"
export KIBANA_PASSWORD="changeme"
bash
export KIBANA_URL="https://your-kibana:5601"
export KIBANA_USERNAME="elastic"
export KIBANA_PASSWORD="changeme"

Option 4: Local Development with start-local

选项4:使用start-local进行本地开发

Use start-local to spin up Elasticsearch/Kibana locally, then source the generated
.env
:
bash
curl -fsSL https://elastic.co/start-local | sh
source elastic-start-local/.env
export KIBANA_URL="$KB_LOCAL_URL"
export KIBANA_USERNAME="elastic"
export KIBANA_PASSWORD="$ES_LOCAL_PASSWORD"
Then run
node scripts/kibana-dashboards.js test
to verify the connection.
使用start-local在本地启动Elasticsearch/Kibana,然后加载生成的
.env
文件:
bash
curl -fsSL https://elastic.co/start-local | sh
source elastic-start-local/.env
export KIBANA_URL="$KB_LOCAL_URL"
export KIBANA_USERNAME="elastic"
export KIBANA_PASSWORD="$ES_LOCAL_PASSWORD"
然后运行
node scripts/kibana-dashboards.js test
验证连接。

Optional: Skip TLS verification (development only)

可选:跳过TLS验证(仅开发环境)

bash
export KIBANA_INSECURE="true"
bash
export KIBANA_INSECURE="true"

Basic Workflow

基础工作流

bash
undefined
bash
undefined

Test connection and API availability

测试连接和API可用性

node scripts/kibana-dashboards.js test
node scripts/kibana-dashboards.js test

Dashboard operations

仪表板操作

node scripts/kibana-dashboards.js dashboard get <id> echo '<json>' | node scripts/kibana-dashboards.js dashboard create - echo '<json>' | node scripts/kibana-dashboards.js dashboard update <id> - node scripts/kibana-dashboards.js dashboard delete <id>
node scripts/kibana-dashboards.js dashboard get <id> echo '<json>' | node scripts/kibana-dashboards.js dashboard create - echo '<json>' | node scripts/kibana-dashboards.js dashboard update <id> - node scripts/kibana-dashboards.js dashboard delete <id>

Lens visualization operations

Lens可视化操作

node scripts/kibana-dashboards.js lens list node scripts/kibana-dashboards.js lens get <id> echo '<json>' | node scripts/kibana-dashboards.js lens create - echo '<json>' | node scripts/kibana-dashboards.js lens update <id> - node scripts/kibana-dashboards.js lens delete <id>
undefined
node scripts/kibana-dashboards.js lens list node scripts/kibana-dashboards.js lens get <id> echo '<json>' | node scripts/kibana-dashboards.js lens create - echo '<json>' | node scripts/kibana-dashboards.js lens update <id> - node scripts/kibana-dashboards.js lens delete <id>
undefined

Dashboards API

仪表板API

Dashboard Definition Structure

仪表板定义结构

The API expects a flat request body with
title
and
panels
at the root level. The response wraps these in a
data
envelope alongside
id
,
meta
, and
spaces
.
json
{
  "title": "My Dashboard",
  "panels": [ ... ],
  "time_range": {
    "from": "now-24h",
    "to": "now"
  }
}
Note: Dashboard IDs are auto-generated by the API. The script also accepts the legacy wrapped format
{ id?, data: { title, panels }, spaces? }
and unwraps it automatically.
API要求请求体为扁平化结构,根层级包含
title
panels
。响应会将这些内容包裹在
data
信封中,同时返回
id
meta
spaces
json
{
  "title": "我的仪表板",
  "panels": [ ... ],
  "time_range": {
    "from": "now-24h",
    "to": "now"
  }
}
注意: 仪表板ID由API自动生成。脚本也接受传统的嵌套格式
{ id?, data: { title, panels }, spaces? }
,并会自动将其展开。

Create Dashboard

创建仪表板

bash
echo '{
  "title": "Sales Dashboard",
  "panels": [],
  "time_range": { "from": "now-7d", "to": "now" }
}' | node scripts/kibana-dashboards.js dashboard create -
bash
echo '{
  "title": "销售仪表板",
  "panels": [],
  "time_range": { "from": "now-7d", "to": "now" }
}' | node scripts/kibana-dashboards.js dashboard create -

Update Dashboard

更新仪表板

bash
echo '{
  "title": "Updated Dashboard Title",
  "panels": [ ... ]
}' | node scripts/kibana-dashboards.js dashboard update my-dashboard-id -
bash
echo '{
  "title": "更新后的仪表板标题",
  "panels": [ ... ]
}' | node scripts/kibana-dashboards.js dashboard update my-dashboard-id -

Dashboard with Inline Lens Panels (Recommended)

包含内联Lens面板的仪表板(推荐)

Use inline
attributes
for self-contained, portable dashboards:
json
{
  "title": "My Dashboard",
  "panels": [
    {
      "type": "lens",
      "uid": "metric-panel",
      "grid": { "x": 0, "y": 0, "w": 12, "h": 6 },
      "config": {
        "attributes": {
          "title": "",
          "type": "metric",
          "dataset": { "type": "esql", "query": "FROM logs | STATS total = COUNT(*)" },
          "metrics": [{ "type": "primary", "operation": "value", "column": "total", "label": "Total Count" }]
        }
      }
    },
    {
      "type": "lens",
      "uid": "chart-panel",
      "grid": { "x": 12, "y": 0, "w": 36, "h": 8 },
      "config": {
        "attributes": {
          "title": "Events Over Time",
          "type": "xy",
          "layers": [
            {
              "type": "area",
              "dataset": {
                "type": "esql",
                "query": "FROM logs | STATS count = COUNT(*) BY bucket = BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
              },
              "x": { "operation": "value", "column": "bucket" },
              "y": [{ "operation": "value", "column": "count" }]
            }
          ]
        }
      }
    }
  ],
  "time_range": { "from": "now-24h", "to": "now" }
}
使用内联
attributes
创建自包含、可移植的仪表板:
json
{
  "title": "我的仪表板",
  "panels": [
    {
      "type": "lens",
      "uid": "metric-panel",
      "grid": { "x": 0, "y": 0, "w": 12, "h": 6 },
      "config": {
        "attributes": {
          "title": "",
          "type": "metric",
          "dataset": { "type": "esql", "query": "FROM logs | STATS total = COUNT(*)" },
          "metrics": [{ "type": "primary", "operation": "value", "column": "total", "label": "总计数" }]
        }
      }
    },
    {
      "type": "lens",
      "uid": "chart-panel",
      "grid": { "x": 12, "y": 0, "w": 36, "h": 8 },
      "config": {
        "attributes": {
          "title": "事件趋势",
          "type": "xy",
          "layers": [
            {
              "type": "area",
              "dataset": {
                "type": "esql",
                "query": "FROM logs | STATS count = COUNT(*) BY bucket = BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
              },
              "x": { "operation": "value", "column": "bucket" },
              "y": [{ "operation": "value", "column": "count" }]
            }
          ]
        }
      }
    }
  ],
  "time_range": { "from": "now-24h", "to": "now" }
}

Copy Dashboard Between Spaces/Clusters

在空间/集群间复制仪表板

bash
undefined
bash
undefined

1. Get dashboard from source

1. 从源端获取仪表板

node scripts/kibana-dashboards.js dashboard get source-dashboard > dashboard.json
node scripts/kibana-dashboards.js dashboard get source-dashboard > dashboard.json

2. Edit dashboard.json to change id and/or spaces

2. 编辑dashboard.json以修改id和/或spaces

3. Create on destination

3. 在目标端创建

node scripts/kibana-dashboards.js dashboard create dashboard.json
undefined
node scripts/kibana-dashboards.js dashboard create dashboard.json
undefined

Dashboard Grid System

仪表板网格系统

Dashboards use a 48-column, infinite-row grid. On 16:9 screens, approximately 20-24 rows are visible without scrolling. Design for density—place primary KPIs and key trends above the fold.
WidthColumnsHeightRowsUse Case
Full48Large14-16Wide time series, tables
Half24Standard10-12Primary charts
Quarter12Compact5-6KPI metrics
Sixth8Minimal4-5Dense metric rows
Target: 8-12 panels above the fold. Use descriptive panel titles on the charts themselves instead of adding markdown headers.
Grid Packing Rules:
  • Eliminate Dead Space: Always calculate the bottom edge (
    y + h
    ) of every panel. When starting a new row or placing a panel below another, its
    y
    coordinate must exactly match the
    y + h
    of the panel immediately above it.
  • Align Row Heights: If multiple panels are placed side-by-side in a row (e.g., sharing the same
    y
    coordinate), they should generally have the exact same height (
    h
    ). If they do not, you must fill the resulting empty vertical space before placing the next full-width panel.
仪表板采用48列、无限行网格。在16:9屏幕上,无需滚动即可看到大约20-24行内容。设计时需注重密度——将关键KPI和核心趋势放在首屏可见区域。
宽度列数高度行数使用场景
全屏48大尺寸14-16宽幅时间序列、表格
半屏24标准尺寸10-12主要图表
四分之一屏12紧凑尺寸5-6KPI指标
六分之一屏8极小尺寸4-5高密度指标行
目标: 首屏显示8-12个面板。在图表本身使用描述性标题,而非添加Markdown标题。
网格排布规则:
  • 消除空白区域: 始终计算每个面板的底部边缘坐标(
    y + h
    )。当开始新行或在某个面板下方放置新面板时,新面板的
    y
    坐标必须与上方面板的
    y + h
    完全匹配。
  • 对齐行高: 如果多个面板在同一行并排放置(例如,共享相同的
    y
    坐标),它们通常应具有完全相同的高度(
    h
    )。如果高度不同,在放置下一个全屏面板前,必须填充由此产生的垂直空白区域。

Panel Schema

面板 Schema

json
{
  "type": "lens",
  "uid": "unique-panel-id",
  "grid": { "x": 0, "y": 0, "w": 24, "h": 15 },
  "config": { ... }
}
PropertyTypeRequiredDescription
type
stringYesEmbeddable type (e.g.,
lens
,
visualization
,
map
)
uid
stringNoUnique panel ID (auto-generated if omitted)
grid
objectYesPosition and size (
x
,
y
,
w
,
h
)
config
objectYesPanel-specific configuration
json
{
  "type": "lens",
  "uid": "unique-panel-id",
  "grid": { "x": 0, "y": 0, "w": 24, "h": 15 },
  "config": { ... }
}
属性类型是否必填描述
type
string可嵌入类型(例如:
lens
visualization
map
uid
string唯一面板ID(若省略则自动生成)
grid
object位置和尺寸(
x
,
y
,
w
,
h
config
object面板专属配置

Lens Visualizations API

Lens可视化API

Supported Chart Types

支持的图表类型

TypeDescriptionES|QL Support
metric
Single metric value displayYes
xy
Line, area, bar chartsYes
gauge
Gauge visualizationsYes
heatmap
Heatmap chartsYes
tagcloud
Tag/word cloudYes
datatable
Data tablesYes
region_map
Region/choropleth mapsYes
pie
,
donut
,
treemap
,
mosaic
,
waffle
Partition chartsYes
类型描述ES|QL支持
metric
单指标值展示
xy
折线图、面积图、柱状图
gauge
仪表盘可视化
heatmap
热力图
tagcloud
标签/词云
datatable
数据表
region_map
区域/分级统计图
pie
,
donut
,
treemap
,
mosaic
,
waffle
分区图

Dataset Types

数据集类型

There are three dataset types supported in the Lens API. Each uses different patterns for specifying metrics and dimensions.
Lens API支持三种数据集类型,每种类型指定指标和维度的方式不同。

Data View Dataset

数据视图数据集

Use
dataView
with aggregation operations. Kibana performs the aggregations automatically.
json
{
  "dataset": {
    "type": "dataView",
    "id": "90943e30-9a47-11e8-b64d-95841ca0b247"
  }
}
Available Aggregation Operations (for dataView):
OperationDescriptionRequires Field
count
Document countNo
average
Average valueYes
sum
Sum of valuesYes
max
Maximum valueYes
min
Minimum valueYes
unique_count
CardinalityYes
median
Median valueYes
standard_deviation
Standard deviationYes
percentile
Percentile (with
percentile
param)
Yes
percentile_rank
Percentile rank (with
rank
param)
Yes
last_value
Last value (with
sort_by
field)
Yes
date_histogram
Time buckets (for x-axis)Yes
terms
Top values (for x-axis/breakdown)Yes
dataView
与聚合操作配合使用。Kibana会自动执行聚合。
json
{
  "dataset": {
    "type": "dataView",
    "id": "90943e30-9a47-11e8-b64d-95841ca0b247"
  }
}
可用聚合操作(dataView):
操作描述是否需要字段
count
文档计数
average
平均值
sum
值的总和
max
最大值
min
最小值
unique_count
基数
median
中位数
standard_deviation
标准差
percentile
百分位数(需
percentile
参数)
percentile_rank
百分位排名(需
rank
参数)
last_value
最后一个值(需
sort_by
字段)
date_histogram
时间桶(用于X轴)
terms
高频值(用于X轴/分类)

ES|QL Dataset

ES|QL数据集

Use
esql
with a query string. Reference the output columns using
{ operation: 'value', column: 'column_name' }
.
json
{
  "dataset": {
    "type": "esql",
    "query": "FROM logs | STATS count = COUNT(), avg_bytes = AVG(bytes) BY host"
  }
}
ES|QL Column Reference Pattern:
json
{
  "operation": "value",
  "column": "count"
}
Key Difference: With ES|QL, you write the aggregation in the query itself, then reference the resulting columns. With dataView, you specify the aggregation operation and Kibana performs it.
esql
与查询字符串配合使用。使用
{ operation: 'value', column: 'column_name' }
引用输出列。
json
{
  "dataset": {
    "type": "esql",
    "query": "FROM logs | STATS count = COUNT(), avg_bytes = AVG(bytes) BY host"
  }
}
ES|QL列引用模式:
json
{
  "operation": "value",
  "column": "count"
}
核心差异: 使用ES|QL时,聚合逻辑写在查询语句中,然后引用生成的列。使用dataView时,只需指定聚合操作,Kibana会自动执行。

Index Dataset

索引数据集

Use
index
for ad-hoc index patterns without a saved data view:
json
{
  "dataset": {
    "type": "index",
    "index": "logs-*",
    "time_field": "@timestamp"
  }
}
对于没有已保存数据视图的临时索引模式,使用
index
json
{
  "dataset": {
    "type": "index",
    "index": "logs-*",
    "time_field": "@timestamp"
  }
}

Examples

示例

For detailed schemas and all chart type options, see Chart Types Reference.
Metric (dataView):
json
{
  "type": "metric",
  "dataset": { "type": "dataView", "id": "90943e30-9a47-11e8-b64d-95841ca0b247" },
  "metrics": [{ "type": "primary", "operation": "count", "label": "Total Requests" }]
}
Metric (ES|QL):
json
{
  "type": "metric",
  "dataset": { "type": "esql", "query": "FROM logs | STATS count = COUNT()" },
  "metrics": [{ "type": "primary", "operation": "value", "column": "count", "label": "Total Requests" }]
}
XY Bar Chart (dataView):
json
{
  "title": "Top Hosts",
  "type": "xy",
  "axis": { "x": { "title": { "visible": false } }, "left": { "title": { "visible": false } } },
  "layers": [
    {
      "type": "bar_horizontal",
      "dataset": { "type": "dataView", "id": "90943e30-9a47-11e8-b64d-95841ca0b247" },
      "x": { "operation": "terms", "fields": ["host.keyword"], "size": 10 },
      "y": [{ "operation": "count" }]
    }
  ]
}
XY Time Series (ES|QL):
json
{
  "title": "Requests Over Time",
  "type": "xy",
  "axis": { "x": { "title": { "visible": false } }, "left": { "title": { "visible": false } } },
  "layers": [
    {
      "type": "line",
      "dataset": {
        "type": "esql",
        "query": "FROM logs | STATS count = COUNT() BY bucket = BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
      },
      "x": { "operation": "value", "column": "bucket" },
      "y": [{ "operation": "value", "column": "count" }]
    }
  ]
}
Tip: Always hide axis titles when the panel title is descriptive. Use
bar_horizontal
for categorical data with long labels.
如需详细Schema和所有图表类型选项,请查看图表类型参考
指标图(dataView):
json
{
  "type": "metric",
  "dataset": { "type": "dataView", "id": "90943e30-9a47-11e8-b64d-95841ca0b247" },
  "metrics": [{ "type": "primary", "operation": "count", "label": "总请求数" }]
}
指标图(ES|QL):
json
{
  "type": "metric",
  "dataset": { "type": "esql", "query": "FROM logs | STATS count = COUNT()" },
  "metrics": [{ "type": "primary", "operation": "value", "column": "count", "label": "总请求数" }]
}
XY柱状图(dataView):
json
{
  "title": "热门主机",
  "type": "xy",
  "axis": { "x": { "title": { "visible": false } }, "left": { "title": { "visible": false } } },
  "layers": [
    {
      "type": "bar_horizontal",
      "dataset": { "type": "dataView", "id": "90943e30-9a47-11e8-b64d-95841ca0b247" },
      "x": { "operation": "terms", "fields": ["host.keyword"], "size": 10 },
      "y": [{ "operation": "count" }]
    }
  ]
}
XY时间序列图(ES|QL):
json
{
  "title": "请求趋势",
  "type": "xy",
  "axis": { "x": { "title": { "visible": false } }, "left": { "title": { "visible": false } } },
  "layers": [
    {
      "type": "line",
      "dataset": {
        "type": "esql",
        "query": "FROM logs | STATS count = COUNT() BY bucket = BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
      },
      "x": { "operation": "value", "column": "bucket" },
      "y": [{ "operation": "value", "column": "count" }]
    }
  ]
}
提示: 当面板标题具备描述性时,始终隐藏轴标题。对于标签较长的分类数据,使用
bar_horizontal
(水平柱状图)。

Full Documentation

完整文档

  • Dashboard API Reference — Dashboard endpoints and schemas
  • Lens API Reference — Lens visualization endpoints
  • Chart Types Reference — Detailed schemas for each chart type
  • Example Definitions — Ready-to-use definitions
  • 仪表板API参考 — 仪表板端点和Schema
  • Lens API参考 — Lens可视化端点
  • 图表类型参考 — 各图表类型的详细Schema
  • 示例定义 — 可直接使用的定义文件

Key Example Files

关键示例文件

  • assets/demo-dashboard.json
    — Complete dashboard with inline Lens panels (dataView format)
  • assets/dashboard-with-lens.json
    — Dashboard with ES|QL format (for future reference)
  • assets/metric-esql.json
    — Standalone metric visualization
  • assets/bar-chart-esql.json
    — Bar chart example
  • assets/line-chart-timeseries.json
    — Time series line chart
  • assets/demo-dashboard.json
    — 包含内联Lens面板的完整仪表板(dataView格式)
  • assets/dashboard-with-lens.json
    — ES|QL格式的仪表板(供未来参考)
  • assets/metric-esql.json
    — 独立指标可视化
  • assets/bar-chart-esql.json
    — 柱状图示例
  • assets/line-chart-timeseries.json
    — 时间序列折线图

Common Issues

常见问题

ErrorSolution
"401 Unauthorized"Check KIBANA_USERNAME/PASSWORD or KIBANA_API_KEY
"404 Not Found"Verify dashboard/visualization ID exists
"409 Conflict"Dashboard/viz with that ID already exists; delete first or use update
"id not allowed in PUT"Remove
id
and
spaces
from update body
Schema validation errorFor ES|QL: ensure column names match query output; use
{ operation: 'value', column: 'name' }
ES|QL missing
operation
ES|QL requires
{ operation: 'value', column: 'col' }
, not just
{ column: 'col' }
Metric uses
metric
not
metrics
Metric chart requires
metrics
(plural) array:
[{ type: 'primary', operation: '...' }]
Tagcloud uses
tag
not
tag_by
Tagcloud requires
tag_by
, not
tag
Datatable uses
columns
ES|QL datatable requires
metrics
+
rows
arrays, not
columns
XY chart failsPut
dataset
inside each layer (for both dataView and ES|QL)
Heatmap property namesUse
xAxis
,
yAxis
,
metric
(not
x
,
y
,
value
)
savedObjectId panels missingPrefer inline
attributes
definitions over savedObjectId
错误信息解决方案
"401 Unauthorized"检查KIBANA_USERNAME/PASSWORD或KIBANA_API_KEY
"404 Not Found"验证仪表板/可视化ID是否存在
"409 Conflict"该ID的仪表板/可视化已存在;先删除或使用update操作
"id not allowed in PUT"从更新请求体中移除
id
spaces
字段
Schema验证错误对于ES|QL:确保列名与查询输出匹配;使用
{ operation: 'value', column: 'name' }
格式
ES|QL缺少
operation
ES|QL要求使用
{ operation: 'value', column: 'col' }
,而非仅
{ column: 'col' }
指标图使用
metric
而非
metrics
指标图需要
metrics
(复数)数组:
[{ type: 'primary', operation: '...' }]
标签云使用
tag
而非
tag_by
标签云需要
tag_by
,而非
tag
数据表使用
columns
ES|QL数据表需要
metrics
+
rows
数组,而非
columns
XY图表加载失败
dataset
放在每个layer内部(dataView和ES|QL均适用)
热力图属性名称使用
xAxis
,
yAxis
,
metric
(而非
x
,
y
,
value
savedObjectId面板缺失优先使用内联
attributes
定义,而非savedObjectId

Guidelines

指南

  1. Design for density — Operational dashboards must show 8-12 panels above the fold (within the first 24 rows). Use compact panel heights: metrics MUST be
    h=4
    to
    h=6
    , and charts MUST be
    h=8
    to
    h=12
    .
  2. Never use Markdown for titles/headers — Do NOT add
    DASHBOARD_MARKDOWN
    panels to act as dashboard titles or section dividers. This wastes critical vertical space. Use descriptive panel titles on the charts themselves.
  3. Prioritize above the fold — Primary KPIs and key trends must be placed at
    y=0
    . Deep-dives and data tables should be placed below the charts.
  4. Use descriptive chart titles — Write titles that explain what the chart shows (e.g., "Revenue by Product Category"). Hide axis labels with
    axis.x.title.visible: false
    to reduce clutter
  5. Choose the right dataset type — Use
    dataView
    for simple aggregations,
    esql
    for complex queries with joins, transformations, or custom logic
  6. Inline Lens definitions — Prefer
    config.attributes
    over
    config.savedObjectId
    for portable dashboards
  7. Test connection first — Run
    node scripts/kibana-dashboards.js test
    before creating resources
  8. Get existing examples — Use
    lens get <id>
    to see the exact schema for different chart types
  9. Avoid redundant metric labels — For ES|QL metrics, avoid using both a panel title and an inner metric label, as it wastes space. Set the panel
    title
    to
    ""
    and configure the human-readable label by aliasing the ES|QL column name using backticks (e.g.,
    STATS `Total Requests` = COUNT()
    and
    "column": "Total Requests"
    ).
  1. 注重密度设计 — 运维仪表板必须在首屏(前24行)显示8-12个面板。使用紧凑的面板高度:指标图高度必须为
    h=4
    h=6
    ,图表高度必须为
    h=8
    h=12
  2. 切勿使用Markdown作为标题/页眉 — 不要添加
    DASHBOARD_MARKDOWN
    面板作为仪表板标题或分区分隔符,这会浪费宝贵的垂直空间。在图表本身使用描述性标题。
  3. 首屏优先展示关键内容 — 核心KPI和关键趋势必须放在
    y=0
    位置。深度分析内容和数据表应放在图表下方。
  4. 使用描述性图表标题 — 标题需清晰说明图表展示的内容(例如:"按产品分类的收入")。通过设置
    axis.x.title.visible: false
    隐藏轴标签以减少视觉干扰
  5. 选择合适的数据集类型 — 简单聚合使用
    dataView
    ,包含连接、转换或自定义逻辑的复杂查询使用
    esql
  6. 内联Lens定义 — 为实现可移植性,优先使用
    config.attributes
    而非
    config.savedObjectId
  7. 先测试连接 — 创建资源前运行
    node scripts/kibana-dashboards.js test
  8. 获取现有示例 — 使用
    lens get <id>
    查看不同图表类型的准确Schema
  9. 避免重复的指标标签 — 对于ES|QL指标,避免同时使用面板标题和内部指标标签,这会浪费空间。将面板
    title
    设置为
    ""
    ,并通过ES|QL列别名(例如:
    STATS `总请求数` = COUNT()
    "column": "总请求数"
    )配置易读的标签。

Schema Differences: dataView vs ES|QL

Schema差异:dataView vs ES|QL

AspectdataViewES|QL
Dataset
{ type: 'dataView', id: '...' }
{ type: 'esql', query: '...' }
Metric chart
metrics: [{ type: 'primary', operation: 'count' }]
metrics: [{ type: 'primary', operation: 'value', column: 'col' }]
XY columns
{ operation: 'terms', fields: ['host'], size: 10 }
{ operation: 'value', column: 'host' }
Static values
{ operation: 'static_value', value: 100 }
Use
EVAL
in query (see below)
XY datasetInside each layerInside each layer
Tagcloud
tag_by: { operation: 'terms', ... }
tag_by: { operation: 'value', column: '...' }
Datatable props
metrics
,
rows
arrays
metrics
,
rows
arrays with
{ operation: 'value', column: '...' }
Key Pattern: ES|QL always uses
{ operation: 'value', column: 'column_name' }
to reference columns from the query result. The aggregation happens in the ES|QL query itself.
方面dataViewES|QL
数据集
{ type: 'dataView', id: '...' }
{ type: 'esql', query: '...' }
指标图
metrics: [{ type: 'primary', operation: 'count' }]
metrics: [{ type: 'primary', operation: 'value', column: 'col' }]
XY列
{ operation: 'terms', fields: ['host'], size: 10 }
{ operation: 'value', column: 'host' }
静态值
{ operation: 'static_value', value: 100 }
在查询中使用
EVAL
(见下文)
XY数据集放在每个layer内部放在每个layer内部
标签云
tag_by: { operation: 'terms', ... }
tag_by: { operation: 'value', column: '...' }
数据表属性
metrics
,
rows
arrays
metrics
,
rows
数组配合
{ operation: 'value', column: '...' }
核心模式: ES|QL始终使用
{ operation: 'value', column: 'column_name' }
引用查询结果中的列。聚合逻辑在ES|QL查询语句中完成。

ES|QL: Time Bucketing

ES|QL:时间分桶

For time series charts, use the
BUCKET
function to create "auto" buckets that automatically scale with the time range. Always use
BUCKET(@timestamp, 75, ?_tstart, ?_tend)
instead of hardcoded intervals like
DATE_TRUNC(1 hour, @timestamp)
:
esql
FROM logs | STATS count = COUNT() BY bucket = BUCKET(@timestamp, 75, ?_tstart, ?_tend)
对于时间序列图表,使用
BUCKET
函数创建"自动"分桶,分桶会随时间范围自动调整。始终使用
BUCKET(@timestamp, 75, ?_tstart, ?_tend)
,而非硬编码间隔(如
DATE_TRUNC(1 hour, @timestamp)
):
esql
FROM logs | STATS count = COUNT() BY bucket = BUCKET(@timestamp, 75, ?_tstart, ?_tend)

ES|QL: Creating Static/Constant Values

ES|QL:创建静态/常量值

ES|QL does not support
static_value
operations. Instead, create constant columns using
EVAL
:
esql
FROM logs | STATS count = COUNT() | EVAL max_value = 20000, goal = 15000
Then reference with
{ "operation": "value", "column": "max_value" }
. For dynamic reference values, use aggregation functions like
PERCENTILE()
or
MAX()
in the query.
ES|QL不支持
static_value
操作。可使用
EVAL
创建常量列:
esql
FROM logs | STATS count = COUNT() | EVAL max_value = 20000, goal = 15000
然后使用
{ "operation": "value", "column": "max_value" }
引用。对于动态参考值,在查询中使用
PERCENTILE()
MAX()
等聚合函数。

Design Principles

设计原则

The APIs follow these principles:
  1. Minimal definitions — Only required properties; defaults are injected
  2. No implementation details — No internal state or machine IDs
  3. Flat structure — Shallow nesting for easy diffing
  4. Semantic names — Clear, readable property names
  5. Git-friendly — Easy to track changes in version control
  6. LLM-optimized — Compact format suitable for one-shot generation
这些API遵循以下原则:
  1. 极简定义 — 仅包含必填属性;默认值会自动注入
  2. 无实现细节 — 无内部状态或机器ID
  3. 扁平化结构 — 浅层级嵌套便于对比差异
  4. 语义化命名 — 清晰、易读的属性名称
  5. Git友好 — 便于在版本控制中追踪变更
  6. LLM优化 — 紧凑格式适配一次性生成