@cloudcare/guance-front-tools 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/guance-all-charts.json +3415 -0
- package/lib/cjs/generated/dashboardCharts.d.ts +54 -13
- package/lib/cjs/scripts/grafana-covert-to-guance-core.d.ts +4 -0
- package/lib/cjs/scripts/grafana-covert-to-guance-core.js +10 -0
- package/lib/cjs/scripts/grafana-dashbord.d.ts +2220 -0
- package/lib/cjs/scripts/grafana-dashbord.js +4 -0
- package/lib/cjs/src/grafana-covert-to-guance.d.ts +2 -0
- package/lib/cjs/src/grafana-covert-to-guance.js +5 -0
- package/lib/cjs/src/index.d.ts +1 -0
- package/lib/cjs/src/index.js +1 -0
- package/lib/esm/generated/dashboardCharts.d.ts +54 -13
- package/lib/esm/scripts/grafana-covert-to-guance-core.d.ts +4 -0
- package/lib/esm/scripts/grafana-covert-to-guance-core.js +7 -0
- package/lib/esm/scripts/grafana-dashbord.d.ts +2220 -0
- package/lib/esm/scripts/grafana-dashbord.js +1 -0
- package/lib/esm/src/grafana-covert-to-guance.d.ts +2 -0
- package/lib/esm/src/grafana-covert-to-guance.js +1 -0
- package/lib/esm/src/index.d.ts +1 -0
- package/lib/esm/src/index.js +1 -0
- package/lib/example/grafana2.json +878 -0
- package/lib/example/guance-dahs-3.json +348 -0
- package/lib/scripts/grafana-covert-to-guance-core.js +7 -0
- package/lib/scripts/grafana-covert-to-guance-core.ts +23 -0
- package/lib/scripts/grafana-covert-to-guance.js +52 -397
- package/lib/scripts/grafana-covert-to-guance.ts +58 -410
- package/lib/src/grafana-covert-to-guance.ts +7 -0
- package/lib/src/index.ts +1 -0
- package/package.json +6 -4
- package/schemas/charts/chart-schema.json +8 -5
- package/schemas/charts/common/chart-link-item-schema.json +48 -0
- package/schemas/charts/common/chart-links-schema.json +9 -0
- package/schemas/charts/common/common-chart-types-schema.json +3 -1
- package/schemas/charts/dashboard-schema.json +11 -4
- package/schemas/charts/query/query-item-schema.json +19 -1
- package/schemas/charts/settings/settings-time-schema.json +1 -5
- package/schemas/charts/settings/settings-unit-items-schema.json +3 -1
- package/schemas/charts/settings/settings-units-schema.json +2 -3
- package/scripts/validate-file.mjs +57 -0
- package/skills/grafana-to-guance-dashboard/SKILL.md +102 -0
- package/skills/grafana-to-guance-dashboard/agents/openai.yaml +4 -0
- package/skills/grafana-to-guance-dashboard/references/converter-notes.md +134 -0
- package/skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs +1899 -0
- package/test/cli.test.mjs +373 -0
- package/test-output/grafana2.cli.guance.json +1029 -0
- package/test-output/grafana2.guance.json +1029 -0
- package/test-output/grafana2.keep-meta.guance.json +1384 -0
- package/test-output/pod.guance.json +2153 -0
- package/test-output/skill-test2-enhanced.guance.json +21596 -0
- package/test-output/skill-test2-validated.guance.json +11610 -0
- package/test-output/skill-test2.guance.json +11610 -0
- package/test-output/test.guance.json +1086 -0
- package/test-output/test2.guance.guance-promql.json +23212 -0
- package/test-output/test2.guance.json +17554 -0
|
@@ -31,12 +31,30 @@
|
|
|
31
31
|
"type": "string",
|
|
32
32
|
"description": "图表查询语句,可以是 dql语句,也可以是 promql 语句"
|
|
33
33
|
},
|
|
34
|
+
"content": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "文本图内容,支持 HTML 或 Markdown 文本"
|
|
37
|
+
},
|
|
34
38
|
"code": {
|
|
35
39
|
"type": "string",
|
|
36
40
|
"description": "查询语句的唯一标识,由单个大写英文字母构成"
|
|
41
|
+
},
|
|
42
|
+
"type": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"description": "查询语句类型冗余字段,实际数据中可能是 promql/dql,也可能是 default/simple 这类查询模式",
|
|
45
|
+
"enum": [
|
|
46
|
+
"default",
|
|
47
|
+
"simple",
|
|
48
|
+
"dql",
|
|
49
|
+
"promql"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"promqlCode": {
|
|
53
|
+
"type": "integer",
|
|
54
|
+
"description": "PromQL 查询顺序编号"
|
|
37
55
|
}
|
|
38
56
|
}
|
|
39
57
|
}
|
|
40
58
|
},
|
|
41
59
|
"additionalProperties": true
|
|
42
|
-
}
|
|
60
|
+
}
|
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
"title": "ChartTimeSettings",
|
|
5
5
|
"description": "图表时间相关配置完整结构。",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": [
|
|
8
|
-
"timeInterval",
|
|
9
|
-
"fixedTime"
|
|
10
|
-
],
|
|
11
7
|
"properties": {
|
|
12
8
|
"timeInterval": {
|
|
13
9
|
"type": "string",
|
|
@@ -44,4 +40,4 @@
|
|
|
44
40
|
"$ref": "settings-fixed-time-schema.json"
|
|
45
41
|
}
|
|
46
42
|
}
|
|
47
|
-
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import Ajv from 'ajv'
|
|
2
|
+
import { readdirSync, readFileSync } from 'fs'
|
|
3
|
+
|
|
4
|
+
const SCHEMAS_DIRECTORY = './schemas'
|
|
5
|
+
|
|
6
|
+
const args = process.argv.slice(2)
|
|
7
|
+
const schemaFlagIndex = args.indexOf('--schema')
|
|
8
|
+
const schemaId = schemaFlagIndex >= 0 ? args[schemaFlagIndex + 1] : 'dashboard-schema.json'
|
|
9
|
+
const jsonPaths =
|
|
10
|
+
schemaFlagIndex >= 0 ? args.filter((_, index) => index !== schemaFlagIndex && index !== schemaFlagIndex + 1) : args
|
|
11
|
+
|
|
12
|
+
if (jsonPaths.length === 0) {
|
|
13
|
+
console.error('Usage: node scripts/validate-file.mjs <json-path...> [--schema <schema-id>]')
|
|
14
|
+
process.exit(1)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const ajv = new Ajv({ allErrors: true })
|
|
18
|
+
|
|
19
|
+
forEachFile(SCHEMAS_DIRECTORY, (schemaPath) => {
|
|
20
|
+
if (!schemaPath.endsWith('.json')) return
|
|
21
|
+
ajv.addSchema(readJson(schemaPath))
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
let hasError = false
|
|
25
|
+
|
|
26
|
+
for (const jsonPath of jsonPaths) {
|
|
27
|
+
const valid = ajv.validate(schemaId, readJson(jsonPath))
|
|
28
|
+
|
|
29
|
+
if (valid) {
|
|
30
|
+
console.log(`✅ ${jsonPath} is valid against ${schemaId}`)
|
|
31
|
+
continue
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
hasError = true
|
|
35
|
+
console.log(`❌ ${jsonPath} is not valid against ${schemaId}:`)
|
|
36
|
+
for (const error of ajv.errors || []) {
|
|
37
|
+
const instancePath = error.instancePath || '/'
|
|
38
|
+
console.log(`- ${instancePath} ${error.message}`)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
process.exit(hasError ? 1 : 0)
|
|
43
|
+
|
|
44
|
+
function forEachFile(directoryPath, callback) {
|
|
45
|
+
for (const entry of readdirSync(directoryPath, { withFileTypes: true })) {
|
|
46
|
+
const entryPath = `${directoryPath}/${entry.name}`
|
|
47
|
+
if (entry.isFile()) {
|
|
48
|
+
callback(entryPath)
|
|
49
|
+
} else {
|
|
50
|
+
forEachFile(entryPath, callback)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function readJson(filePath) {
|
|
56
|
+
return JSON.parse(readFileSync(filePath, 'utf8'))
|
|
57
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grafana-to-guance-dashboard
|
|
3
|
+
description: Convert Grafana dashboard JSON into Guance dashboard JSON in this repository. Use when the user wants to convert a Grafana dashboard file, adjust mapping logic for panels or variables, preserve settings, groups, and vars as much as possible, validate generated Guance dashboard JSON against local schemas, or debug why a Grafana dashboard does not convert cleanly.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Grafana To Guance Dashboard
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Use this skill when working on Grafana dashboard to Guance dashboard conversion in this repository.
|
|
11
|
+
|
|
12
|
+
This skill ships its own standalone converter script under `skills/grafana-to-guance-dashboard/scripts/`. Use that script first. Only inspect the older repository converter when the user explicitly wants comparison or historical behavior.
|
|
13
|
+
|
|
14
|
+
## Core Workflow
|
|
15
|
+
|
|
16
|
+
1. Identify the input Grafana dashboard and output path.
|
|
17
|
+
2. Run the standalone skill script.
|
|
18
|
+
3. Validate the generated Guance dashboard against local schemas.
|
|
19
|
+
4. If conversion gaps remain, patch the standalone skill script and re-run validation.
|
|
20
|
+
5. Only inspect the older repository converter if the user asks to compare outputs.
|
|
21
|
+
|
|
22
|
+
## Commands
|
|
23
|
+
|
|
24
|
+
Use this command from the repository root.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Convert a Grafana dashboard JSON to Guance JSON
|
|
28
|
+
node skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs \
|
|
29
|
+
--input path/to/grafana-dashboard.json \
|
|
30
|
+
--output path/to/guance-dashboard.json \
|
|
31
|
+
--validate
|
|
32
|
+
|
|
33
|
+
# Convert and normalize PromQL metric names toward Guance measurement:field style
|
|
34
|
+
node skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs \
|
|
35
|
+
--input path/to/grafana-dashboard.json \
|
|
36
|
+
--output path/to/guance-dashboard.guance-promql.json \
|
|
37
|
+
--validate \
|
|
38
|
+
--guance-promql-compatible
|
|
39
|
+
|
|
40
|
+
# Convert and keep original Grafana metadata under extend.grafana for debugging
|
|
41
|
+
node skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs \
|
|
42
|
+
--input path/to/grafana-dashboard.json \
|
|
43
|
+
--output path/to/guance-dashboard.keep-meta.json \
|
|
44
|
+
--validate \
|
|
45
|
+
--keep-grafana-meta
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## What The Standalone Skill Converter Supports
|
|
49
|
+
|
|
50
|
+
- Grafana variables of type `query`, `custom`, `textbox`, `constant`, `interval`, and `datasource`
|
|
51
|
+
- Grafana row panels mapped to Guance groups
|
|
52
|
+
- Row collapse state mapped to `dashboardExtend.groupUnfoldStatus`
|
|
53
|
+
- Panel links gathered from panel links, default links, and override links
|
|
54
|
+
- Common panel types:
|
|
55
|
+
- `stat`, `singlestat` -> `singlestat`
|
|
56
|
+
- `timeseries`, `graph` -> `sequence`
|
|
57
|
+
- `barchart` -> `bar`
|
|
58
|
+
- `piechart` -> `pie`
|
|
59
|
+
- `histogram` -> `histogram`
|
|
60
|
+
- `bargauge` -> `toplist`
|
|
61
|
+
- `gauge` -> `gauge`
|
|
62
|
+
- `table` -> `table`
|
|
63
|
+
- `text` -> `text`
|
|
64
|
+
- `heatmap` -> `heatmap`
|
|
65
|
+
- `treemap` -> `treemap`
|
|
66
|
+
- Query extraction from Grafana `targets[]` using `expr`, `query`, or `queryText`
|
|
67
|
+
- Datasource-aware query classification for Prometheus-like and SQL-like targets
|
|
68
|
+
- `guance-guance-datasource` targets default to `dql`, but explicit `qtype: "promql"` is preserved as `promql`
|
|
69
|
+
- Optional `--guance-promql-compatible` mode to rewrite PromQL metric selectors from `metric_name` toward Guance `measurement:field` style
|
|
70
|
+
- Default output omits raw `extend.grafana` metadata; pass `--keep-grafana-meta` only when debugging conversion fidelity
|
|
71
|
+
- Variable replacement from Grafana `$var` / `${var}` to Guance `#{var}`
|
|
72
|
+
- Settings extraction from both newer `fieldConfig` / `options` panels and older Grafana `graph` / `singlestat` fields
|
|
73
|
+
- Settings mapping for thresholds, value mappings, legend, units, decimals, min, max, stack mode, null handling, panel links, and common chart display settings
|
|
74
|
+
- Transformation-aware table mapping for `organize`, `filterFieldsByName`, and `filterByValue`
|
|
75
|
+
- Extra appearance metadata preserved under `extend.grafana` and `settings.extend.appearance`, including line width, fill opacity, point mode, stat text/color mode, reduce calcs, and gauge display hints
|
|
76
|
+
|
|
77
|
+
## Known Limits
|
|
78
|
+
|
|
79
|
+
- The converter is still Prometheus/PromQL-oriented for query extraction.
|
|
80
|
+
- Plugin-specific Grafana options are converted heuristically, not losslessly.
|
|
81
|
+
- Unsupported panel types are filtered out unless the mapping table is extended.
|
|
82
|
+
- Complex transformations and non-standard datasource payloads may still need manual cleanup.
|
|
83
|
+
|
|
84
|
+
When conversion fails or output is incomplete, read [references/converter-notes.md](references/converter-notes.md).
|
|
85
|
+
|
|
86
|
+
## Editing Rules
|
|
87
|
+
|
|
88
|
+
- Prefer patching `skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs` for conversion behavior.
|
|
89
|
+
- Only change schemas when the generated Guance JSON is valid real data but the schema is too strict.
|
|
90
|
+
- Keep validation green:
|
|
91
|
+
- `npm run validate`
|
|
92
|
+
- `npm run validate:dashboard`
|
|
93
|
+
- When adding support for a new Grafana panel type, update the standalone script's panel type map first, then validate an example dashboard.
|
|
94
|
+
|
|
95
|
+
## Typical Requests This Skill Should Handle
|
|
96
|
+
|
|
97
|
+
- "Convert this Grafana dashboard JSON to Guance format."
|
|
98
|
+
- "Why did this Grafana panel disappear after conversion?"
|
|
99
|
+
- "Add support for Grafana panel type `xyz`."
|
|
100
|
+
- "Map Grafana variables into Guance vars correctly."
|
|
101
|
+
- "Validate the converted Guance dashboard against the local schema."
|
|
102
|
+
- "Compare a Grafana dashboard and generated Guance dashboard to find missing panels."
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Converter Notes
|
|
2
|
+
|
|
3
|
+
## Skill Files
|
|
4
|
+
|
|
5
|
+
- `skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs`: standalone converter shipped by this skill
|
|
6
|
+
- `schemas/dashboard-schema.json`: Guance dashboard schema entrypoint
|
|
7
|
+
|
|
8
|
+
## Current Mapping Notes
|
|
9
|
+
|
|
10
|
+
### Variables
|
|
11
|
+
|
|
12
|
+
- Supported Grafana variable types:
|
|
13
|
+
- `query`
|
|
14
|
+
- `custom`
|
|
15
|
+
- Variable mapping:
|
|
16
|
+
- `query` -> `PROMQL_QUERY`
|
|
17
|
+
- `custom` -> `CUSTOM_LIST`
|
|
18
|
+
|
|
19
|
+
Additional Grafana variable types such as `textbox`, `constant`, `interval`, and `datasource` are converted into Guance custom-list style variables by the standalone script.
|
|
20
|
+
|
|
21
|
+
The standalone script also preserves extra variable metadata such as `refresh`, `skipUrlSync`, `sort`, `description`, and raw option lists under `var.extend`.
|
|
22
|
+
|
|
23
|
+
### Panels
|
|
24
|
+
|
|
25
|
+
Panel type mapping currently lives in `convert-grafana-dashboard.mjs`.
|
|
26
|
+
|
|
27
|
+
If a Grafana panel type is missing, the panel is filtered out before conversion. Add the panel type to the standalone script map before debugging deeper.
|
|
28
|
+
|
|
29
|
+
By default, the converter does not emit raw `extend.grafana` metadata in the generated Guance dashboard. Use `--keep-grafana-meta` only when you need source-level debugging context.
|
|
30
|
+
|
|
31
|
+
### Queries
|
|
32
|
+
|
|
33
|
+
The converter pulls query text from the first defined field among:
|
|
34
|
+
|
|
35
|
+
1. `target.expr`
|
|
36
|
+
2. `target.query`
|
|
37
|
+
3. `target.queryText`
|
|
38
|
+
4. `target.expression`
|
|
39
|
+
5. `target.rawSql`
|
|
40
|
+
|
|
41
|
+
Generated Guance queries default to PromQL-style output unless the query looks like DQL:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"datasource": "dataflux",
|
|
46
|
+
"qtype": "promql",
|
|
47
|
+
"type": "sequence",
|
|
48
|
+
"query": {
|
|
49
|
+
"q": "...",
|
|
50
|
+
"type": "promql",
|
|
51
|
+
"code": "a",
|
|
52
|
+
"promqlCode": 1
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Variable replacement is intentionally conservative:
|
|
58
|
+
|
|
59
|
+
- only known Grafana dashboard variables are rewritten from `$var` / `${var}` to `#{var}`
|
|
60
|
+
- Grafana built-ins such as `${__from}` and `${__to}` are preserved
|
|
61
|
+
- unknown template expressions such as JavaScript local variables in text panels stay unchanged, for example `${hotcall}`
|
|
62
|
+
|
|
63
|
+
Query classification is datasource-aware:
|
|
64
|
+
|
|
65
|
+
- Prometheus-like datasources stay `promql`
|
|
66
|
+
- SQL-like datasources such as MySQL/Postgres/MSSQL are emitted as `dql`
|
|
67
|
+
- `guance-guance-datasource` defaults to `dql`
|
|
68
|
+
- if a `guance-guance-datasource` target explicitly sets `qtype: "promql"`, that explicit PromQL mode wins
|
|
69
|
+
- the generated `query.type` now follows the same classification instead of falling back to `simple`
|
|
70
|
+
|
|
71
|
+
Guance PromQL compatibility mode:
|
|
72
|
+
|
|
73
|
+
- pass `--guance-promql-compatible` to rewrite PromQL metric selectors from `metric_name` to `measurement:field`
|
|
74
|
+
- the rewrite is conservative and only applies to metric selector tokens outside label braces
|
|
75
|
+
- label keys such as `app_name` and grouping keys such as `by (app_name)` are preserved
|
|
76
|
+
- keep this mode opt-in, because some dashboards may already target Guance-native metric names
|
|
77
|
+
|
|
78
|
+
### Layout
|
|
79
|
+
|
|
80
|
+
Grafana `gridPos` is not copied directly.
|
|
81
|
+
|
|
82
|
+
- `x` and `w` are kept close to Grafana values
|
|
83
|
+
- `y` and `h` are scaled into a Guance-friendly layout ratio
|
|
84
|
+
|
|
85
|
+
If the final dashboard looks vertically misaligned, inspect the layout conversion helpers first.
|
|
86
|
+
|
|
87
|
+
## Debug Checklist
|
|
88
|
+
|
|
89
|
+
When output is wrong:
|
|
90
|
+
|
|
91
|
+
1. Confirm the panel type is in the standalone script panel map.
|
|
92
|
+
2. Confirm the panel has `gridPos`.
|
|
93
|
+
3. Confirm the panel has usable `targets`.
|
|
94
|
+
4. Check whether the query lives in `expr`, `query`, or `queryText`.
|
|
95
|
+
5. Check whether row panels are collapsed, because collapsed and expanded rows are handled differently.
|
|
96
|
+
6. Validate the generated JSON with:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
node scripts/validate-file.mjs path/to/output.json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Settings Conversion
|
|
103
|
+
|
|
104
|
+
The standalone script attempts to convert:
|
|
105
|
+
|
|
106
|
+
- thresholds -> Guance `levels`
|
|
107
|
+
- Grafana value maps and range maps -> Guance `mappings`
|
|
108
|
+
- table override mappings -> Guance `valMappings`
|
|
109
|
+
- legend placement and legend values, including older Grafana `legend.current/avg/min/max/total`
|
|
110
|
+
- units, decimals, min, max from both newer and older Grafana panel formats
|
|
111
|
+
- stacking and connect-nulls behavior from both newer and older Grafana panel formats
|
|
112
|
+
- table column organize / rename / exclude / order transformations
|
|
113
|
+
- panel links and field links into `extend.links`
|
|
114
|
+
- appearance metadata into `settings.extend.appearance`, including:
|
|
115
|
+
- `lineWidth`
|
|
116
|
+
- `fillOpacity`
|
|
117
|
+
- `pointMode`
|
|
118
|
+
- `graphMode`
|
|
119
|
+
- `colorMode`
|
|
120
|
+
- `textMode`
|
|
121
|
+
- `reduceCalcs`
|
|
122
|
+
- `gaugeMode`
|
|
123
|
+
|
|
124
|
+
This is heuristic conversion. For plugin-specific panels, validate the generated JSON and then refine the script with a real sample.
|
|
125
|
+
|
|
126
|
+
## Safe Extension Pattern
|
|
127
|
+
|
|
128
|
+
When adding support for a new panel type:
|
|
129
|
+
|
|
130
|
+
1. Add the Grafana panel type to the standalone script panel map.
|
|
131
|
+
2. Decide the Guance chart type target.
|
|
132
|
+
3. Add any special-case settings generation in the standalone script.
|
|
133
|
+
4. Convert a real dashboard containing that panel.
|
|
134
|
+
5. Run `npm run validate`.
|