“This is the 16th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.

Prometheus custom burial position ii of the SpringBoot series

Custom burial points for Prometheus were introduced in the previous blog post, why are they here again?

For those of you who have read the previous article, there is a simpler way to use the Simpleclient package to create metrics for data collection

Compared with the implementation of the previous article, in general, the degree of simplicity can be seen in general, the last article can be viewed by clicking below

  • Prometheus middleware 】 【 Blog buried custom report point | a is gray

II. Custom report

Still building a foundation project, the project demonstrated in this article is mainly SpringBoot2.2.1, there is no big difference in postures used in higher versions, as for 1.x version is not guaranteed to work (because I did not test it).

1. Rely on

Pom dependencies, mainly the following packages

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
</dependencies>
Copy the code

2. Configure information

Next is the configuration file, which registers information about Prometheus

spring:
  application:
    name: prometheus-example
management:
  endpoints:
    web:
      exposure:
        include: "*"
  metrics:
    tags:
      application: ${spring.application.name}
Copy the code

In the above configuration, there are two key pieces of information, described in previous blog posts, which are briefly explained here

  • management.endpoints.web.exposure.includeThis specifies that all Web interfaces are reported
  • metrics.tags.applicationAll metrics reported by the app will be labeled application

After the configuration is complete, a /actuator/ Prometheus endpoint is provided for Prometheus to pull Metrics

3. Customize interceptors to collect and report data

Implement a basic interceptor that blocks all HTTP requests and then collects the request information for reporting

public class MetricInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private MeterRegistry meterRegistry;
    private ThreadLocal<Timer.Sample> threadLocal = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // Total number + 1
        meterRegistry.counter("micro_req_total", Tags.of("url", request.getRequestURI(), "method", request.getMethod())).increment();
        // Count +1 in processing
        meterRegistry.gauge("micro_process_req", Tags.of("url", request.getRequestURI(), "method", request.getMethod()), 1);

        Timer.Sample sample = Timer.start();
        threadLocal.set(sample);
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        try {
            super.postHandle(request, response, handler, modelAndView);
        } finally {
            meterRegistry.gauge("micro_process_req", Tags.of("url", request.getRequestURI(), "method", request.getMethod()), -1);
            // Timer timer = meterRegistry.timer("micro_req_histogram", Tags.of("url", request.getRequestURI(), "method", request.getMethod(), "code", String.valueOf(response.getStatus())));
            Timer timer = Timer.builder("micro_req_histogram").minimumExpectedValue(Duration.ofMillis(1)).maximumExpectedValue(Duration.ofMinutes(3))
                    .sla(Duration.ofMillis(10), Duration.ofMillis(50), Duration.ofMillis(100), Duration.ofMillis(300), Duration.ofMillis(1000))
                    .tags(Tags.of("url", request.getRequestURI(), "method", request.getMethod(), "code", String.valueOf(response.getStatus()))) .register(meterRegistry); threadLocal.get().stop(timer); threadLocal.remove(); }}}Copy the code

Notice how the three metrics are created above

  • Counter: Directly usedmeterRegistry.counter()To create the metric and implement the +1 count
    • In propmetheus, Tags form the label format defined in KV, and the first parameter defines MetricName
  • Gauge: Use the same posture as above, but note that the count is added or subtracted directly from the pass
  • Histogram: The posture of its use requires special attention, as defined in the preHanderTimer.SamplerIn object,postHandlerThe realization of data acquisition

Just a little code above, to achieve a simple custom information report; The next step is to register interceptors

4. Register and test

The interceptor relies on Spring’s bean object, so it needs to be defined as a bean object

@RestController
@SpringBootApplication
public class Application implements WebMvcConfigurer {
    private Random random = new Random();

    @Bean
    public MetricInterceptor metricInterceptor(a) {
        return new MetricInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(metricInterceptor()).addPathPatterns("/ * *");
    }

    @GetMapping(path = "hello")
    public String hello(String name) {
        int sleep = random.nextInt(200);
        try {
            Thread.sleep(sleep);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello sleep: " + sleep + " for " + name;
    }

    public static void main(String[] args) { SpringApplication.run(Application.class); }}Copy the code

Based on this, a simple custom collection report is completed; After the project is started, access the collection endpoint to see if any data is reported

As a final note, although SpringBoot can easily access Prometheus to collect metrics, it is a good choice to use MeterRegistry to collect metrics and create metrics when custom reporting is required. Generally, the three types we choose serve the following purpose

  • Total requests: adoptedCounter
  • Number of requests currently being processed: YesGauge
  • Request Time histogram:Histogram

III. Can’t miss the source code and related knowledge points

0. Project

  • Project: github.com/liuyueyi/sp…
  • Source: github.com/liuyueyi/sp…

1. Wechat official account: Yash Blog

As far as the letter is not as good, the above content is purely one’s opinion, due to the limited personal ability, it is inevitable that there are omissions and mistakes, if you find bugs or have better suggestions, welcome criticism and correction, don’t hesitate to appreciate

Below a gray personal blog, record all the study and work of the blog, welcome everyone to go to stroll

  • A grey Blog Personal Blog blog.hhui.top
  • A Grey Blog-Spring feature Blog Spring.hhui.top