@cloudcare/guance-front-tools 1.0.12 → 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.
Files changed (39) hide show
  1. package/guance-all-charts.json +3415 -0
  2. package/lib/cjs/generated/dashboardCharts.d.ts +54 -13
  3. package/lib/cjs/scripts/grafana-covert-to-guance-core.d.ts +1 -1
  4. package/lib/cjs/scripts/grafana-covert-to-guance-core.js +5 -289
  5. package/lib/esm/generated/dashboardCharts.d.ts +54 -13
  6. package/lib/esm/scripts/grafana-covert-to-guance-core.d.ts +1 -1
  7. package/lib/esm/scripts/grafana-covert-to-guance-core.js +5 -289
  8. package/lib/example/grafana2.json +878 -0
  9. package/lib/example/guance-dahs-3.json +348 -0
  10. package/lib/scripts/grafana-covert-to-guance-core.js +5 -286
  11. package/lib/scripts/grafana-covert-to-guance-core.ts +12 -326
  12. package/lib/scripts/grafana-covert-to-guance.js +52 -29
  13. package/lib/scripts/grafana-covert-to-guance.ts +60 -32
  14. package/package.json +4 -3
  15. package/schemas/charts/chart-schema.json +8 -5
  16. package/schemas/charts/common/chart-link-item-schema.json +48 -0
  17. package/schemas/charts/common/chart-links-schema.json +9 -0
  18. package/schemas/charts/common/common-chart-types-schema.json +3 -1
  19. package/schemas/charts/dashboard-schema.json +11 -4
  20. package/schemas/charts/query/query-item-schema.json +19 -1
  21. package/schemas/charts/settings/settings-time-schema.json +1 -5
  22. package/schemas/charts/settings/settings-unit-items-schema.json +3 -1
  23. package/schemas/charts/settings/settings-units-schema.json +2 -3
  24. package/scripts/validate-file.mjs +57 -0
  25. package/skills/grafana-to-guance-dashboard/SKILL.md +102 -0
  26. package/skills/grafana-to-guance-dashboard/agents/openai.yaml +4 -0
  27. package/skills/grafana-to-guance-dashboard/references/converter-notes.md +134 -0
  28. package/skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs +1899 -0
  29. package/test/cli.test.mjs +316 -0
  30. package/test-output/grafana2.cli.guance.json +1029 -0
  31. package/test-output/grafana2.guance.json +1029 -0
  32. package/test-output/grafana2.keep-meta.guance.json +1384 -0
  33. package/test-output/pod.guance.json +2153 -0
  34. package/test-output/skill-test2-enhanced.guance.json +21596 -0
  35. package/test-output/skill-test2-validated.guance.json +11610 -0
  36. package/test-output/skill-test2.guance.json +11610 -0
  37. package/test-output/test.guance.json +1086 -0
  38. package/test-output/test2.guance.guance-promql.json +23212 -0
  39. package/test-output/test2.guance.json +17554 -0
