@cloudcare/guance-front-tools 1.0.2 → 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: replaceVariableStr(_variable.query),
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',
@@ -258,18 +260,26 @@ const covert = (grafanaData: GrafanaDashboardType): GuanceDashboardType => {
258
260
  value: values.join(','),
259
261
  }
260
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
+ }
261
271
  const guanceVariableItem: ChartVarsItem = {
262
272
  type: VARIABLE_MAP[type],
263
273
  datasource: VARIABLE_DATASOURCE_MAP[type],
264
274
  name: _variable.label,
265
275
  seq: index,
266
276
  hide: _variable.hide ? 1 : 0,
267
- multiple: _variable.multi,
268
- includeStar: _variable.includeAll,
277
+ multiple: _variable.multi !== undefined ? _variable.multi : true,
278
+ includeStar: _variable.includeAll !== undefined ? _variable.includeAll : true,
269
279
  valueSort: 'desc',
270
280
  code: _variable.name,
271
281
  definition: {
272
- value: replaceVariableStr(_variable.query as string),
282
+ value: value,
273
283
  defaultVal: defaultVal,
274
284
  },
275
285
  }
@@ -368,6 +378,11 @@ export async function run(args) {
368
378
  try {
369
379
  const grafanaJSONData = JSON.parse(fs.readFileSync(grafanaJsonPath, 'utf-8'))
370
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
+ }
371
386
  fs.writeFileSync(outGuanceJsonPath, JSON.stringify(covertResult), 'utf-8')
372
387
  } catch (err) {
373
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.2",
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":"![foo](https://grafana.com/about/events/grafanacon/assets/2023/graphic-golden-grot2.svg)\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"}]}}