@cloudcare/guance-front-tools 1.0.1 → 1.0.3
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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"title":"Redis (非codis) NEW","dashboardExtend":{"groupUnfoldStatus":{"redis server":true}},"main":{"vars":[{"type":"CUSTOM_LIST","datasource":"custom","name":"机房","seq":0,"hide":0,"multiple":false,"includeStar":false,"valueSort":"desc","code":"datacenter","definition":{"value":"new,JQ,Tencent,old","defaultVal":{"label":"new","value":"new"}}},{"type":"PROMQL_QUERY","datasource":"dataflux","name":"集群名称","seq":1,"hide":0,"multiple":false,"includeStar":false,"valueSort":"desc","code":"cluster","definition":{"value":"query_result(count(label_replace(redis_up{datacenter=\"#{datacenter}\",job!~\".*Codis.+\"} , \"Name\", \"#{1}\", \"job\", \"(.+)\") or redis_up{idc=\"#{datacenter}\",job=\"redis\"}) by (Name))","defaultVal":{"label":"base-rediscluster","value":"base-rediscluster"}}},{"type":"PROMQL_QUERY","datasource":"dataflux","name":"DB","seq":2,"hide":0,"multiple":false,"includeStar":false,"valueSort":"desc","code":"db","definition":{"value":"query_result(sum(redis_db_keys{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"} or redis_db_keys{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}) by (db) > 0)","defaultVal":{"label":"db0","value":"db0"}}}],"charts":[{"extend":{"settings":{}},"group":{"name":"default"},"pos":{"x":0,"y":0.5,"h":17.2,"w":24},"name":"超过SLA负载的集群 ","queries":[{"datasource":"dataflux","qtype":"promql","type":"table","query":{"q":" count by (idc,Name) (max(avg(rate(redis_cpu_sys_seconds_total{}[1d]) offset 1d +rate(redis_cpu_user_seconds_total{}[1d]) offset 1d) by (Name,instance,idc)) by (Name,idc) * 100 > 30 or max(1 - avg(irate(node_cpu_seconds_total{mode=\"idle\",role=\"proxy\"}[1d])offset 1d) by (instance,Name,idc)) by (Name,idc) * 100 > 30)","type":"promql"}}],"type":"table"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":2,"h":7.7,"w":4},"name":"节点内存上限","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"avg(redis_config_maxmemory{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"} or redis_config_maxmemory{idc=~\"#{datacenter}\",Name=\"#{cluster}\"})","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":4,"y":2,"h":7.7,"w":4},"name":"节点数量","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"count(redis_config_maxmemory{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"} or redis_config_maxmemory{idc=~\"#{datacenter}\",Name=\"#{cluster}\"})","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":8,"y":2,"h":7.7,"w":4},"name":"集群总内存","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"avg(redis_config_maxmemory{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"}) * sum (redis_instance_info{datacenter=~\"#{datacenter}\",job=\"#{cluster}\",role=\"master\"}) or avg(redis_config_maxmemory{idc=~\"#{datacenter}\",Name=\"#{cluster}\"}) * sum (redis_instance_info{idc=~\"#{datacenter}\",Name=\"#{cluster}\",role=\"master\"})","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"avg(redis_config_maxmemory{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"}) * count(redis_config_maxmemory{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"}) / 2","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":2,"h":7.7,"w":4},"name":"集群已用内存","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"sum(redis_memory_used_bytes{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}) / (sum (redis_instance_info{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"}) / sum (redis_instance_info{datacenter=~\"#{datacenter}\",job=\"#{cluster}\",role=\"master\"}) ) or sum(redis_memory_used_bytes{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}) / (sum (redis_instance_info{idc=~\"#{datacenter}\",Name=\"#{cluster}\"}) / sum (redis_instance_info{idc=~\"#{datacenter}\",Name=\"#{cluster}\",role=\"master\"}) )","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":16,"y":2,"h":7.7,"w":4},"name":"key数量","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"sum(redis_db_keys{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\", db=~\"#{db}\"}) / (sum (redis_instance_info{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"}) / sum (redis_instance_info{datacenter=~\"#{datacenter}\",job=\"#{cluster}\",role=\"master\"}) ) or sum(redis_db_keys{idc=~\"#{datacenter}\",Name=~\"#{cluster}\", db=~\"#{db}\"}) / (sum (redis_instance_info{idc=~\"#{datacenter}\",Name=\"#{cluster}\"}) / sum (redis_instance_info{idc=~\"#{datacenter}\",Name=\"#{cluster}\",role=\"master\"}) ) ","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":20,"y":2,"h":7.7,"w":4},"name":"集群总内存使用率","queries":[{"datasource":"dataflux","qtype":"promql","type":"gauge","query":{"q":"sum(redis_memory_used_bytes{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}) / (avg(redis_config_maxmemory{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"}) * count(redis_config_maxmemory{datacenter=~\"#{datacenter}\",job=\"#{cluster}\"})) or sum(redis_memory_used_bytes{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}) / (avg(redis_config_maxmemory{idc=~\"#{datacenter}\",Name=\"#{cluster}\"}) * count(redis_config_maxmemory{idc=~\"#{datacenter}\",Name=\"#{cluster}\"}))","type":"promql"}}],"type":"gauge"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":24.8,"h":15.3,"w":12},"name":"OPS/sec","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_commands_processed_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m])","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_commands_processed_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m])","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":24.8,"h":15.3,"w":12},"name":"命令执行时间","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"avg(irate(redis_commands_duration_seconds_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m])) by (instance) ","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"avg(irate(redis_commands_duration_seconds_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m])) by (instance) ","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":40,"h":15.3,"w":12},"name":"slowlog","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"delta(redis_slowlog_last_id{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m])","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"delta(redis_slowlog_last_id{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m])","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":40,"h":15.3,"w":12},"name":"slowlog detail","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_slowlog{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":55.2,"h":15.3,"w":12},"name":"key 数量","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"sum(redis_db_keys{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\", db=~\"#{db}\"}) by (instance)","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"sum(redis_db_keys{idc=~\"#{datacenter}\",Name=~\"#{cluster}\", db=~\"#{db}\"}) by (instance)","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":55.2,"h":15.3,"w":12},"name":"key 设置ttl的百分比","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"sum(redis_db_keys{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\", db=~\"#{db}\"}) by (instance)","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_db_keys_expiring{idc=~\"#{datacenter}\",Name=~\"#{cluster}\", db=~\"#{db}\"}/redis_db_keys{idc=~\"#{datacenter}\",Name=~\"#{cluster}\", db=~\"#{db}\"}\r","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":70.4,"h":15.3,"w":12},"name":"CPU使用率(多线程最大400%)","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"rate(redis_cpu_sys_seconds_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m]) + rate(redis_cpu_user_seconds_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m])","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":70.4,"h":15.3,"w":12},"name":"redis内存使用率","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_memory_used_bytes{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"} / redis_config_maxmemory{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_memory_used_bytes{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"} / redis_config_maxmemory{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":85.6,"h":15.3,"w":12},"name":"redis 网络io","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_net_input_bytes_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m])","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"1 - irate(redis_net_output_bytes_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m])","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_net_input_bytes_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m])","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"1 - irate(redis_net_output_bytes_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m])","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":85.6,"h":15.3,"w":12},"name":"命中率","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_keyspace_hits_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m]) / irate(redis_commands_processed_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m])","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_keyspace_hits_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m]) / irate(redis_commands_processed_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m])","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":100.8,"h":15.3,"w":12},"name":"key过期","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"increase(redis_expired_keys_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[1m])","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"increase(redis_expired_keys_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[1m])","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":100.8,"h":15.3,"w":12},"name":"连接数使用率","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_connected_clients{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"} / redis_config_maxclients{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_connected_clients{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"} / redis_config_maxclients{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":116,"h":15.3,"w":12},"name":"redis_memory_used_bytes(key所占用内存)","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_memory_used_bytes{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_memory_used_bytes{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":116,"h":15.3,"w":12},"name":"key驱逐","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_evicted_keys_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m])","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_evicted_keys_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m])","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":131.2,"h":15.3,"w":12},"name":"redis_memory_used_rss_bytes(redis实际使用内存)","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_memory_used_rss_bytes{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_memory_used_rss_bytes{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":131.2,"h":15.3,"w":12},"name":"命令执行时间","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_commands_duration_seconds_total{datacenter=~\"#{datacenter}\",job=~\"#{cluster}\"}[5m]) ","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"irate(redis_commands_duration_seconds_total{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}[5m]) ","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":146.4,"h":15.3,"w":12},"name":"keyprefixes memory ","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_keyprefixes_mem{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":146.4,"h":15.3,"w":12},"name":"主从延迟","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_connected_slave_lag_seconds{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":0,"y":161.6,"h":15.3,"w":12},"name":"keyprefixes number","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_keyprefixes_num{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":161.6,"h":15.3,"w":12},"name":"hotkey detail","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_hotkey{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"redis server"},"pos":{"x":12,"y":176.8,"h":15.3,"w":12},"name":"bigkey detail","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"redis_bigkey{idc=~\"#{datacenter}\",Name=~\"#{cluster}\"}","type":"promql"}}],"type":"sequence"}],"groups":[{"name":"redis server"}]}}
|
|
@@ -60,8 +60,10 @@ import yargs from 'yargs';
|
|
|
60
60
|
// | 'iframe'
|
|
61
61
|
const grafanaPanelTypeToGuanceChartMap = {
|
|
62
62
|
stat: 'singlestat',
|
|
63
|
+
singlestat: 'singlestat',
|
|
63
64
|
barchart: 'bar',
|
|
64
65
|
timeseries: 'sequence',
|
|
66
|
+
graph: 'sequence',
|
|
65
67
|
piechart: 'pie',
|
|
66
68
|
histogram: 'histogram',
|
|
67
69
|
bargauge: 'toplist',
|
|
@@ -71,8 +73,11 @@ const grafanaPanelTypeToGuanceChartMap = {
|
|
|
71
73
|
heatmap: 'heatmap',
|
|
72
74
|
treemap: 'treemap',
|
|
73
75
|
};
|
|
76
|
+
const GRAFANA_KEYWORKD = ['__interval'];
|
|
74
77
|
function replaceVariableStr(grafanaExpr) {
|
|
75
78
|
return grafanaExpr.replace(/\$([\d_\w]+)/g, (match, $0) => {
|
|
79
|
+
if (GRAFANA_KEYWORKD.includes($0))
|
|
80
|
+
return match;
|
|
76
81
|
return `#{${$0}}`;
|
|
77
82
|
});
|
|
78
83
|
}
|
|
@@ -259,18 +264,28 @@ const covert = (grafanaData) => {
|
|
|
259
264
|
value: values.join(','),
|
|
260
265
|
};
|
|
261
266
|
}
|
|
267
|
+
let value = _variable.query;
|
|
268
|
+
if (value && typeof value === 'object' && value.query) {
|
|
269
|
+
value = replaceVariableStr(value.query);
|
|
270
|
+
}
|
|
271
|
+
else if (value && typeof value === 'string') {
|
|
272
|
+
value = replaceVariableStr(_variable.query);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
262
277
|
const guanceVariableItem = {
|
|
263
278
|
type: VARIABLE_MAP[type],
|
|
264
279
|
datasource: VARIABLE_DATASOURCE_MAP[type],
|
|
265
280
|
name: _variable.label,
|
|
266
281
|
seq: index,
|
|
267
282
|
hide: _variable.hide ? 1 : 0,
|
|
268
|
-
multiple: _variable.multi,
|
|
269
|
-
includeStar: _variable.includeAll,
|
|
283
|
+
multiple: _variable.multi !== undefined ? _variable.multi : true,
|
|
284
|
+
includeStar: _variable.includeAll !== undefined ? _variable.includeAll : true,
|
|
270
285
|
valueSort: 'desc',
|
|
271
286
|
code: _variable.name,
|
|
272
287
|
definition: {
|
|
273
|
-
value:
|
|
288
|
+
value: value,
|
|
274
289
|
defaultVal: defaultVal,
|
|
275
290
|
},
|
|
276
291
|
};
|
|
@@ -358,6 +373,11 @@ export function run(args) {
|
|
|
358
373
|
try {
|
|
359
374
|
const grafanaJSONData = JSON.parse(fs.readFileSync(grafanaJsonPath, 'utf-8'));
|
|
360
375
|
const covertResult = covert(grafanaJSONData);
|
|
376
|
+
// 确保目录存在
|
|
377
|
+
const dir = path.dirname(outGuanceJsonPath);
|
|
378
|
+
if (!fs.existsSync(dir)) {
|
|
379
|
+
fs.mkdirSync(dir, { recursive: true }); // recursive: true 确保递归创建目录
|
|
380
|
+
}
|
|
361
381
|
fs.writeFileSync(outGuanceJsonPath, JSON.stringify(covertResult), 'utf-8');
|
|
362
382
|
}
|
|
363
383
|
catch (err) {
|
|
@@ -64,8 +64,10 @@ import type { DashboardData as GrafanaDashboardType, VariableModel, Panel, RowPa
|
|
|
64
64
|
// | 'iframe'
|
|
65
65
|
const grafanaPanelTypeToGuanceChartMap: { [key: string]: GuanceChartType } = {
|
|
66
66
|
stat: 'singlestat',
|
|
67
|
+
singlestat: 'singlestat',
|
|
67
68
|
barchart: 'bar',
|
|
68
69
|
timeseries: 'sequence',
|
|
70
|
+
graph: 'sequence',
|
|
69
71
|
piechart: 'pie',
|
|
70
72
|
histogram: 'histogram',
|
|
71
73
|
bargauge: 'toplist',
|
|
@@ -75,9 +77,10 @@ const grafanaPanelTypeToGuanceChartMap: { [key: string]: GuanceChartType } = {
|
|
|
75
77
|
heatmap: 'heatmap',
|
|
76
78
|
treemap: 'treemap',
|
|
77
79
|
}
|
|
78
|
-
|
|
80
|
+
const GRAFANA_KEYWORKD = ['__interval']
|
|
79
81
|
function replaceVariableStr(grafanaExpr: string): string {
|
|
80
82
|
return grafanaExpr.replace(/\$([\d_\w]+)/g, (match, $0) => {
|
|
83
|
+
if (GRAFANA_KEYWORKD.includes($0)) return match
|
|
81
84
|
return `#{${$0}}`
|
|
82
85
|
})
|
|
83
86
|
}
|
|
@@ -257,18 +260,26 @@ const covert = (grafanaData: GrafanaDashboardType): GuanceDashboardType => {
|
|
|
257
260
|
value: values.join(','),
|
|
258
261
|
}
|
|
259
262
|
}
|
|
263
|
+
let value = _variable.query
|
|
264
|
+
if (value && typeof value === 'object' && value.query) {
|
|
265
|
+
value = replaceVariableStr(value.query as string)
|
|
266
|
+
} else if (value && typeof value === 'string') {
|
|
267
|
+
value = replaceVariableStr(_variable.query as string)
|
|
268
|
+
} else {
|
|
269
|
+
return
|
|
270
|
+
}
|
|
260
271
|
const guanceVariableItem: ChartVarsItem = {
|
|
261
272
|
type: VARIABLE_MAP[type],
|
|
262
273
|
datasource: VARIABLE_DATASOURCE_MAP[type],
|
|
263
274
|
name: _variable.label,
|
|
264
275
|
seq: index,
|
|
265
276
|
hide: _variable.hide ? 1 : 0,
|
|
266
|
-
multiple: _variable.multi,
|
|
267
|
-
includeStar: _variable.includeAll,
|
|
277
|
+
multiple: _variable.multi !== undefined ? _variable.multi : true,
|
|
278
|
+
includeStar: _variable.includeAll !== undefined ? _variable.includeAll : true,
|
|
268
279
|
valueSort: 'desc',
|
|
269
280
|
code: _variable.name,
|
|
270
281
|
definition: {
|
|
271
|
-
value:
|
|
282
|
+
value: value,
|
|
272
283
|
defaultVal: defaultVal,
|
|
273
284
|
},
|
|
274
285
|
}
|
|
@@ -367,6 +378,11 @@ export async function run(args) {
|
|
|
367
378
|
try {
|
|
368
379
|
const grafanaJSONData = JSON.parse(fs.readFileSync(grafanaJsonPath, 'utf-8'))
|
|
369
380
|
const covertResult = covert(grafanaJSONData)
|
|
381
|
+
// 确保目录存在
|
|
382
|
+
const dir = path.dirname(outGuanceJsonPath)
|
|
383
|
+
if (!fs.existsSync(dir)) {
|
|
384
|
+
fs.mkdirSync(dir, { recursive: true }) // recursive: true 确保递归创建目录
|
|
385
|
+
}
|
|
370
386
|
fs.writeFileSync(outGuanceJsonPath, JSON.stringify(covertResult), 'utf-8')
|
|
371
387
|
} catch (err) {
|
|
372
388
|
throw new Error(err)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcare/guance-front-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"clean": "rm -rf ./lib/generated && rm -rf ./lib/esm && rm -rf ./lib/cjs",
|
|
24
24
|
"generate": "node scripts/generate.mjs",
|
|
25
25
|
"format": "prettier -c .",
|
|
26
|
-
"validate": "node scripts/validate.mjs"
|
|
26
|
+
"validate": "node scripts/validate.mjs",
|
|
27
|
+
"prepare": "npm run build"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"ajv": "8.11.0",
|
package/test/xx.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"title":"SHOWCASE: Loki NGINX Service Mesh - JSON version","dashboardExtend":{"groupUnfoldStatus":{"WELCOME TO GRAFANA PLAY!":true,"KPI's":true,"Request statistics over time":true,"Acquisition and Behaviour":false}},"main":{"vars":[{"type":"PROMQL_QUERY","datasource":"dataflux","name":"Label Name","seq":1,"hide":0,"multiple":true,"includeStar":false,"valueSort":"desc","code":"label_name","definition":{"value":"label_names()","defaultVal":{"label":"","value":""}}},{"type":"PROMQL_QUERY","datasource":"dataflux","name":"Label Value","seq":2,"hide":0,"multiple":true,"includeStar":true,"valueSort":"desc","code":"label_value","definition":{"value":"label_values(#{label_name})","defaultVal":{"label":"all values","value":"__all__"}}},{"type":"PROMQL_QUERY","datasource":"dataflux","name":"Job","seq":3,"hide":0,"multiple":true,"includeStar":true,"valueSort":"desc","code":"job","definition":{"value":"label_values({#{label_name}=~\"#{label_value}\"}, job)","defaultVal":{"label":"*","value":"*"}}},{"type":"PROMQL_QUERY","datasource":"dataflux","name":"Instance","seq":4,"hide":0,"multiple":true,"includeStar":true,"valueSort":"desc","code":"instance","definition":{"value":"label_values({#{label_name}=~\"#{label_value}\"}, instance)","defaultVal":{"label":"*","value":"*"}}},{"type":"CUSTOM_LIST","datasource":"custom","name":"query1","seq":5,"hide":0,"multiple":true,"includeStar":true,"valueSort":"desc","code":"query0","definition":{"value":"key:value","defaultVal":{"label":"key:value","value":"key:value"}}}],"charts":[{"extend":{"settings":{}},"group":{"name":"WELCOME TO GRAFANA PLAY!"},"pos":{"x":0,"y":2,"h":15.3,"w":6},"name":"","queries":[{"query":{"content":"\n"}}],"type":"text"},{"extend":{"settings":{}},"group":{"name":"WELCOME TO GRAFANA PLAY!"},"pos":{"x":0,"y":17.2,"h":5.8,"w":9},"name":"","queries":[{"query":{"content":"# THE DASHBOARD SHOWCASE FOR JULY, 2023:\n\n## The [Loki NGINX Service Mesh](https://play.grafana.org/d/T512JVH7z/loki-nginx-service-mesh-json-version?orgId=1), by [Ward Bekker](https://twitter.com/i/flow/login?redirect_after_login=%2Fwardbekker). 👇"}}],"type":"text"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":0,"y":2,"h":7.7,"w":5},"name":"Total requests ","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"sum by(host) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"}[$__interval])) ","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":5,"y":2,"h":15.3,"w":7},"name":"Requests per status code","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"sum by (status) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | __error__=\"\" [$__interval]))","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":12,"y":2,"h":7.7,"w":3},"name":"NGINX logs in bytes","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"bytes_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"}[$__interval])","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":15,"y":2,"h":7.7,"w":3},"name":"% of 5xx requests ","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"sum(count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | status >= 500 |__error__=\"\"[$__interval])) / (sum(count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | __error__=\"\"[$__interval]))/ 100)","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":18,"y":2,"h":7.7,"w":6},"name":"","queries":[{"query":{"content":"📊 Dashboard created by Ward Bekker (hope you like it!)\n\n🐦 Follow me on [Twitter](https://twitter.com/wardbekker) & [LinkedIn](https://www.linkedin.com/in/wardbekker/) for Grafana Loki updates \n\n🎥 Check out my [Grafana Loki video's](https://www.youtube.com/playlist?list=PLDGkOdUX1UjqEzcxQrbROMy8DN7MZv_h4) on Youtube"}}],"type":"text"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":0,"y":9.6,"h":7.7,"w":5},"name":"Realtime visitors ","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"count(sum by (remote_addr) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | __error__=\"\" [$__interval])))","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":12,"y":9.6,"h":7.7,"w":3},"name":"# NGINX log lines","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"}[$__interval])","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":15,"y":9.6,"h":7.7,"w":3},"name":"Total Bytes Sent","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"sum by (host) (sum_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | unwrap body_bytes_sent | __error__=\"\" [$__interval]))","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":18,"y":9.6,"h":7.7,"w":6},"name":"% of requests by Googlebot","queries":[{"datasource":"dataflux","qtype":"promql","type":"singlestat","query":{"q":"sum(count_over_time(({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} |= \"Googlebot\")[$__interval])) / (sum(count_over_time(({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} != \"Googlebot\")[$__interval])) / 100)","type":"promql"}}],"type":"singlestat"},{"extend":{"settings":{}},"group":{"name":"KPI's"},"pos":{"x":12,"y":17.2,"h":21,"w":3},"name":"Top Countries","queries":[{"datasource":"dataflux","qtype":"promql","type":"table","query":{"q":"topk(10, sum by (geoip_country_code) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | geoip_country_code != \"\" and __error__=\"\" [$__interval])))","type":"promql"}}],"type":"table"},{"extend":{"settings":{}},"group":{"name":"Request statistics over time"},"pos":{"x":0,"y":2,"h":17.2,"w":8},"name":"95th percentile of Request Time","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"quantile_over_time(0.95,{#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | unwrap request_time | __error__=\"\" [$__interval]) by (host)","type":"promql"}},{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"max by (host) (max_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | unwrap request_time | __error__=\"\" [$__interval]))","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"Request statistics over time"},"pos":{"x":8,"y":2,"h":17.2,"w":8},"name":"HTTP status codes over time","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"sum by (status) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | __error__=\"\" [$__interval]))","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"Request statistics over time"},"pos":{"x":16,"y":2,"h":17.2,"w":8},"name":"Bytes Sent","queries":[{"datasource":"dataflux","qtype":"promql","type":"sequence","query":{"q":"sum by (host) (sum_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | status=200 | unwrap body_bytes_sent | __error__=\"\" [$__interval]))","type":"promql"}}],"type":"sequence"},{"extend":{"settings":{}},"group":{"name":"Acquisition and Behaviour"},"pos":{"x":0,"y":70.4,"h":11.5,"w":9},"name":"Top 10 HTTP Referers","queries":[{"datasource":"dataflux","qtype":"promql","type":"table","query":{"q":"topk(10, sum by (http_referer) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | http_referer != \"\" and http_referer !~ \".*?#{host}.*?\" and http_referer !~ \".*?\\\\*\\\\*\\\\*.*?\" | __error__=\"\" [15m])))","type":"promql"}}],"type":"table"},{"extend":{"settings":{}},"group":{"name":"Acquisition and Behaviour"},"pos":{"x":9,"y":70.4,"h":11.5,"w":15},"name":"Top 10 User Agents","queries":[{"datasource":"dataflux","qtype":"promql","type":"table","query":{"q":"topk(10, sum by (http_user_agent) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | __error__=\"\" [15m])))","type":"promql"}}],"type":"table"},{"extend":{"settings":{}},"group":{"name":"Acquisition and Behaviour"},"pos":{"x":0,"y":81.8,"h":15.3,"w":9},"name":"Top 10 visitor IPs","queries":[{"datasource":"dataflux","qtype":"promql","type":"table","query":{"q":"topk(10, sum by (remote_addr, geoip_country_code) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} | json | __error__=\"\" [15m])))","type":"promql"}}],"type":"table"},{"extend":{"settings":{}},"group":{"name":"Acquisition and Behaviour"},"pos":{"x":9,"y":81.8,"h":15.3,"w":15},"name":"Top 10 Requested Pages","queries":[{"datasource":"dataflux","qtype":"promql","type":"table","query":{"q":"topk(10, sum by (request_uri) (count_over_time({#{label_name}=~\"#{label_value}\", job=~\"#{job}\", instance=~\"#{instance}\"} !~ `\\.ico|\\.svg|\\.css|\\.png|\\.txt|\\.js|\\.xml` | json | status = 200 and request_uri != \"/\" | __error__=\"\" [15m])))","type":"promql"}}],"type":"table"}],"groups":[{"name":"WELCOME TO GRAFANA PLAY!"},{"name":"KPI's"},{"name":"Request statistics over time"},{"name":"Acquisition and Behaviour"}]}}
|