Prometheus查询及接口服务

目录

1.查询语句

1.1 直接使用metrics的name进行查询

1.2 使用标签查询

2.使用记录

2.1 查询语句有加上时间限制

2.2 聚合分组查询

2.3 对区间向量求聚合

2.4 关于Prometheus的api

3 其他

3.1 采集到重复数据

3.2 丢失更新数据

3.3 时区问题

参考文献


1.查询语句

1.1 直接使用metrics的name进行查询

例如我定义如下几个度量

CONST.GAUGE0 = Gauge.build()
		.name(CONST.HOST_NAME+"_a")
		.labelNames("prov","label")
		.help(CONST.HOST_DES)
		.register();
CONST.GAUGE1 = Gauge.build()
		.name(CONST.HOST_NAME+"_s")
		.labelNames("host_ip","process_port","label")
		.help(CONST.HOST_DES)
		.register();
CONST.GAUGE2 = Gauge.build()
		.name(CONST.HOST_NAME+"_c")
		.labelNames("host_ip","process_port","label","d_label","to_ip","to_port")
		.help(CONST.HOST_DES)
		.register();

其中CONST.HOST_NAME="online_access_host_1"

在Graph中,直接输入 online_acces_host_1_a,就能看到如下向量集

1.2 使用标签查询

使用label查询是非常方便的,我们可以通过如下的查询获取所有label=2.1.1的向量。

{label="2.1.1"}

其他的标签也是一样的效果。

其实比较重要的是如何进行聚合查询,例如sum的使用、avg的使用。参考文献1中对这方面有比较好的讲解。

这里记录下我自己在使用过程中的一些体会。

2.使用记录

2.1 查询语句有加上时间限制

{label="2.1.2"} [5m]

它的结果类型是“matrix”,就是一个数据集,不是向量集。是不能用sum聚合的。sum进行聚合是对向量的聚合,结果还是向量集。

2.2 聚合分组查询

场景:在GAUGE1这个度量中,存在这样情况,一台设备有4个process_port,对应标签50个。

  • 我们想查询某台设备不同端口号下标签等于1.2.1的数据向量集,我们可以如下写:
{host_ip="192.168.1.1",label="1.2.1"}

按照上面这样写,可以直接出来四条记录如下:

  • 我想看设备192.168.1.1每个process_port产生的所有数据量,即不考虑指标值了。这时候,我们可以如下写:
sum({host_ip="192.168.1.1"}) by (process_port)

使用 by关键字进行分类聚合,结果如下:

  • 我们想按照主机ip分组查询所有标签等于1.6.1的数据情况,即:想获取每一个设备的1.2.1指标的数据向量集
sum({label="1.6.2"})  by  (host_ip)

灵活的运用标签进行筛选,结合聚合函数,Prometheus能提供非常强大的数据查询效果。

2.3 对区间向量求聚合

例如:求某一个指标一小时内的最大值,这是对向量的某个固定区间求最大值,而不是不同纬度的最大值。

max_over_time({label='1.4.1'} [3h])

类似用法的还有如下函数

2.4 关于Prometheus的api

先看下一下代码

    public static void main(String[] args) throws Exception
    {
        String query = URLEncoder.encode("{label=\"2.1.2\"} [5m]","utf-8");
        String url = "http://localhost:9090/api/v1/query?query="+query;
        String ret = HttpKit.get(url);
        System.out.println(ret);
    }

这段代码的意思,就是模拟请求Prometheus的api接口,将查询语句直接传递过去,就能获取对应的数据。我们可以自己定制化的开发对应的展示效果。

出参如下:

{
	"status": "success",
	"data": {
		"resultType": "matrix",
		"result": [{
			"metric": {
				"__name__": "online_accse_host_1_a",
				"instance": "sp1-exp",
				"job": "bis-sp1",
				"label": "2.1.2",
				"prov": "yunnan"
			},
			"values": [
				[1552558929.044, "3903089"],
				[1552559214.044, "3903089"]
			]
		}]
	}
}

这是一个标准的JSON串。一般情况下,我们在使用Prometheus的时候,都会配套的使Grafana等其他数据展示的工具,但其实,我们也可以自己开发自定义的panel。通过访问Prometheus的接口服务,来获取对应的数据。

3 其他

在使用的过程中,还有以下小细节问题记录。Prometheus通过配置scrape_interval和evaluation_interval参数来设置向exporter采集数据的间隔时间。采集数据的间隔和数据生成的时间间隔大小不同,会对数据采集结果有影响。

3.1 采集到重复数据

假如采集的间隔时间小于数据生成的间隔时间,就会采集到重复的数据。

即:假设Prometheus是每5秒采集一次,但是exporter是每11秒生成一次数据,那么第一次采集成功后,第二次采集的数据还是之前的历史数据,并未更新。

3.2 丢失更新数据

假如采集的时间间隔大于数据生成的时间间隔,那么就会丢失更新数据。上一次的数据还未被采集,就被新的数据覆盖了。

简而言之:Prometheus每次向exporter获取数据的时候,都是获取的当前值,不会取到历史数据。

同样的:在使用pushgetway做中转的时候,也有同样的问题,并不能获取到历史数据,或者避免重复数据。

3.3 时区问题

通过prometheus的UI查询界面查询的到数据在查看graph的时候会发现时间对不上,经过观察比对,会发现时间永远是比当前时间小8个小时。检查Prometheus所在主机的时区以及业务bis_exporter的主机的时区以及时间都相同,但是查看的时候时间数据时间对不上,不过,最怪异的是通过Grafana展示的数据曲线却是正确的,时间也正确。

最后经过搜索发现,Prometheus为了保证时序的准确性,内部所有组件都是会用UTC时间,查了下出的日志文件时间也是少8个小时,这就对的上了。

时间戳必须使用UTC时间么?

是的。为了避免时区的混乱,prometheus所有的组件内部都强制使用Unix时间,对外展示使用UTC时间。如果想改变时区,可以在UI改为合适的时区时间。

参考文献

【1】Prometheus 查询语言

【2】Prometheus监控系统简介(2.1.0)

【3】Prometheus FAQ

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值