关于 dynatrace-kpi-dashboard-generator
dynatrace-kpi-dashboard-generator 是用于创建公司专属 Dynatrace Gen 3 KPI 仪表板和业务事件注入器的 Agent 技能。它涵盖调研、生成、使用 dtctl 部署及验证数据摄取,并要求写入前确认目标租户。
主要功能
- 01调研行业相关 KPI
- 02生成 Gen 3 仪表板 JSON
- 03创建 BizEvents 注入器
- 04向现有注入器工作流添加任务
- 05通过 dtctl 部署并验证摄取
- 06记录可复用的公司模式
适用场景
- 01为公司构建运营 KPI 仪表板
- 02生成仪表板所需的业务事件
- 03将仪表板和注入器更改部署到 Dynatrace
- 04记录公司专属 DQL 与设计模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sudosmitty/ dynatrace-kpi-dashboard-generator --skill dynatrace-kpi-dashboard-generator安装后在 Claude Code 中输入/dynatrace-kpi-dashboard-generator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
reference/example_dashboard.jsonexample_data_injector.workflow.jsonexample-injector.js详细介绍
Business Event Generator Agent
适用于在此仓库中运行的任何 Agent(Claude Code、GitHub Copilot、Cursor 等)的规范说明。Agent 的任务是:针对用户指定的任意公司,生成一个 Dynatrace Gen 3 KPI 仪表板和一个30 分钟 BizEvents 注入器,通过 dtctl 部署,并验证数据摄取情况。
角色与目标
你是一名 Dynatrace 解决方案工程师。针对指定公司:
- 调研与其业务相关的行业特定 KPI(15–20 项)。
- 构建一个Gen 3 仪表板,包含实时 KPI 磁贴、图表和必需的地图磁贴。
- 创建一个 JavaScript 注入器,每次运行 30 分钟,流式发送 3,000–5,000 个业务事件。
- 通过
dtctl将两者部署到 Dynatrace,向现有注入器工作流添加任务(绝不创建第二个注入器工作流)。 - 在公司文件夹中记录可复用的模式。
先决条件
- 已安装
dtctl,并已通过身份验证连接到 Dynatrace Gen 3 租户。使用dtctl auth whoami或scripts/check-prereqs.sh验证。如果缺少dtctl或未通过身份验证,请停止并告知用户——不要尝试安装或配置它。(macOS/Linux 用户可以运行scripts/install.sh;Windows 用户请按照 https://github.com/dynatrace-oss/dtctl#install 操作。) - 已安装
dtctlAgent 技能 (npx skills add dynatrace-oss/dtctl)——Agent 使用它来正确操作dtctl。 - 已安装
dynatrace-for-ai技能 (npx skills add dynatrace/dynatrace-for-ai)——提供dt-dql-essentials、dt-app-dashboards、dt-app-notebooks,以及 Agent 会用到的dt-obs-*领域技能。 - 用于操作工作流 JSON 的
jq。 - 可访问网络以获取公司徽标 URL。
确认租户——写入任何租户之前都必须执行
在 Agent 运行任何 dtctl apply、dtctl exec、dtctl create、
dtctl edit 或 dtctl delete 命令之前(即任何会修改租户或
执行工作流的操作),必须:
- 向用户显示当前活动上下文和身份,例如:
显示租户 URL / 环境、上下文名称和已通过身份验证的主体。dtctl ctx current dtctl auth whoami - 请用户确认这是正确的租户,然后再继续。
- 如果用户拒绝或表示租户不正确,请停止,并让用户切换上下文
(
dtctl context use <name>),然后再重新运行。
Agent 不得默认静默地操作当前活动上下文指向的租户。 每次调用都必须执行此检查,即使 Agent 在本次会话中先前已成功操作过同一租户。
Agent 收集的输入
调用时,Agent 会询问(或根据用户的请求推断):
- 公司名称(必填)——用于文件夹名称、仪表板标题和
event.provider(例如acme.event.provider)。 - 行业 / 业务领域(可选)——作为选择 KPI 的调研提示。
- 徽标 URL(可选)——如果未提供,请在网络上搜索公开的徽标 URL, 并在使用前与用户确认。
Logo URL — 嵌入前务必验证
在确认 URL 能向跨域浏览器提供图片之前,切勿嵌入徽标。运行:
curl -sIL -A 'Mozilla/5.0' -H 'Referer: https://apps.dynatrace.com' '<URL>' \
| grep -E '^(HTTP|content-type)'
要求:最终返回 HTTP/2 200,且 content-type: image/(png|svg+xml|jpeg|webp)。
如果响应为 400、403、404 或 text/html,徽标在 Markdown 磁贴中将显示为损坏的图片。
已知行为:
upload.wikimedia.org/wikipedia/commons/...— 文件经常会被重命名(例如,在哈希路径下,Walmart_logo.svg→Walmart logo (2008).svg)。非维基站点的来源通过普通热链接访问时,Varnish 会返回400。请通过 Commons API 获取当前 URL:https://commons.wikimedia.org/w/api.php?action=query&titles=File:<Name>.svg&prop=imageinfo&iiprop=url&format=json。1000logos.net和logos-world.net— 允许热链接,返回image/png。是知名品牌的可靠备用来源。- 企业
*.comCDN(例如i5.walmartimages.com、corporate.<brand>.com)— 通常不稳定;需要授权或会轮换。除非已验证,否则避免使用。
如果尝试 2–3 个候选 URL 后仍未找到可用链接,请向用户索要一个,不要猜测。
输出布局
为每家新公司在 dashboards/ 下创建一个文件夹:
dashboards/<Company>/
<company>-dashboard-v1.json # Gen 3 dashboard JSON
<company>-injector.js # 30-min BizEvents injector
README.md # overview, dashboard ID, workflow ID
LEARNINGS.md # iteration notes (DQL patterns, pitfalls)
SALES-PITCH.md # 1-page value pitch for sales teams
文件命名:公司 slug 使用小写字母,并以连字符分隔。版本化仪表板命名为 *-dashboard-v2.json — 切勿覆盖 v1。工作流内的任务名称与版本一致(例如 acme_v1、acme_v2)。
参考资源(生成前阅读)
reference/example_dashboard.json— Gen 3 仪表板 JSON 结构:磁贴、布局、变量、地图磁贴、分区分隔符、 类别覆盖。reference/example_data_injector.workflow.json— 工作流 + JS 任务结构(计划、所有者类型、操作类型、位置)。reference/example-injector.js— 真实的注入器 JS 模板:事件辅助函数、批量摄取、集群/区域权重、地理 坐标、架构约定。
Agent 必须遵循这些示例的结构。
阶段 1 — 规划与研究
确定主要业务流程(游戏、酒店、制造、销售、运营等)。对每个流程,定义:
- KPI(收入、利用率、满意度、响应时间等)。
- 与这些 KPI 对应的事件类型(交易、状态变更、服务请求、 遥测数据)。
- 每次运行的实际事件量目标(每 30 分钟运行一次,共 15–20 种事件类型,总计 3,000–5,000 个事件)。
阶段 2 — 仪表板设计(仅限 Gen 3)
页眉 — 必须采用拆分布局
两个并排的 Markdown 磁贴(不能合并为一个磁贴,也不能使用 HTML):
"0": # Logo tile
type: markdown
content: ""
layout: { x: 0, y: 0, w: 6, h: 2 }
"41": # Title tile
type: markdown
content: "# <Company> | Operations Dashboard\n\nReal-time KPI monitoring..."
layout: { x: 6, y: 0, w: 18, h: 2 }
Markdown 磁贴无法可靠地支持 <div>、<img> 或其他内联 HTML。请使用纯 Markdown 图片语法()。
分区分隔符
使用带有 data record(section="...") 的 singleValue 数据磁贴,高度为
h:1,宽度为 w:24,并为每个分区使用符合品牌风格的不同背景色。
建议配色(可根据公司品牌调整):
- 游戏:
#D4AF37(金色) - 酒店:
#1E90FF(蓝色) - 餐饮/F&B:
#FF6347(番茄红) - 宾客体验:
#9B59B6(紫色) - 运营/设施:
#34495E(石板灰) - 摘要/KPI:
#DAA520(暗金色)
分隔符示例:
{
"type": "data",
"title": "SECTION NAME",
"query": "data record(section=\"Name\")",
"visualization": "singleValue",
"visualizationSettings": {
"singleValue": {
"labelMode": "none",
"isIconVisible": true,
"prefixIcon": "GridIcon",
"colorThresholdTarget": "background"
},
"thresholds": [
{ "id": 1, "field": "section", "rules": [
{ "id": 1, "color": "#D4AF37", "comparator": "!=", "value": "1" }
]}
]
}
}
磁贴高度指南
| 高度 | 用途 | 示例 |
|---|---|---|
h:1 | 分区分隔符、信息较少的内容 | 分区标题 |
h:2 | 单值 KPI | 收入总额、入住率 %、计数 |
h:3 | 小型图表 | 2–3 类别的柱状图 |
h:4 | 标准图表(推荐) | 折线图、柱状图、面积图、环形图 |
h:5+ | 密集表格/多序列内容 | 汇总表、复杂分析 |
规则: 图表磁贴的高度至少为 h:4。h:2–h:3 会截断图例和
标签。
布局与间距
尽量减少垂直间隔,呈现专业外观:
- Y 轴增量:各行之间为
+1到+2个单位(不要使用+3+)。 - 模式:分隔符(
h:1)→ KPI 行(h:2)→ 图表行(h:4)→ 下一个 分隔符。 - X 列保持一致:
0, 6, 12, 18(画布宽度为 24)。 - 示例流程:
y:0 header (h:2) y:2 divider (h:1) y:3 KPI row (h:2) y:5 chart row (h:4) y:9 next divider (h:1)
地图图块 — 必需,且位于首屏
每个仪表板都必须包含最相关的地图图块,即 bubbleMap、
dotMap、connectionMap 或 chloropleth 图块,并使用会生成
geo.location.latitude 和 geo.location.longitude 的事件类型
(集群、区域、站点或门店)提供数据。注入器必须为至少一种事件类型填充这些字段。请参阅 example_dashboard.json 中的图块 30,了解结构。
将地图紧接在标题下方放置——全宽(w:24、
h:8),位于 y:2,且在执行摘要之前。地理背景信息应位于首屏内。插入地图时,将后续每个图块的 y 精确增加地图的高度;图块碰撞会导致布局悄然出错。
可视化类型多样性 — 必需组合
将圆环图和面积图堆在一起,视觉上会显得单调。请在整个仪表板中有意识地采用多种可视化类型:
pieChart— 小型分类占比(3–5 个切片)。donutChart— 同上,适合需要显示中心总计的场景。barChart(垂直、堆叠)— 随时间变化的分类数据。需要使用makeTimeseries ..., by:{<group>}, bins:N(参见阶段 3)。categoricalBar— 水平堆叠时间条形图;查询要求相同。honeycomb— 许多小类别(6 个以上);需要设置visualizationSettings.honeycomb.dataMappings.value = "<count_field>"。lineChart/areaChart— 单系列或多系列时间序列。table/dataPage— 原始行数据。bubbleMap/dotMap— 地理数据。singleValue— KPI。通过添加三个阈值colorRules,并将colorThresholdTarget: "background"和来自var(--dt-colors-charts-status-{success,warning,critical}-default, ...)的customColor用作仪表效果。比较符使用≥(Unicode),并按阈值从高到低排列。第 3 代没有单独的gauge可视化类型——这就是仪表。
将圆环图或饼图改为条形图、分类条形图或蜂巢图时,请移除
visualizationSettings.chartSettings.circleChartSettings。如果保留该设置,新图表将显示为空白。
阶段 3 — DQL 查询模式
始终按 event.provider == "<company>.event.provider" 进行筛选,并使用事件架构中的字段别名(snake_case)。
模式 → 可视化类型
| DQL 模式 | 可视化类型 | 使用场景 |
|---|---|---|
summarize <agg> | singleValue | 单个 KPI |
makeTimeseries <agg>, bins:N | lineChart、areaChart | 时间趋势 |
fetch ... | filter ... | fields ... | table、dataPage | 原始数据展示 |
summarize by:{field} | donutChart、pieChart、honeycomb | 纯分类细分(无时间轴) |
makeTimeseries by:{field}, bins:N | barChart、categoricalBar、堆叠 areaChart | 随时间变化的分类趋势 |
**重要:**第 3 代中的 barChart 和 categoricalBar 始终需要时间轴。第 3 代图表引擎要求 fieldMapping.timestamp = "timeframe",且结果中必须包含 timeframe 列;只有 makeTimeseries 会生成该列。将 summarize by:{} 的结果传给 barChart 会报错:“Time is required and there is no suitable
field.” 对于非时间类的分类可视化,请使用 donutChart、pieChart、
honeycomb 或 table。
barChart / categoricalBar 的 fieldMapping:
{ "timestamp": "timeframe",
"leftAxisValues": ["<value_field>"],
"leftAxisDimensions": ["<group_field>"] }
常见问题
❌ 错误 — 将 summarize 的结果传给 barChart / categoricalBar:
fetch bizevents | summarize revenue = sum(amount), by:{venue}
| visualization: barChart // "Time is required"
✅ 正确 — 任何条形图都应使用 makeTimeseries:
fetch bizevents | makeTimeseries revenue = sum(amount), by:{venue}, bins:20
| visualization: barChart
❌ 错误 — 将 avg(percentage_field) 用于比率指标:
| summarize conversion = avg(conversion_percent)
✅ 正确 — 使用 sum/sum 计算:
| summarize visitors = sum(visitors_count), txns = sum(transactions_count)
| fieldsAdd conversion = (toDouble(txns) / toDouble(visitors)) * 100
多选变量筛选器
将每个变量定义为 type: "query"、multiple: true,并通过
| dedup <field> 从公司的 event.provider 获取数据。
使用普通的 | filter in(<field>, $<Var>) 筛选图块——不要添加
array_size($Var) == 0 例外子句(它会破坏筛选器;默认全选已会返回所有行)。
规则:
- 在聚合管道之前插入筛选器(
makeTimeseries、summarize、fields*、sort、limit)。在makeTimeseries之后, 源字段已不存在,因此末尾添加| filter in(region, $Region)会静默丢弃所有行。 - 每个图块的字段可用性都很重要。计算图块引用的所有
event.type中可筛选字段的交集。仅注入所有引用类型都共有的字段筛选器。 事件之间没有共有可筛选维度的图块(分区标题、仅漏斗事件、 全局地图)无需添加变量筛选器。 - 变量因公司而异。选择 3–5 个符合运营模式的维度(例如
$Banner、$Region、$Department、$Channel、$Store)。避免超过约 5 个—— 否则筛选栏会显得拥挤。
DQL 最佳实践
- 始终按
event.provider筛选。 - 字段名称使用与注入器架构匹配的 snake_case。
- 测试时添加
| limit 10。 - 时间图表以及
barChart/categoricalBar使用makeTimeseries; 仅singleValue/donutChart/pieChart/honeycomb/table使用summarize。 - 比率指标 =
sum(num)/sum(denom)*100,绝不要使用avg(percent)。 - 将查询添加到仪表板 JSON 之前,先在 DQL 编辑器(或
dtctl query)中 测试。使用字面量array(...)替换$Var,以快速测试多选筛选器。
如果 Agent 运行时提供了 dt-app-dashboards、dt-dql-essentials、
dt-app-notebooks 和 dtctl 技能,请使用它们。
第 4 阶段 — 事件注入器 JavaScript
使用 reference/example-injector.js 和
example_data_injector.workflow.json 中的 script
字段作为结构模板。
要求
- **事件类型:**15–20 种不同类型
(
gaming.transaction、guest.checkin、equipment.telemetry等)。 - **字段架构:**所有字段均使用 snake_case
(
gaming_venue、occupancy_percent等)。 - **真实的值:**符合业务领域(价格使用货币单位,百分比为 0–100, 数值范围合理)。
- **事件量:**每次执行 3,000–5,000 个事件(每种事件类型约 100 个以上)。
- **地理字段:**至少一种事件类型会输出
geo.location.latitude/geo.location.longitude,供地图图块使用。 - 摄取端点:
/platform/classic/environment-api/v2/bizevents/ingest。 - **批处理:**每次 POST 发送 500 个事件,以确保低于约 5MB;非 2xx 响应时抛出错误。
- **身份验证:**集成式平台身份验证——无需令牌;工作流在 AutomationEngine 上下文中运行。
- 提供方:
EVENT_PROVIDER = "<company>.event.provider"。
阶段 5 — 仪表板实施检查清单
实施前:
- 仪表板标题清晰有意义(例如,
<Company> | Operations Dashboard)。 - 调研 15–20 个 KPI,并映射到事件类型。
- 绘制布局草图(分区、磁贴位置)。
- 收集 Logo URL,并确认有效,使用
curl -sIL验证(必须返回HTTP 200+content-type: image/*)。 - 根据品牌/主题选择 5–6 种分区颜色。
- 选择 3–5 个仪表板变量(多选、由查询驱动)。
查询验证:
- 在 DQL 编辑器中使用
| limit 10测试每个 DQL 查询。 - 聚合类型与可视化相匹配(
makeTimeseries与summarize)。 - 字段名称与注入器架构完全一致。
磁贴创建:
- Logo 磁贴(Markdown,
h:2,w:6)。 - 标题磁贴(Markdown,
h:2,w:18)。 - 地图磁贴放置在
y:2(执行摘要上方),w:24、h:8。 - 分区分隔条(
h:1,带颜色)。 - KPI 磁贴(
h:2,位于各分区下方);其中 3–4 个使用singleValue+ 阈值colorRules,营造仪表盘效果。 - 图表磁贴(
h:4+,位于 KPI 下方)。 - 可视化类型组合: 整个仪表板至少使用 4 种不同的图表类型(例如,
pieChart、barChart、categoricalBar、honeycomb、lineChart、areaChart);避免全部使用环形图。 - 所有
barChart/categoricalBar查询均使用makeTimeseries, 而非summarize by:{};fieldMapping包含timestamp:"timeframe"、leftAxisValues、leftAxisDimensions。 - 任何
honeycomb磁贴都设置visualizationSettings.honeycomb.dataMappings.value。 - 移除任何非圆形图表的
chartSettings.circleChartSettings。 - X 位置保持一致(
0, 6, 12, 18)。 - 尽量缩小 Y 方向间距(
+1至+2)。
样式与验证:
- 应用分区颜色。
- 图表
legend.ratio为 20–30。 - 为语义颜色设置
categoryOverrides。 - 预览中没有红色 X 磁贴。
- Logo 和地图磁贴均正确呈现。
阶段 6 — 工作流与部署(关键规则)
同一租户中的所有公司共用注入器工作流。每个租户恰好有一个注入器工作流;新公司作为额外任务添加到该工作流中。
分步操作
-
应用仪表板:
dtctl apply -f "dashboards/<Company>/<company>-dashboard-v1.json"记录返回的仪表板 ID。
封装结构(必需):
dtctl apply需要一个包装对象:{ "id": "<uuid?>", "name": "<Company> | Operations Dashboard", "type": "dashboard", "isPrivate": false, "content": { "tiles": {...}, "layouts": {...}, "variables": [...], "settings": {...}, "version": 21, ... } }仅提交
content正文会导入磁贴,但会创建一个名称和 ID 脱离的“Untitled dashboard”。使用包装对象重新应用即可原位修复(ACTION = updated)。 -
首先搜索现有注入器工作流:
dtctl get workflows -o json --plain | \ jq '.[] | select(.title | test("BizEvents Dashboard Generator|KPI Data Injector|injector"; "i"))'优先选择标题为
1.BizEvents Dashboard Generator的工作流。如果匹配多个,请向用户确认。 -
如果工作流已存在(通常情况):
dtctl get workflow <id> -o json --plain > .tmp/workflow.json- 添加一个以
<company>_v1(迭代时使用_v2)为键的新任务。 - 使用唯一的
position.{x, y},重复会导致 400 错误。 - 设置
predecessors: [],使任务并行运行。 dtctl apply -f .tmp/workflow.json
-
如果工作流不存在(仅限全新租户的首次运行):
- 使用
reference/example_data_injector.workflow.json作为模板。 - 将其中的单个任务替换为新公司的任务;将工作流重命名为
1.BizEvents Dashboard Generator。 - 执行
dtctl apply -f;记录工作流 ID。
- 使用
-
执行并验证:
dtctl exec workflow <id> dtctl describe workflow-execution <exec-id> # wait for SUCCESSdescribe workflow-execution会返回一个空的tasks{}字典。要检查 JS 任务的返回值(总数、批次、错误),请使用:dtctl get wfe-task-result <exec-id> -t <taskName>必须通过
-t/--task标志指定任务名称,不能将其作为位置参数。 -
验证数据摄取:
fetch bizevents | filter event.provider == "<company>.event.provider" | summarize total = count()
如果已有注入器工作流,绝不要创建第二个。
版本管理
- 首次迭代:
<company>-dashboard-v1.json,任务<company>_v1。 - 更新:
<company>-dashboard-v2.json,任务<company>_v2。 - 绝不要覆盖 v1 文件。
第 7 阶段 — 文档交付物
为每个项目在公司文件夹中编写以下文档:
README.md— 项目概览、文件列表、仪表板 ID、工作流 ID、 任务名称、部署命令。LEARNINGS.md— DQL 模式、布局决策、易踩的坑、配色方案,以及 任何可复用于下一个项目的内容。SALES-PITCH.md— 为公司量身打造的 1 页价值主张,供销售团队使用。
LEARNINGS.md 模板:
# <Company> Dashboard Learnings
**Date:** <date>
**Version:** v1
## DQL Patterns Used
| Tile Type | DQL Pattern | Notes |
|-----------|-------------|-------|
## Layout Decisions
- Header, dividers, KPI rows, chart rows...
## Pitfalls Hit
1. ...
## Color Scheme
- Section: `#hex`
第 8 阶段 — 质量门禁(宣布完成前运行)
- Logo 正常显示。
- 所有分区分隔线都显示正确的颜色。
- 没有红色 X 磁贴。
- 每个 KPI 磁贴都有数据。
- 每个图表都显示图例/标签。
- 地图磁贴已填充集群/区域/站点坐标。
- 布局紧凑(没有过多空白)。
- 工作流执行已成功完成。
- 每次运行已摄取 3,000+ 个事件。
-
README.md、LEARNINGS.md、SALES-PITCH.md均已提供。
核心原则
- Markdown 格式至关重要 — 仅使用纯 Markdown,不使用 HTML。
- Logo = 专业质感 — 每个仪表板都应带有品牌标识。
- 图表需要空间 — 最小高度为
h:4。 - 部署前先测试 — 先在编辑器中测试 DQL。
- 记录一切 —
LEARNINGS.md是知识资产。 - 保持一致才能保证质量 — 严格遵循示例的结构。
- 每个租户使用一个注入器工作流 — 始终添加任务,不要重复创建。
Agent 不得执行的操作
- 不要臆造仪表板 ID、工作流 ID 或 URL — 始终使用
dtctl返回的值。 - 如果已有注入器工作流,不要再创建第二个。
- 不要跳过地图磁贴。
- 除非有人要求,否则不要推送提交或创建 PR。
- 未经用户明确确认,不要运行具有破坏性的
dtctl delete命令。 - 不要尝试安装或配置
dtctl。