spring boot prometheus client 源码分析

来源:互联网 发布:梅县东山中学 知乎 编辑:程序博客网 时间:2024/06/07 02:59

说明

本文针对prometheus官方的spring boot集成client
maven 依赖如下:

<dependency>            <groupId>io.prometheus</groupId>            <artifactId>simpleclient_spring_boot</artifactId>            <version>0.0.26</version>        </dependency>

Metrics 输出

首先从metrics输出入手,http://localhost:8080/prometheus
在工程中使用注解 @EnablePrometheusEndpoint 的时候,程序启用配置,通过注册MvcEndpoint,暴露出访问路径为”prometheus”的http请求服务.
关键代码片段:
注解

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Import({PrometheusEndpointConfiguration.class})public @interface EnablePrometheusEndpoint {}

配置类,配置PrometheusMvcEndpoint

@Configurationclass PrometheusEndpointConfiguration {    PrometheusEndpointConfiguration() {    }    @Bean    public PrometheusEndpoint prometheusEndpoint() {        return new PrometheusEndpoint(CollectorRegistry.defaultRegistry);    }    @Bean    @ConditionalOnBean({PrometheusEndpoint.class})    @ConditionalOnEnabledEndpoint("prometheus")    public PrometheusMvcEndpoint prometheusEndpointFix(PrometheusEndpoint prometheusEndpoint) {        return new PrometheusMvcEndpoint(prometheusEndpoint);    }}

创建PrometheusEndpoint

@ConfigurationProperties("endpoints.prometheus")class PrometheusEndpoint extends AbstractEndpoint<String> {    private final CollectorRegistry collectorRegistry;    PrometheusEndpoint(CollectorRegistry collectorRegistry) {        super("prometheus");        this.collectorRegistry = collectorRegistry;    }    public String invoke() {        return this.writeRegistry(Collections.emptySet());    }    public String writeRegistry(Set<String> metricsToInclude) {        try {            StringWriter e = new StringWriter();            TextFormat.write004(e, this.collectorRegistry.filteredMetricFamilySamples(metricsToInclude));            return e.toString();        } catch (IOException var3) {            throw new RuntimeException("Writing metrics failed", var3);        }    }}

最终由writeRegistry输出metrics信息.
进去查看,发现实际上是将搜集器注册中心(CollectorRegistry)中所有的搜集器(Collector)中的信息, 描述到Enumeration中,再由TextFormat将Enumeration以text格式输出.

Metrics 搜集

创建搜集器时,搜集器被注册到CollectorRegistry.
创建搜集器Counter,并注册.

public static final Counter requestTotal = Counter.build().name("NAME").labelNames("label1", "label2").help            ("total request counter of api").register();

注册Counter:

public C register() {            return this.register(CollectorRegistry.defaultRegistry);        }        public C register(CollectorRegistry registry) {            SimpleCollector sc = this.create();            registry.register(sc);            return sc;        }

搜集器本身提供计数方法,和描述方法.
计数方法记录数据的增加, 描述方法用于输出metrics时将记录数据转换成便于描述的metrics信息.
Counter 源码:

public class Counter extends SimpleCollector<Counter.Child> implements Describable {    Counter(Counter.Builder b) {        super(b);    }    public static Counter.Builder build(String name, String help) {        return (Counter.Builder)((Counter.Builder)(new Counter.Builder()).name(name)).help(help);    }    public static Counter.Builder build() {        return new Counter.Builder();    }    protected Counter.Child newChild() {        return new Counter.Child();    }    //计数器加1    public void inc() {        this.inc(1.0D);    }    public void inc(double amt) {        ((Counter.Child)this.noLabelsChild).inc(amt);    }    public double get() {        return ((Counter.Child)this.noLabelsChild).get();    }    //将数据转换成Metric    public List<MetricFamilySamples> collect() {        ArrayList samples = new ArrayList(this.children.size());        Iterator var2 = this.children.entrySet().iterator();        while(var2.hasNext()) {            Entry c = (Entry)var2.next();            samples.add(new Sample(this.fullname, this.labelNames, (List)c.getKey(), ((Counter.Child)c.getValue()).get()));        }        return this.familySamplesList(Type.COUNTER, samples);    }    public List<MetricFamilySamples> describe() {        return Collections.singletonList(new CounterMetricFamily(this.fullname, this.help, this.labelNames));    }    public static class Child {        private final DoubleAdder value = new DoubleAdder();        public Child() {        }        public void inc() {            this.inc(1.0D);        }        public void inc(double amt) {            if(amt < 0.0D) {                throw new IllegalArgumentException("Amount to increment must be non-negative.");            } else {                this.value.add(amt);            }        }        public double get() {            return this.value.sum();        }    }    public static class Builder extends io.prometheus.client.SimpleCollector.Builder<Counter.Builder, Counter> {        public Builder() {        }        public Counter create() {            return new Counter(this);        }    }}
原创粉丝点击