随着互联网技术的发展,前后端分离已成为互联网项目开发的业界标准使用方式。前后端分离的好处之一就是前后端可以并行开发,它能极大的提高工作效率。但前端开发需要依赖后端的数据,所以前后端并行开发的前提是前端能够mock后端数据,有很多第三方库可以实现这种数据的mock,比如著名的mock.js,它可以拦截前端页面的异步请求,返回自定义的数据。
对于一般的前端项目我们都可以mock数据,但如果前端在开发grafana看板,又该如何mock数据呢?以下是我在实际工作中开发grafana看板的过程,前提是跟后台沟通好了数据,然后mock数据来完成grafana看板的本地开发。
一、本地开发环境搭建
首先需要在本地搭建开发环境,我们需要prometheus数据库,需要生成数据源的工具node-exporter,当然也需要绘制图表的工具grafana。使用docker可以一条命令部署这三个应用,前提是配置好docker-compose.yml。
在项目根目录下新建docker-compose.yml配置文件:
version: '3.4'
services:
prometheus:
image: prom/prometheus
container_name: prometheus
hostname: prometheus
ports:
- 9090:9090
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
node-exporter:
image: prom/node-exporter
container_name: node-exporter
hostname: node-exporter
ports:
- 9100:9100
volumes:
- ./textfile:/textfile
entrypoint: /bin/sh -c "/bin/node_exporter --collector.textfile.directory=textfile"
grafana:
image: grafana/grafana
container_name: grafana
hostname: grafana
ports:
- 3000:3000
volumes:
- ./grafana.ini:/etc/grafana/grafana.ini
- ./provisioning:/etc/grafana/provisioning/
下面简要说明下docker-compose.yml的配置:
1、prometheus的配置:主要是映射宿主机的9090端口到容器的9090端口,并将prometheus的配置文件prometheus.yml挂载到宿主机的项目根目录下。prometheus.yml的内容如下:
global:
scrape_interval: 60s # 抓取频率
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["node-exporter:9100"]
prometheus.yml主要配置下采集的数据源为node-exporter:9100,这里只需要一个数据源,也可以配置多个。
2、node-exporter的配置:首先映射端口,然后覆盖容器的默认启动方式,将启动命令加上--collector.textfile.directory参数,目的是为了设置自定义metrics的存放目录,这里将存放目录设置为textfile目录,这个目录是在容器里面的,所以为了操作方便,我们将它挂载到宿主机中来。我们只需要将prom文件放置到textfile目录里,即可实现自定义metrics的功能。
一个prom文件的例子(textfile/pool_capacity_total.prom):
# HELP pool_capacity_total Metric read from path/to/textfile/pool_capacity_total.prom
# TYPE pool_capacity_total gauge
pool_capacity_total{name="cluster1",pool_id="001"} 13
pool_capacity_total{name="cluster1",pool_id="002"} 13
pool_capacity_total{name="cluster2",pool_id="003"} 14
这样,node-exporter就生成了三个自定义metrics,部署以后可以通过 <http://localhost:9100/metrics> 来查看。
3、grafana的配置:首先映射端口;其次挂载配置文件grafana.ini到宿主机方便修改;最后,将provisioning挂载出来。provisioning中可以放置预先配置好的数据源和仪表盘,实现启动的时候就可以看到仪表盘。
4、三个应用都配置好了,执行一条命令既可以将三个应用都部署起来:
docker compose up -d
二、自定义metrics与数据mock
在textfile目录中加prom文件可以自定义metrics,但数据是无法变化的,prometheus每次采集的都是同样的数据,为了更接近真实效果,需要让数据动起来。方案就是在系统中起定时任务来不断得覆盖prom文件。
1、首先需要一个配置文件,用来描述prom文件中的metrics,然后通过一个脚本来调用它生成prom文件。这个文件可以命名为metrics.json:
[
{
"metricName": "pool_rep_num",
"metricType": "gauge",
"metricValueMin": 2,
"metricValueMax": 10,
"metrics": [
{ "name": "cluster1", "pool_id": "001" },
{ "name": "cluster1", "pool_id": "002" },
{ "name": "cluster2", "pool_id": "003" }
]
}
]
它将生成下面的prom文件:
# HELP pool_rep_num Metric read from path/to/textfile/pool_rep_num.prom
# TYPE pool_rep_num gauge
pool_rep_num{name="cluster1",pool_id="001"} 5
pool_rep_num{name="cluster1",pool_id="002"} 7
pool_rep_num{name="cluster2",pool_id="003"} 4
2、我们需要一个脚本来完成metrics.json文件到prom文件的转化,可以写个python脚本(printMetrics.py):
import json
import random
import sys
import os
currentPath = os.path.dirname(os.path.abspath(__file__))
def createMetricData(metricName, metricType="gauge", metricValueMin=1, metricValueMax=100, metrics=[]):
metricStr = "# HELP %s Metric read from path/to/textfile/%s.prom\n# TYPE %s %s" % (metricName, metricName, metricName, metricType)
if metrics:
for metric in metrics:
metricDictStr = ""
if metric:
metricDictStr = "{%s}" % ",".join(["%s=\"%s\"" % (key, value) for key, value in metric.items()])
metricStr += "\n%s%s %d" % (metricName, metricDictStr, random.randint(metricValueMin, metricValueMax))
return metricStr
f = open("%s/metrics.json" % currentPath, encoding="utf-8")
res = f.read()
arr = json.loads(res)
for data in arr:
metricName = data["metricName"]
metricType = data["metricType"]
metricValueMin = data["metricValueMin"]
metricValueMax = data["metricValueMax"]
metrics = data["metrics"]
sys.stdout = open("%s/textfile/%s.prom" % (currentPath, metricName), "w")
print(createMetricData(metricName, metricType, metricValueMin, metricValueMax, metrics))
sys.stdout.close()
3、还需要一个启动定时任务的脚本,定时调用printMetrics.py生成prom文件:
#!/bin/sh
# 当前脚本文件所在的绝对路径
fileAbsDir=$(cd $(dirname $0);pwd)
# 启动定时任务产生数据
crontab_job="* * * * * ${fileAbsDir}/printMetrics.sh"
echo "${crontab_job}" > crontab_test
crontab crontab_test