grafana可以非常方便地将prometheus、mysql等数据库中的数据以各种漂亮的图表形式进行展示,但是在某些情况下,grafana并不能或不方便直接从数据库中查询数据,比如,数据本身并不是以grafana可以访问到的数据库数据形式存在,或者需要对原始数据进行比较灵活、复杂的处理后才能提供给grafana进行展示等等。grafana也支持从应用程序的http接口获取展示数据,simplejson数据源就是这种类型的数据源。
1 simplejson数据源应用
1.1 安装
grafana并没有默认安装simplejson数据源,如果需要使用simplejson,需要自己安装
如果环境支持在线安装,可以通过以下方式进行安装:
$ grafana-cli plugins install grafana-simple-json-datasource
也可先下载安装包,然后手动安装:
$ mv grafana-simple-json-datasource-1.4.2.zip ./plugins-bundled
$ cd plugins-bundled
$ unzip grafana-simple-json-datasource-1.4.2.zip
安装后重启grafana
$ sudo su -
# service grafana-server restart
1.2 添加数据源
simplejson安装完后,在grafana的数据源仓库中就可以看到simplejson数据源了,我们就可以添加相应的数据源了。
如下图所示,name
字段填写数据源的名字,url
字段填写数据源对应的url,这个url的路径部分是simplejson数据源相关接口的路径前缀。其他的数据源信息跟普通的数据源相同。如下图所示:
1.3 设置panel数据源为simplejson数据源
添加了simplejson数据源,就可以在panel中使用该数据源了,如下图所示:
上图中查询输入框中的值会作为simplejson /search
接口请求body的target字段值传递给数据源后端,后端根据这个查询字符串确定返回的指标名字列表。
1.4 simplejson数据源接口
simplejson数据源由一组http接口组成:
1.4.1 GET /
该接口必须实现。健康探测接口。没有任何请求参数,返回http响应状态码200表示数据源正常。
1.4.2 POST /search
请求body内容格式:
{
"target": "content of request, usually is a json string"
}
该接口必须实现。这个接口用来查询panel的一些选项参数,如query型变量(variable)的值,指标(metric)的名字等。请求body只有一个target字段,是一个字符串,用来传递请求的内容,比如是请求哪个变量的可能取值等,实际应用中,target往往是一个json字符串。接口返回则是一个值的list或map。因为metric、variable都是通过这个接口获取的,所以target中一般需要有一个表示查询类型的字段。
1.4.2.1 请求metric名字
请求body内容就是创建panel数据查询时查询语句输入框中的内容,如下所示:
{
"target": "{\"type\":\"METRIC\",\"queryId1\":\"$queryId1\",\"queryId2:\"$queryId3\"}"
}
响应body可以是:
["cpu","memory"]
或者:
[ { "text" :"cpu", "value": 1}, { "text" :"memory", "value": 2} ]
表示panel可以向simplejson后端查询展示cpu、memory两个指标
1.4.2.2 请求query变量
如果我们dashboard创建了query类型的variable,且variable的数据源都是simplejson,那么grafana会向simplejson后端查询variable的可取值列表。
例如,我们创建了两个变量:
那么请求body的target
字段的值就是variable变量definition(query)
属性的值,格式如下:
{
"target": "{\"type\":\"QUERY_ID1\"}"
}
{
"target": "{\"type\":\"QUERY_ID2\", \"queryId1\": \"$queryId1\"}"
}
后端响应body格式与请求metric名字一样,是query变量的取值列表
1.4.3 POST /query
该接口必须实现。根据/search
接口返回的指标列表查询这些指标的具体时间序列值。
请求body内容格式:
{
"app": "dashboard",
"requestId": "Q111",
"timezone": "browser",
"panelId": 2,
"dashboardId": 10,
"range": {
"from": "2023-08-13T07:42:01.305Z",
"to": "2023-08-13T07:47:01.305Z",
"raw": {
"from": "now-5m",
"to": "now"
}
},
"timeInfo": "",
"interval": "200ms",
"intervalMs": 200,
"targets": [
{
"target": "cpu",
"refId": "A",
"type": "timeserie"
},
{
"target": "memory",
"refId": "B",
"type": "timeserie"
}
],
"maxDataPoints": 1236,
"scopedVars": {
"__interval": {
"text": "200ms",
"value": "200ms"
},
"__interval_ms": {
"text": "200",
"value": 200
}
},
"startTime": 1691912821305,
"rangeRaw": {
"from": "now-5m",
"to": "now"
},
"adhocFilters": [{
"key": "hostname",
"operator": "=",
"value": "example.com"
}]
}
请求body中的target字段就是/search
接口返回的metric的值
后端返回的body内容格式,如果是时间序列指标,则如下所示,是一个列表,每一个metric是一个元素,元素的datapoint
字段是metric的时间序列值:
[
{
"target":"cpu", // metric名字
"datapoints":[
[80,1450754160000], // 第一个元素是metric值,数据类型是float,第二个元素是unix时间戳,单位是毫秒
[85,1450754220000]
]
},
{
"target":"memory",
"datapoints":[
[861256321,1450754160000],
[767469432,1450754220000]
]
}
]
如果是表格形式,后端返回的body内容格式:
[
{
"columns":[
{"text":"Time","type":"time"},
{"text":"Country","type":"string"},
{"text":"Number","type":"number"}
],
"rows":[
[1234567,"SE",123],
[1234567,"DE",231],
[1234567,"US",321]
],
"type":"table"
}
]
1.4.4 POST /annotations
该接口非必需。如果panel需要向simplejson数据源获取特定的事件,可以通过该接口获取
例如,我们在dashboard中创建了query annotation,数据源是simplejson:
那么grafana会向simplejson请求annotation事件,请求body的格式:
{
"range": {
"from": "2016-04-15T13:44:39.070Z",
"to": "2016-04-15T14:44:39.070Z"
},
"rangeRaw": {
"from": "now-1h",
"to": "now"
},
"annotation": {
"name": "annotation_test", // annotation的名字
"datasource": "SimpleJsonSli",
"iconColor": "rgba(255, 96, 96, 1)", // annotation事件标记的颜色
"enable": true,
"query": "queryString"
}
}
响应body是annotation事件的列表,格式为:
[
{
"annotation": "annotation_test", // annotation的名字
"time": 1450754160000, // 必须。事件发生的时间。unix时间戳,单位为毫秒
"title": "title", // 必须,annotation事件的标题
"tags": ["tag1","tag2"], // 可选。annotation事件的标签
"text": "text" // 可选。annotation事件的文本内容
}
]
1.4.5 POST /tag-keys
该接口非必须。/query
请求body中有一个adhocFilters
参数,用来对数据进行过滤。过滤的key名字列表可以通过这个接口获取。
该接口无需请求参数。
响应body内容是key名字和key值数据类型的列表,格式为:
[
{"type":"string","text":"hostname"},
{"type":"string","text":"rack"}
]
1.4.6 POST /tag-values
该接口非必须。/query
请求body中有一个adhocFilters
参数,用来对数据进行过滤。过滤的key的值列表可以通过这个接口获取。
请求body内容是key的名字,格式为:
{"key": "hostname"}
响应body是key的取值列表,格式为:
[
{'text': 'example.com'},
{'text': 'example2.com'}
]