2

I am trying to learn Grafana and creating application using Spring Boot 2, Prometheus and Grafana for metrics. I need to create custom metrics for per day student creation count.

import com.demo.mockito.entity.StudentEntity;
import com.demo.mockito.service.StudentService;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Metrics;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Controller {
    
    @Autowired
    private StudentRepository studentRepository;

    @Timed
    @GetMapping("studentEntity")
    public ResponseEntity<StudentEntity> studentEntity() {
        StudentEntity studentEntity = new StudentEntity();
        studentEntity.setName("shri");
        studentEntity.setSurName("sharma");
        StudentEntity student = studentRepository.save(studentEntity); // <- need to create metrics of student.getRollNo()
        
        return ResponseEntity.ok(student);
    }
}

application.properties

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# Enable prometheus exporter
management.metrics.export.prometheus.enabled=true
# Enable prometheus end point
management.endpoints.web.exposure.include=prometheus
# enable percentile-based histogram for http requests
management.metrics.distribution.percentiles-histogram.http.server.requests=true
# http SLA histogram buckets
management.metrics.distribution.sla.http.server.requests=100ms,150ms,250ms,500ms,1s
# enable JVM metrics
management.metrics.enable.jvm=true
spring.application.name=test app
management.metrics.tags.application=${spring.application.name}
spring.app.jpa.properties.hibernate.hibernateDDL=create
spring.app.jpa.properties.hibernate.hibernateShowSql=true
spring.jpa.generate-ddl=true
spring.jpa.database.schema=student_db
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

build.gradle

plugins {
    id 'org.springframework.boot' version '2.3.0.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
repositories {
    mavenCentral()
}
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.h2database:h2'
    runtimeOnly 'io.micrometer:micrometer-registry-prometheus'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}
test {
    useJUnitPlatform()
}

Main Application:

package com.demo.mockito;
import io.micrometer.core.aop.TimedAspect;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;

@SpringBootApplication
public class SpringMockitoApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(SpringMockitoApplication.class, args);
    }

    // custom application name
    @Bean
    MeterRegistryCustomizer<MeterRegistry> configurer(
            @Value("${spring.application.name}") String applicationName) {
        return (registry) -> registry.config().commonTags("application", applicationName);
    }

    @Bean
    TimedAspect timedAspect(MeterRegistry registry) {
        return new TimedAspect(registry);
    }
}

I need to create custom actuator endpoint metrics for per day student creation count so that I can plot its graph using Grafana. The rollNo is an auto-generated field so it will give me a count of the total student.

How to create custom metrics in Spring Boot?

Thanks in advance.

informatik01
  • 16,038
  • 10
  • 74
  • 104
shrikant.sharma
  • 203
  • 1
  • 17
  • 37
  • You just made statements, didn't ask a question. What does this code currently do? Why is that wrong or incomplete? What specific answers do you need from readers? – underscore_d Jun 12 '20 at 10:28
  • Hi, I have updated the question, I need to create custom metrics for my per day student creation count. so that I can plot the graph on grafana. – shrikant.sharma Jun 12 '20 at 10:38
  • You just create a counter to the student creation. It will count all creation. Then in Graphana, group it by `time(1d)`. You do not need to create custom endpoint, just register the counter to micrometer. `actuator/prometheus` endpoint will expose the registered counter with the others automaticaly. – zlaval Jun 12 '20 at 10:45
  • hi, how to do that, I am new in this thing. – shrikant.sharma Jun 12 '20 at 13:24

1 Answers1

3

Since you are working with Prometheus, a prometheusMeterRegistry bean is automatically registered.

In your Controller class, you need to autowire the prometheusMeterRegistry bean. The following will do:

@Autowired
MeterRegistry registry;

Then you can register a counter to the registry and increment it using

Counter counter = registry.counter(counterName);
counter.increment();

See Micrometer docs for more details.

Jackson
  • 362
  • 3
  • 10