0


java prometheus 自定义exporter开发,以及实现多个接口返回metrics

普罗----自定义exporter开发

  exporter的作用是采集需要监控的数据,并将采集到的数据转换成prometheus所需要的数据格式,将这些转换后的数据返回,供给prometheus 使用。

java 编写自定义exporter所需要的pom.xml:

<dependency><groupId>io.prometheus</groupId><artifactId>simpleclient</artifactId><version>0.3.0</version></dependency><dependency><groupId>io.prometheus</groupId><artifactId>simpleclient_httpserver</artifactId><version>0.3.0</version></dependency>

exporter的四类指标说明
数据类型解释CounterCounter类型代表一种样本数据单调递增的指标,即只增不减,除非监控系统发生了重置GuageGuage类型代表一种样本数据可以任意变化的指标,即可增可减HistogramHistogram 由bucket{le=””},bucket{le=”+Inf”},sum,count 组成,主要用于表示一段时间范围内对数据进行采样(通常是请求持续时间或响应大小),并能够对其指定区间以及总数进行统计,通常它采集的数据展示为直方图SummarySummary 和 Histogram 类似,由{quantile=”<φ>”},sum,count 组成,主要用于表示一段时间内数据采样结果(通常是请求持续时间或响应大小),它直接存储了 quantile 数据,而不是根据统计区间计算出来的。
目前在开发hadoop集群指标监控中只用到了前两种数据类型。
demo:
创建启动类Exporter

publicclassExporter{publicstaticvoidmain(String[] args)throwsIOException{//注册collectornewExample1Collector().register();newExample2Collector().register();//开启http服务供prometheus调用,该http服务默认只提供一个接口 http://ip:port/metrics 所有指标一起返回HTTPServer server=newHTTPServer("localhost",8080);}}

创建我们自定义的收集器,继承Collector

publicclassExample1CollectorextendsCollector{//每个指标收集器继承collector类,在收到http请求时,会自动返回collect()方法返回的list@OverridepublicList<MetricFamilySamples>collect(){List<MetricFamilySamples> list =newArrayList<>();GaugeMetricFamily exampleGaugeMetricFamily =newGaugeMetricFamily("example_1_collector","example1_gauge",Arrays.asList("name"));
        exampleGaugeMetricFamily.addMetric(Arrays.asList("Example1Collector"),1);
        list.add(exampleGaugeMetricFamily);return list;}}
publicclassExample2CollectorextendsCollector{@OverridepublicList<MetricFamilySamples>collect(){List<MetricFamilySamples> list =newArrayList<>();CounterMetricFamily exampleCounterMetricFamily=newCounterMetricFamily("example_2_collector","example2_counter",Arrays.asList("name"));
        exampleCounterMetricFamily.addMetric(Arrays.asList("Example2Collector"),1);
        list.add(exampleCounterMetricFamily);return list;}}

这样一个小demo即完成,启动Exporter即可。
访问http://localhost:8080,返回结果如下:

# HELP example_1_collector example1_gauge
# TYPE example_1_collector gauge
example_1_collector{name="Example1Collector",} 1.0
# HELP example_2_collector example2_counter
# TYPE example_2_collector counter
example_2_collector{name="Example2Collector",} 1.0

  这样开发有一个问题就是整个http服务只有这一个接口返回所有指标。假如有需求需要提供多个接口返回指定的指标时,这样就不能满足需求了。

思考:可以使用grizzly2实现http服务提供多个接口,返回固定的指标,那么最重要的就是返回prometheus需要的数据格式,在TextFormat这个类中找到了具体的实现,具体代码如下:

publicclassTextFormat{/**
   * Content-type for text version 0.0.4.
   */publicfinalstaticStringCONTENT_TYPE_004="text/plain; version=0.0.4; charset=utf-8";/**
   * Write out the text version 0.0.4 of the given MetricFamilySamples.
   */publicstaticvoidwrite004(Writer writer,Enumeration<Collector.MetricFamilySamples> mfs)throwsIOException{/* See http://prometheus.io/docs/instrumenting/exposition_formats/
     * for the output format specification. */while(mfs.hasMoreElements()){Collector.MetricFamilySamples metricFamilySamples = mfs.nextElement();
      writer.write("# HELP ");
      writer.write(metricFamilySamples.name);
      writer.write(' ');writeEscapedHelp(writer, metricFamilySamples.help);
      writer.write('\n');

      writer.write("# TYPE ");
      writer.write(metricFamilySamples.name);
      writer.write(' ');
      writer.write(typeString(metricFamilySamples.type));
      writer.write('\n');for(Collector.MetricFamilySamples.Sample sample: metricFamilySamples.samples){
        writer.write(sample.name);if(sample.labelNames.size()>0){
          writer.write('{');for(int i =0; i < sample.labelNames.size();++i){
            writer.write(sample.labelNames.get(i));
            writer.write("=\"");writeEscapedLabelValue(writer, sample.labelValues.get(i));
            writer.write("\",");}
          writer.write('}');}
        writer.write(' ');
        writer.write(Collector.doubleToGoString(sample.value));if(sample.timestampMs !=null){
          writer.write(' ');
          writer.write(sample.timestampMs.toString());}
        writer.write('\n');}}}privatestaticvoidwriteEscapedHelp(Writer writer,String s)throwsIOException{for(int i =0; i < s.length(); i++){char c = s.charAt(i);switch(c){case'\\':
          writer.append("\\\\");break;case'\n':
          writer.append("\\n");break;default:
          writer.append(c);}}}privatestaticvoidwriteEscapedLabelValue(Writer writer,String s)throwsIOException{for(int i =0; i < s.length(); i++){char c = s.charAt(i);switch(c){case'\\':
          writer.append("\\\\");break;case'\"':
          writer.append("\\\"");break;case'\n':
          writer.append("\\n");break;default:
          writer.append(c);}}}privatestaticStringtypeString(Collector.Type t){switch(t){caseGAUGE:return"gauge";caseCOUNTER:return"counter";caseSUMMARY:return"summary";caseHISTOGRAM:return"histogram";default:return"untyped";}}}

可以通过在获取collector返回的list后调用该方法返回普罗的数据格式。

这种方式可实现多个自定义接口返回多个指定的metrics
pom.xml

<dependency><groupId>io.prometheus</groupId><artifactId>simpleclient</artifactId><version>0.3.0</version></dependency><dependency><groupId>org.glassfish.jersey.core</groupId><artifactId>jersey-server</artifactId><version>2.25.1</version></dependency><dependency><groupId>org.glassfish.jersey.containers</groupId><artifactId>jersey-container-grizzly2-http</artifactId><version>2.25.1</version></dependency>

本文转载自: https://blog.csdn.net/Monoluge/article/details/128645447
版权归原作者 monoluge 所有, 如有侵权,请联系我们删除。

“java prometheus 自定义exporter开发,以及实现多个接口返回metrics”的评论:

还没有评论