Prometheus远程写Metric
2020-10-05 本文已影响0人
jyhnp
一路坑坑洼洼走过来真不简单!
prometheus学习网址:https://my.oschina.net/u/4400455/blog/3442099
大致思路先写下,prometheus.yml加个配置项,远程写是调用http请求来写的,数据格式是protobuf(一种自定义的编码格式),编码格式是snappy(一种压缩格式);远程写通过snappy先压缩,然后protobuf编码的字节数组请求的;接收到远程写数据时是乱码,先用snappy进行解压缩,prometheus官网文档远程写提供remote.proto(包含编码和解码),remote.proto文件中依赖了types.proto和gogo.proto两个文件,我是在prometheus源码的包里边找到的,所以需要把这三个protobuf文件生成java文件,调用Remote.WriteRequest.parseFrom来解码
一、protobuf转java
1. 下载Protocol Buffers
地址:https://github.com/protocolbuffers/protobuf/releases
Mac解压,如图:
2. 把remote.proto、types.proto、gogo.proto三个文件copy的bin下面 如图:
image.png3. protoc生成java文件
// src_dir: .proto 所在的源目录
// --java_out: 生成 java 代码
// dst_dir: 生成代码的目标目录
// xxx.proto: 要针对哪个 proto 文件生成接口代码
protoc -I=src_dir --java_out=dst_dir src_dir/xxx.proto
如图三个protobuf文件生成三个java文件:
image.png image.png
二、prometheus.yml配置
# 远程写地址
remote_write:
- url: "http://172.16.128.209:8081/receive"
# 基本认证 这是每个远程写请求的授权头属性
basic_auth:
username: prometheus
password: prometheus
image.png
三、java代码(三个java文件copy到项目中)
package com.jyh.prome;
import com.jyh.prome.protobuf.Remote;
import com.jyh.prome.protobuf.Types;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.xerial.snappy.Snappy;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@RestController
public class RemoteWrite {
@RequestMapping(value = "/receive")
public void write(@RequestBody byte[] body, HttpServletRequest request) throws IOException, InterruptedException {
byte[] a = Snappy.uncompress(body);
List<Types.TimeSeries> timeSeriesList = Remote.WriteRequest.parseFrom(a).getTimeseriesList();
for (Types.TimeSeries timeSeries : timeSeriesList) {
List<Types.Sample> samples = timeSeries.getSamplesList();
List<Types.Label> labels = timeSeries.getLabelsList();
Map<String, Object> map = new LinkedHashMap<>();
for (Types.Label label : labels) {
map.put(label.getName(), label.getValue());
}
for (Types.Sample sample : samples) {
map.put("timestamp", sample.getTimestamp());
map.put("value", sample.getValue());
}
System.out.println(map);
}
}
}
控制台打印:
labels {
name: "__name__"
value: "mysql_global_variables_query_cache_min_res_unit"
}
labels {
name: "instance"
value: "192.168.31.40:9101"
}
labels {
name: "job"
value: "ser4"
}
samples {
value: 4096.0
timestamp: 1601196751516
}
不懂就问