@@ -0,0 +1,348 @@
1
+ {
2
+ "title": "test-dcl-23-copy",
3
+ "dashboardType": "CUSTOM",
4
+ "dashboardExtend": {
5
+ "groupUnfoldStatus": {
6
+ "test1": false
7
+ }
8
+ },
9
+ "dashboardMapping": [],
10
+ "dashboardOwnerType": "node",
11
+ "iconSet": {},
12
+ "dashboardBindSet": [],
13
+ "thumbnail": "",
14
+ "tagInfo": [],
15
+ "summary": "1",
16
+ "main": {
17
+ "vars": [
18
+ {
19
+ "name": "host",
20
+ "seq": 0,
21
+ "datasource": "dataflux",
22
+ "code": "host",
23
+ "type": "QUERY",
24
+ "definition": {
25
+ "tag": "",
26
+ "field": "",
27
+ "value": "L('default')::RE(`.*`):(distinct_by_collapse(`host`)) LIMIT 20",
28
+ "metric": "",
29
+ "object": "",
30
+ "defaultVal": {
31
+ "label": "*",
32
+ "value": "*"
33
+ }
34
+ },
35
+ "valueSort": "asc",
36
+ "hide": 0,
37
+ "isHiddenAsterisk": 0,
38
+ "multiple": true,
39
+ "includeStar": true,
40
+ "extend": {
41
+ "starMeaning": "*"
42
+ }
43
+ },
44
+ {
45
+ "name": "test_host_link",
46
+ "seq": 1,
47
+ "datasource": "dataflux",
48
+ "code": "test",
49
+ "type": "QUERY",
50
+ "definition": {
51
+ "tag": "",
52
+ "field": "",
53
+ "value": "L('default')::RE(`.*`):(`service`) { host = '#{host}' }",
54
+ "metric": "",
55
+ "object": "",
56
+ "defaultVal": {
57
+ "label": "",
58
+ "value": ""
59
+ }
60
+ },
61
+ "valueSort": "asc",
62
+ "hide": 0,
63
+ "isHiddenAsterisk": 0,
64
+ "multiple": true,
65
+ "includeStar": false,
66
+ "extend": {}
67
+ }
68
+ ],
69
+ "charts": [
70
+ {
71
+ "extend": {
72
+ "links": [
73
+ {
74
+ "url": "/logIndi/log/all?time=#{TR}&query=#{T}",
75
+ "open": "newWin",
76
+ "show": true,
77
+ "type": "logging",
78
+ "showChanged": false
79
+ },
80
+ {
81
+ "url": "/objectadmin/docker_containers?routerTabActive=ObjectadminDocker&time=#{TR}&query=#{T}",
82
+ "open": "curWin",
83
+ "show": true,
84
+ "type": "container",
85
+ "showChanged": false
86
+ },
87
+ {
88
+ "url": "/objectadmin/host_processes?routerTabActive=ObjectadminProcesses&time=#{TR}&query=#{T}",
89
+ "open": "drawerWin",
90
+ "show": true,
91
+ "type": "processes",
92
+ "showChanged": false
93
+ },
94
+ {
95
+ "url": "/tracing/link/all?time=#{TR}&query=#{T}",
96
+ "open": "newWin",
97
+ "show": false,
98
+ "type": "tracing",
99
+ "showChanged": false
100
+ },
101
+ {
102
+ "url": "/scene/builtinview/detail?time=#{TR}&query=#{T}",
103
+ "open": "newWin",
104
+ "show": false,
105
+ "type": "host",
106
+ "showChanged": false
107
+ }
108
+ ],
109
+ "settings": {
110
+ "alias": [],
111
+ "units": [],
112
+ "colors": [],
113
+ "levels": [],
114
+ "slimit": 20,
115
+ "compares": [
116
+ {
117
+ "label": "小时同比",
118
+ "value": "hourCompare"
119
+ },
120
+ {
121
+ "label": "日同比",
122
+ "value": "dayCompare"
123
+ }
124
+ ],
125
+ "lineType": "linear",
126
+ "showLine": false,
127
+ "unitType": "global",
128
+ "chartType": "line",
129
+ "fixedTime": "",
130
+ "isPercent": false,
131
+ "openStack": false,
132
+ "precision": "2",
133
+ "showLabel": false,
134
+ "showTitle": true,
135
+ "stackType": "percent",
136
+ "titleDesc": "",
137
+ "globalUnit": [],
138
+ "isSampling": true,
139
+ "compareType": [
140
+ "hourCompare",
141
+ "dayCompare"
142
+ ],
143
+ "openCompare": true,
144
+ "yAxixMaxVal": null,
145
+ "yAxixMinVal": null,
146
+ "connectNulls": true,
147
+ "legendValues": [
148
+ "avg",
149
+ "last",
150
+ "first",
151
+ "min",
152
+ "max",
153
+ "sum"
154
+ ],
155
+ "timeInterval": "auto",
156
+ "legendPostion": "bottom",
157
+ "maxPointCount": 20,
158
+ "sorderByOrder": "desc",
159
+ "xAxisShowType": "time",
160
+ "isCombineChart": false,
161
+ "isTimeInterval": true,
162
+ "changeWorkspace": false,
163
+ "openRepeatChart": false,
164
+ "compareChartType": "sequence",
165
+ "currentChartType": "sequence",
166
+ "showFieldMapping": false,
167
+ "onlyShowGroupName": false,
168
+ "scientificNotation": true,
169
+ "repeatChartRowLimit": 3,
170
+ "repeatChartVariable": "",
171
+ "yAxixOpenIncludeZero": true,
172
+ "openThousandsSeparator": true,
173
+ "enablePreflightEstimate": true,
174
+ "mainMeasurementQueryCode": "A"
175
+ },
176
+ "fixedTime": "",
177
+ "isRefresh": false,
178
+ "fixedGroupByTime": null
179
+ },
180
+ "group": {
181
+ "name": null
182
+ },
183
+ "chartGroupUUID": "default",
184
+ "name": "新建图表",
185
+ "pos": {
186
+ "h": 9,
187
+ "w": 19,
188
+ "x": 0,
189
+ "y": 0
190
+ },
191
+ "type": "sequence",
192
+ "queries": [
193
+ {
194
+ "name": "",
195
+ "type": "sequence",
196
+ "unit": "",
197
+ "color": "",
198
+ "qtype": "dql",
199
+ "query": {
200
+ "q": "L('default')::RE(`.*`):(count(`*`) AS `aaa`) { `host` = '#{host}' } BY `host`",
201
+ "code": "A",
202
+ "fill": null,
203
+ "type": "simple",
204
+ "alias": "aaa",
205
+ "field": "*",
206
+ "limit": null,
207
+ "fillNum": null,
208
+ "filters": [
209
+ {
210
+ "id": "6b770a50-f4ef-11f0-ac95-dd561dcf45d1",
211
+ "op": "=",
212
+ "name": "host",
213
+ "type": "keyword",
214
+ "logic": "and",
215
+ "value": "#{host}",
216
+ "values": []
217
+ }
218
+ ],
219
+ "groupBy": [
220
+ "host"
221
+ ],
222
+ "labelOp": "",
223
+ "funcList": [],
224
+ "fieldFunc": "count",
225
+ "fieldType": "keyword",
226
+ "namespace": "logging",
227
+ "dataSource": "*",
228
+ "queryFuncs": [],
229
+ "withLabels": [],
230
+ "groupByTime": "",
231
+ "indexFilter": "default"
232
+ },
233
+ "disabled": false,
234
+ "datasource": "dataflux"
235
+ }
236
+ ],
237
+ "prevGroupName": null,
238
+ "uuid": "chrt_fd51995ec5e443119f66d2f5fa54c59c"
239
+ },
240
+ {
241
+ "extend": {
242
+ "settings": {
243
+ "alias": [],
244
+ "units": [],
245
+ "colors": [],
246
+ "levels": [],
247
+ "slimit": 20,
248
+ "lineType": "linear",
249
+ "showLine": false,
250
+ "unitType": "global",
251
+ "chartType": "line",
252
+ "fixedTime": "",
253
+ "isPercent": false,
254
+ "openStack": false,
255
+ "precision": "2",
256
+ "showLabel": false,
257
+ "showTitle": true,
258
+ "stackType": "time",
259
+ "titleDesc": "",
260
+ "globalUnit": [],
261
+ "isSampling": true,
262
+ "compareType": [],
263
+ "openCompare": false,
264
+ "yAxixMaxVal": null,
265
+ "yAxixMinVal": null,
266
+ "connectNulls": true,
267
+ "legendValues": "",
268
+ "timeInterval": "auto",
269
+ "legendPostion": "none",
270
+ "maxPointCount": null,
271
+ "sorderByOrder": "desc",
272
+ "xAxisShowType": "time",
273
+ "isCombineChart": false,
274
+ "isTimeInterval": true,
275
+ "changeWorkspace": false,
276
+ "openRepeatChart": false,
277
+ "currentChartType": "sequence",
278
+ "showFieldMapping": false,
279
+ "onlyShowGroupName": false,
280
+ "scientificNotation": true,
281
+ "repeatChartRowLimit": 3,
282
+ "repeatChartVariable": "",
283
+ "yAxixOpenIncludeZero": true,
284
+ "openThousandsSeparator": true,
285
+ "enablePreflightEstimate": false,
286
+ "mainMeasurementQueryCode": ""
287
+ },
288
+ "fixedTime": ""
289
+ },
290
+ "group": {
291
+ "name": null
292
+ },
293
+ "chartGroupUUID": "default",
294
+ "name": "新建图表2",
295
+ "pos": {
296
+ "h": 10,
297
+ "w": 8,
298
+ "x": 0,
299
+ "y": 0
300
+ },
301
+ "type": "sequence",
302
+ "queries": [
303
+ {
304
+ "name": "",
305
+ "type": "sequence",
306
+ "unit": "",
307
+ "color": "",
308
+ "qtype": "dql",
309
+ "query": {
310
+ "q": "",
311
+ "code": "A",
312
+ "fill": null,
313
+ "type": "simple",
314
+ "alias": "",
315
+ "field": "",
316
+ "filters": [],
317
+ "groupBy": [],
318
+ "funcList": [],
319
+ "fieldFunc": "",
320
+ "namespace": "metric",
321
+ "dataSource": "",
322
+ "queryFuncs": [],
323
+ "groupByTime": "",
324
+ "indexFilter": ""
325
+ },
326
+ "disabled": false,
327
+ "datasource": "dataflux"
328
+ }
329
+ ],
330
+ "prevGroupName": null,
331
+ "uuid": "chrt_11b8a61a4060492db997572f85f66208"
332
+ }
333
+ ],
334
+ "chartGroupPos": [
335
+ "chtg_472fc54aa73f4bd1969b16b991a71763"
336
+ ],
337
+ "groups": [
338
+ {
339
+ "name": "test1",
340
+ "extend": {
341
+ "colorKey": "style_key14"
342
+ }
343
+ }
344
+ ],
345
+ "type": "template"
346
+ },
347
+ "identifier": "12"
348
+ }
@@ -1,288 +1,7 @@
1
- const grafanaPanelTypeToGuanceChartMap = {
2
- stat: 'singlestat',
3
- singlestat: 'singlestat',
4
- barchart: 'bar',
5
- timeseries: 'sequence',
6
- graph: 'sequence',
7
- piechart: 'pie',
8
- histogram: 'histogram',
9
- bargauge: 'toplist',
10
- gauge: 'gauge',
11
- table: 'table',
12
- text: 'text',
13
- heatmap: 'heatmap',
14
- treemap: 'treemap',
15
- };
16
- const GRAFANA_KEYWORKD = ['__interval'];
17
- const VARIABLE_MAP = {
18
- query: 'PROMQL_QUERY',
19
- custom: 'CUSTOM_LIST',
20
- };
21
- const VARIABLE_DATASOURCE_MAP = {
22
- query: 'dataflux',
23
- custom: 'custom',
24
- };
25
- function isSupportedVariableType(type) {
26
- return Object.prototype.hasOwnProperty.call(VARIABLE_MAP, type);
27
- }
28
- function replaceVariableStr(grafanaExpr) {
29
- return grafanaExpr.replace(/\$\{?([\d_\w]+)\}?/g, function (match, variable) {
30
- if (GRAFANA_KEYWORKD.indexOf(variable) > -1)
31
- return match;
32
- return `#{${variable}}`;
33
- });
34
- }
35
- function sortPanelItemsByRowCol(panels) {
36
- return panels.slice(0).sort(function (panelA, panelB) {
37
- const { gridPos: posA } = panelA;
38
- const { gridPos: posB } = panelB;
39
- if (!posA || !posB)
40
- return -1;
41
- if (posA.y === posB.y && posA.x === posB.x && posA.w > posB.w) {
42
- return -1;
43
- }
44
- if (posA.y === posB.y && posA.x === posB.x) {
45
- return 0;
46
- }
47
- if (posA.y > posB.y || (posA.y === posB.y && posA.x > posB.x)) {
48
- return 1;
49
- }
50
- return -1;
51
- });
52
- }
53
- function tenToTweenty(source = 1) {
54
- const numArr = [];
55
- source--;
56
- do {
57
- numArr.push(source % 26);
58
- source = Math.floor(source / 26);
59
- } while (source > 0);
60
- return numArr
61
- .reverse()
62
- .map((item, index) => {
63
- return String.fromCharCode(item + 97 + (index === numArr.length - 1 ? 0 : -1));
64
- })
65
- .join('')
66
- .toLowerCase();
67
- }
68
- function getGridH(h, rowHeight, margin) {
69
- return Math.round(h * rowHeight + Math.max(0, 2 * (h - 1)) * margin);
70
- }
71
- function getGuanceHByGrafanaH(granfanH) {
72
- return (getGridH(granfanH, 30, 4) + 10) / 20;
73
- }
74
- function covertPanelToGuanceChart(grafanaPanel, rowPanel) {
75
- const { gridPos, title, type, targets, options } = grafanaPanel;
76
- const chartType = grafanaPanelTypeToGuanceChartMap[type];
77
- let pos = {
78
- x: gridPos.x,
79
- w: gridPos.w,
80
- y: gridPos.y,
81
- h: gridPos.h,
82
- };
83
- if (rowPanel) {
84
- const { gridPos: rowGridPos } = rowPanel;
85
- if (rowGridPos && gridPos && !rowPanel.collapsed) {
86
- pos = {
87
- x: gridPos.x,
88
- w: gridPos.w,
89
- y: gridPos.y - rowGridPos.y,
90
- h: gridPos.h,
91
- };
92
- }
93
- }
94
- const queries = [];
95
- if (targets && targets.length) {
96
- let currentIndex = 0;
97
- targets.forEach((_target) => {
98
- const queryStr = _target.expr || _target.query || _target.queryText;
99
- if (!queryStr)
100
- return;
101
- currentIndex++;
102
- const queryItem = {
103
- datasource: 'dataflux',
104
- qtype: 'promql',
105
- type: chartType,
106
- query: {
107
- q: replaceVariableStr(queryStr),
108
- type: 'promql',
109
- code: tenToTweenty(currentIndex),
110
- promqlCode: currentIndex,
111
- },
112
- };
113
- queries.push(queryItem);
114
- });
115
- }
116
- let settings = {};
117
- if (options) {
118
- switch (chartType) {
119
- case 'text':
120
- queries.push({
121
- query: {
122
- content: options.content,
123
- },
124
- });
125
- break;
126
- case 'toplist':
127
- settings = {
128
- showTopSize: true,
129
- chartType: 'bar',
130
- };
131
- break;
132
- default:
133
- break;
134
- }
135
- }
136
- return {
137
- extend: {
138
- settings: settings,
139
- },
140
- group: {
141
- name: rowPanel ? rowPanel.title : null,
142
- },
143
- pos: {
144
- x: pos.x,
145
- y: getGuanceHByGrafanaH(pos.y),
146
- h: getGuanceHByGrafanaH(pos.h),
147
- w: pos.w,
148
- },
149
- name: replaceVariableStr(title || ''),
150
- queries: queries,
151
- type: chartType,
152
- };
153
- }
154
- function covertPanelsToCharts(grafanaPanelData, rowPanel) {
155
- const guanceCharts = [];
156
- grafanaPanelData.forEach((grafanaPanel) => {
157
- if (!grafanaPanel.gridPos)
158
- return;
159
- guanceCharts.push(covertPanelToGuanceChart(grafanaPanel, rowPanel));
160
- });
161
- return guanceCharts;
162
- }
1
+ // This script is the shared conversion source for the published API and CLI.
2
+ // Keep it thin and delegate to the maintained converter implementation.
3
+ // @ts-ignore
4
+ import { convertDashboard } from '../../skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs';
163
5
  export function covert(grafanaData) {
164
- var _a, _b, _c;
165
- const covertGuanceResult = {};
166
- covertGuanceResult.title = grafanaData.title;
167
- const guanceVars = [];
168
- (_b = (_a = grafanaData.templating) === null || _a === void 0 ? void 0 : _a.list) === null || _b === void 0 ? void 0 : _b.forEach((_variable, index) => {
169
- const { current, type, allValue } = _variable;
170
- const variableType = String(type);
171
- if (!isSupportedVariableType(variableType))
172
- return;
173
- let defaultVal = {
174
- label: '',
175
- value: '',
176
- };
177
- if (current) {
178
- let labels = [];
179
- let values = [];
180
- if (Array.isArray(current.text)) {
181
- labels = current.text;
182
- }
183
- else if (typeof current.text === 'string') {
184
- labels = [current.text];
185
- }
186
- if (Array.isArray(current.value)) {
187
- values = current.value;
188
- }
189
- else if (typeof current.value === 'string') {
190
- values = [current.value];
191
- }
192
- labels = labels.map((label) => {
193
- if (label === 'All') {
194
- if (allValue === '.*') {
195
- return '*';
196
- }
197
- return 'all values';
198
- }
199
- return label;
200
- });
201
- values = values.map((value) => {
202
- if (value === '$__all') {
203
- if (allValue === '.*') {
204
- return '*';
205
- }
206
- return '__all__';
207
- }
208
- return value;
209
- });
210
- defaultVal = {
211
- label: labels.join(','),
212
- value: values.join(','),
213
- };
214
- }
215
- let value = _variable.query;
216
- if (value && typeof value === 'object' && value.query) {
217
- value = replaceVariableStr(value.query);
218
- }
219
- else if (value && typeof value === 'string') {
220
- value = replaceVariableStr(_variable.query);
221
- }
222
- else {
223
- return;
224
- }
225
- const guanceVariableItem = {
226
- type: VARIABLE_MAP[variableType],
227
- datasource: VARIABLE_DATASOURCE_MAP[variableType],
228
- name: _variable.label || _variable.name || '',
229
- seq: index,
230
- hide: _variable.hide ? 1 : 0,
231
- multiple: _variable.multi !== undefined ? _variable.multi : true,
232
- includeStar: _variable.includeAll !== undefined ? _variable.includeAll : true,
233
- valueSort: 'desc',
234
- code: _variable.name,
235
- definition: {
236
- value: value,
237
- defaultVal: defaultVal,
238
- },
239
- };
240
- guanceVars.push(guanceVariableItem);
241
- });
242
- const guanceGroups = [];
243
- const guanceExpand = {};
244
- const guanceCharts = [];
245
- let lastRowPanel;
246
- let lastPanels = [];
247
- let grafanaCharts = ((_c = grafanaData.panels) === null || _c === void 0 ? void 0 : _c.filter((_panel) => _panel.type === 'row' || grafanaPanelTypeToGuanceChartMap[_panel.type])) || [];
248
- grafanaCharts = sortPanelItemsByRowCol(grafanaCharts);
249
- grafanaCharts.forEach((_panel) => {
250
- var _a;
251
- if (_panel.type === 'row') {
252
- const _rowPanel = _panel;
253
- if (_rowPanel.title) {
254
- guanceGroups.push({
255
- name: _rowPanel.title,
256
- });
257
- guanceExpand[_rowPanel.title] = !_rowPanel.collapsed;
258
- }
259
- if (lastPanels.length) {
260
- guanceCharts.push(...covertPanelsToCharts(lastPanels, lastRowPanel));
261
- lastPanels = [];
262
- lastRowPanel = undefined;
263
- }
264
- if (_rowPanel.collapsed) {
265
- const subPanels = ((_a = _rowPanel.panels) === null || _a === void 0 ? void 0 : _a.filter((_childPanel) => _childPanel.type === 'row' || grafanaPanelTypeToGuanceChartMap[_childPanel.type])) || [];
266
- guanceCharts.push(...covertPanelsToCharts(subPanels, _rowPanel));
267
- }
268
- else {
269
- lastRowPanel = _rowPanel;
270
- }
271
- }
272
- else {
273
- lastPanels.push(_panel);
274
- }
275
- });
276
- if (lastPanels.length) {
277
- guanceCharts.push(...covertPanelsToCharts(lastPanels, lastRowPanel));
278
- }
279
- covertGuanceResult.dashboardExtend = {
280
- groupUnfoldStatus: guanceExpand,
281
- };
282
- covertGuanceResult.main = {
283
- vars: guanceVars,
284
- charts: guanceCharts,
285
- groups: guanceGroups,
286
- };
287
- return covertGuanceResult;
6
+ return convertDashboard(grafanaData);
288
7
  }