CodeGym /Courses /Module 5. Spring /Lecture 119: Setting up custom metrics in Spring Boot

Lecture 119: Setting up custom metrics in Spring Boot

Module 5. Spring
Level 19 , Lesson 8
Available

Today we're diving into the world of custom metrics. Metrics are like little spies inside your app that tell you what's going on: how many users visited the site, how many orders were placed, and even how many times the cat pressed the "buy food" button. We'll see why you need this, how it works, and how to implement real "personalized" metrics that fit your business.


Why might you need custom metrics?

Real life rarely fits into the standard metrics Actuator provides. For example, you might want to measure:

  • How many times users add an item to the cart.
  • How long a specific business process takes.
  • The number of successfully processed orders in the last hour.
  • The percentage of successful vs failed login attempts.

Custom metrics are necessary so your monitoring matches your app's specifics. For example, if you're building an online store, tracking purchase conversion is important, while a streaming service needs to know which movies/series are most popular.


Using Micrometer for custom metrics

If Spring Boot Actuator is the "Swiss Army knife" for monitoring, Micrometer is its "blade". Micrometer is the library integrated into Actuator that lets you collect and export metrics to various monitoring systems like Prometheus, New Relic, Graphite, and others.

To create custom metrics you'll need to:

  1. Add Actuator (if you haven't already).
  2. Use the Micrometer API to register and track your own metrics.

Connecting Actuator and Micrometer

First, make sure your project has the required dependencies. Add them to your pom.xml or build.gradle.

Maven:


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId> <!-- For integration with Prometheus -->
</dependency>

Gradle:


implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus' // For Prometheus

Don't forget to configure Actuator in application.properties. For example:

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

Implementing custom metrics

Now for the fun part: how to register your own metrics!

Example 1: counting orders

Imagine we have an online store app and we want to track the number of successfully processed orders. We'll create a Counter.


import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    private final Counter orderCounter;

    public OrderService(MeterRegistry meterRegistry) {
        // Register the counter
        this.orderCounter = meterRegistry.counter("orders.processed");
    }

    public void processOrder(String orderId) {
        // Order processing logic goes here
        System.out.println("Processing order: " + orderId);

        // Increment the counter on successful order processing
        orderCounter.increment();
    }
}

Now, whenever processOrder() is called, our orders.processed counter increments by one. You can view this metric via /actuator/metrics/orders.processed.


Example 2: measuring operation duration

Sometimes it's important to know how long operations take. For that we can use Timers (Timer).


import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class FileProcessingService {

    private final Timer fileProcessingTimer;

    public FileProcessingService(MeterRegistry meterRegistry) {
        // Register the timer
        this.fileProcessingTimer = meterRegistry.timer("file.processing.time");
    }

    public void processFile(String fileName) {
        // Measure the operation duration
        long startTime = System.nanoTime();
        try {
            System.out.println("Processing file: " + fileName);
            Thread.sleep(200); // Simulate file processing
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            long endTime = System.nanoTime();
            fileProcessingTimer.record(endTime - startTime, TimeUnit.NANOSECONDS);
        }
    }
}

When you process a file through this service, the file.processing.time metric will contain information about the task's duration.


Example 3: creating a custom Gauge

Gauge lets you track the current state of some value. For example, you can track the number of items in a certain collection.


import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ActiveUsersService {

    private final List<String> activeUsers = new ArrayList<>();

    public ActiveUsersService(MeterRegistry meterRegistry) {
        // Register a Gauge to track the number of active users
        meterRegistry.gauge("active.users.count", activeUsers, List::size);
    }

    public void userLoggedIn(String username) {
        activeUsers.add(username);
    }

    public void userLoggedOut(String username) {
        activeUsers.remove(username);
    }
}

The active.users.count metric will update automatically as the size of the activeUsers list changes.


Practical task: your custom metrics

  1. Add a metric to count calls to some API (for example, the API that adds items to the cart).
  2. Set up a timer to measure the duration of a complex business operation.
  3. Create a Gauge to track the current value of a business metric (for example, the number of active orders).

Common pitfalls and nuances

Some common mistakes when setting up custom metrics:

  • Incorrect use of Counter or Timer. For example, don't use Counter for values that can decrease. Use Gauge for that.
  • Too many metrics. Always ask yourself: "Do I really need this metric?" If you have a million custom metrics, it can impact your app's performance.
  • Uninformative metric names. Try to name metrics so it's clear what they measure. For example, orders.processed is better than op.proc.

Where do we go from here?

Now that you know how to create custom metrics, you can integrate them with external monitoring systems like Prometheus or Grafana so your business metrics become not just data, but nice graphs and useful analytics. Just imagine how great it'd be to see conversion growth or optimized task execution times in real time!

For those who want to dive deeper, check out the Micrometer documentation — a great place to find inspiration and extra features.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION