简体   繁体   中英

How to expose metrics to Prometheus from a Java (Spring boot) application

My Spring-Boot application simply has a counter metric. I just don't know how to send this information to Prometheus. I am using Maven (build tool) and Spring Boot (Java).

Prometheus, like Graphite, is a time-series storage engine.

Grafana can then query Prometheus to generate graphics and alerts.

https://prometheus.io/docs/introduction/faq/

As the documentation cites, Prometheus, unlike other metrics storage systems, uses a (debatable) "pull" model.

This means that there is a (stand-alone) Prometheus server that must be downloaded/installed. This server then periodically makes HTTP GET requests (pull) to a list of application servers - such as a Java SpringBoot server to fetch (in-memory) stored metrics.

Ref: https://prometheus.io/docs/introduction/faq/#why-do-you-pull-rather-than-push?

Thus the (Spring Boot) application must expose a metrics end-point that the Prometheus server can pull from (default is /metrics).

Ref: https://github.com/prometheus/client_java

Thus there is much documentation available on Google but that is the (arguably convoluted) topology - along with arguments from the SoundCloud and Prometheus folks as to why a "pull" model is preferred over "push" as every other metrics framework employs.

For Intergrating Prometheus, add the following dependencies in your POM.XML

<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_spring_boot</artifactId>
    <version>0.1.0</version>
</dependency>
<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_servlet</artifactId>
    <version>0.1.0</version>
</dependency>
<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_hotspot</artifactId>
    <version>0.1.0</version>
</dependency>

In your SpringBoot Application Class, add the Annonation @EnablePrometheusEndpoint

In your Controller, you can define a Custom Counter

private static final Counter myCounter = Counter.build()
        .name("CounterName")
        .labelNames("status")
        .help("Counter desc").register();

In your service, you can have appropriate logic for your Counter which would be automatically pulled by Prometheus

@RequestMapping("/myService")
    public void endpoint() {
           String processingResult = yourLogic(myCounter);
            myCounter.labels("label1",processingResult).inc();
            }

Spring Boot 2.0.0

Check your spring boot properties file to ensure that metrics and Prometheus exporting are enabled.

For example:

management.endpoints.web.exposure.include=*
management.endpoint.metrics.enabled=true
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true

My Few Cents from spring-boot perspective -

build.gradle

compile 'io.prometheus:simpleclient_servlet:0.3.0'
compile('io.prometheus:simpleclient_hotspot:0.3.0')
compile('io.prometheus:simpleclient_spring_boot:0.3.0')

Your class containing main function should have the following annotations

@EnableSpringBootMetricsCollector
@EnablePrometheusEndpoint
...
...
@Bean
public boolean initializePrometheusEssentials() {
    return prometheusUtility.initializePrometheusEssentials();
}

PometheusUtility.java

import io.prometheus.client.Counter;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;

@Component("PrometheusUtility")
public class PrometheusUtility {

private PrometheusUtility(){

}

private final static Map<String,Counter> counters = new HashMap<>();

public boolean initializePrometheusEssentials() {
counters.put("SAMPLE-COUNTER",Counter.build()
            .name("SAMPLE COUNTER")
            .help("Records the Sample Count").register());
            return true;
}


public static void incrementCounter(String counterName){
    counters.get(counterName).inc();
}
}

Use the incrementCounter method to increment it.

And be sure to add the following properties to your env file

# Prometheus settings
#change prometheus endpoint to metrics
endpoints.prometheus.id=
#change actuator endpoint to springmetrics
endpoints.metrics.id=
endpoints.metrics.sensitive=
endpoints.metrics.enabled=
endpoints.prometheus.sensitive=

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM