自定义Prometheus中的exporter

本文介绍了如何自定义Prometheus Exporter,首先从需求出发,然后详细讲解了一般Java环境下和使用SpringBoot实现自定义Exporter的步骤,包括导入依赖、创建Collector、启动HTTP Server以及处理响应格式问题。在SpringBoot中,通过@RequestMapping和设置响应类型为plain解决了数据格式问题,并提供了在service层处理数据的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

公司最近需要进行监控的调整,于是需要用到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));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值