自定义Prometheus中的exporter
需求公司最近需要进行监控的调整,于是需要用到Prometheus。Prometheus自带了node_exporter,可是需求往往是多变的,所以在多变的需求下,便萌生了自己写一个Exporter的想法说干就干首先翻阅Prometheus的中文文档很容易就能找到自定义Exporter的章节找到了这一章节后,...
需求
公司最近需要进行监控的调整,于是需要用到Prometheus。
Prometheus自带了node_exporter,可是需求往往是多变的,所以在多变的需求下,便萌生了自己写一个Exporter的想法
说干就干
一般Java自定义Exporter
首先翻阅Prometheus的中文文档
很容易就能找到自定义Exporter的章节
找到了这一章节后,剩下的就简单了,跟着文档中的步骤走就行了呗
一、导包
项目用的是maven对依赖进行管理
在pom.xml中加入:
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.11.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_httpserver</artifactId>
<version>0.11.0</version>
</dependency>
接下来需要进行Exporter核心的功能:对监控数据样本的采集,这一步骤需要继承Collector类并实现父类的collect()方法:
public class YourCustomCollector extends Collector {
public List<MetricFamilySamples> collect() {
List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>();
String metricName = "my_guage_1";
// Your code to get metrics
MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample(metricName, Arrays.asList("l1"), Arrays.asList("v1"), 4);
MetricFamilySamples.Sample sample2 = new MetricFamilySamples.Sample(metricName, Arrays.asList("l1", "l2"), Arrays.asList("v1", "v2"), 3);
MetricFamilySamples samples = new MetricFamilySamples(metricName, Type.GAUGE, "help", Arrays.asList(sample, sample2));
mfs.add(samples);
return mfs;
}
}
然后调用Collector的register()方法将其注册
再在main方法中启动一个HTTP Server实例:
public class CustomExporter {
public static void main(String[] args) throws IOException {
HTTPServer server = new HTTPServer(1234);
}
}
接下来便可以访问http://127.0.0.1:1234/metrics来获取Prometheus的数据了
SpringBoot实现自定义Exporter
第一阶段目标,在Prometheus中文文档的帮助下轻松完成,接下来便是第二阶段目标:
为了能够自定义Exporter的路径,用SpringBoot再自定义一个Exporter
SpringBoot项目,说到底启动一个Server
故如上一阶段中最后一步,便可以省略。
既然需要自定义路径,那自然是在controller层利用RequestMapping()注解来承载需要更改的路径
为了能在controller中显示Prometheus类型的格式,首先最简单的方法便是直接在方法中定义一串字符,但这种方式回带来一个问题:在Prometheus中打开时回出现错误:以非法字符‘<’开始
这个错误是由于RequestMapping收到的响应是html格式的,为此,将响应类型改为plain格式即可解决该问题,解决方法:在方法开始加入:
response.setContentType("text/plain; version=0.0.4; charset=utf-8");
即可。
别忘了,此时得到的数据是最开始的时候直接输入的字符串,这还是有问题的,不能按照自己的需求更改需要的数据,也没有真实数据。
为了解决该问题。查看上一阶段中register()方法源码,探究其做了什么能让一个List<MetricFamilySamples>类型的数据转换为response能接受的Prometheus类型的数据
可以很快查找到,数据转换是在TextFormat类中的静态方法write004()内完成的,但是write004()方法需要的是枚举类型而不是List
在service层,根据一阶段中的collector方法,编写返回类型为枚举的方法:
public Enumeration<Collector.MetricFamilySamples> collect(List<String> metricsNames) {
List<Collector.MetricFamilySamples> mfs = new ArrayList<>();
if(metricsNames == null) {
metricsNames.add("a");
metricsNames.add("b");
}
for(String metricName : metricsNames) {
Collector.MetricFamilySamples.Sample sample2 = new Collector.MetricFamilySamples.Sample(metricName,
Arrays.asList("a_k"), Arrays.asList("a_v"),
new Random().nextInt(15), System.currentTimeMillis());
Collector.MetricFamilySamples samples;
Collector.MetricFamilySamples.Sample sample3 = new Collector.MetricFamilySamples.Sample(metricName,
Arrays.asList("b_k"), Arrays.asList("b_v"),
new Random().nextInt(20), System.currentTimeMillis());
samples = new Collector.MetricFamilySamples(metricName, Collector.Type.GAUGE, "help", Arrays.asList(sample2,sample3));
System.out.println(samples);
mfs.add(samples);
}
return Collections.enumeration(mfs);
}
在controller层代码为:
@RequestMapping("/metricsTrue")
public void metricsTrue(HttpServletResponse response, @RequestParam(value = "metrics", required = false)List<String> metricsNames) throws IOException {
response.setContentType("text/plain; version=0.0.4; charset=utf-8");
List<String> metricsNames = new ArrayList<>();
metricsNames.add("a");
TextFormat.write004(response.getWriter(), new ExportServer().collect(metricsNames));
}
更多推荐
所有评论(0)