Spring Boot Monitoring Flashcards
Reference Project
Spring Pet Clinic - Visits Service
MetricConfig.java
MetricConfig.java
@Configuration
public class MetricConfig {
@Bean
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config().commonTags("application", "petclinic");
}</MeterRegistry>
@Bean
TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
Annotate the class with @Configuration. This annotation indicates that MetricConfig is a Spring configuration class, where beans are defined.
Customizes the MeterRegistry by applying common tags (key-value pairs, application:pet-clinic) to all metrics generated by the application.
TimedAspect - Intercepts method calls annotated with @Timed.
You do not need to explicitly invoke the metricsCommonTags method in your configuration class. In Spring, methods annotated with @Bean are automatically managed by the Spring IoC container. The metricsCommonTags method will be invoked by Spring during the application startup to create and configure the MeterRegistryCustomizer bean.
Filtering by tags in Prometheus
To filter metrics by the tags (labels) like application=petclinic in Prometheus, you can use PromQL (Prometheus Query Language).
Filter All Metrics for application=petclinic
{application=”petclinic”}
Filtering Specific Metrics
http_server_requests_seconds_count{application=”petclinic”}
Filtering with Multiple Tags
http_server_requests_seconds_sum{application=”petclinic”, method=”GET”}
Grouping and Aggregation
Prometheus allows you to group and aggregate metrics by specific labels.
sum(http_server_requests_seconds_count) by (application) - Sums up the request counts and groups the result by the application label.
@Timed annotation
The @Timed annotation is typically used in the Micrometer metrics library, which is commonly integrated with Spring Boot to measure the duration of specific methods or operations.
Scope - Can be applied at the method or class level.
Attributes
value - Custom name for the timer metric
description - Description of the metric
extraTags - Additional tags to be associated with the metric
longTask - Whether to create a long-task timer
Ex @Timed(value = “example.method.timed”, description = “Time taken to execute exampleMethod”)
A long-task timer is a specialized type of timer in Micrometer used to measure the duration of tasks that run for an extended period, such as background jobs, batch processing, or workflows. Unlike standard timers, which measure the duration of short-lived operations (e.g., method calls), long-task timers allow you to monitor ongoing tasks and report their state while they are still in progress.
@Counted
Example
@RestController
public class LoginController {
@Counted(value = "login.attempts", description = "Number of login attempts") @GetMapping("/login") public String login(@RequestParam String username, @RequestParam String password) { } } When you hit the /login endpoint, the Prometheus metrics might look like this: login_attempts_total 5.0
It counts how many times the annotated method has been called since the application started.
If you want to know how many calls are happening per second, you would need to rely on rate calculations provided by the monitoring system (like Prometheus) over time.
Prometheus can calculate the rate of calls per second using the rate() function. For example, to see the number of calls per second for the login.attempts counter, you could query:
rate(login_attempts_total[1m]) - This will give you the rate of calls per second over the last 1 minute.
Auto-Configuration
You do not need to manually add any beans to the Spring application context for using @Counted or @Timed. Both annotations are part of Micrometer, which integrates seamlessly with Spring Boot through Spring Boot Actuator and Micrometer’s auto-configuration.
Micrometer Auto-Configuration: When you include Micrometer dependencies in your Spring Boot project (like micrometer-core and spring-boot-starter-actuator), Spring Boot automatically configures the necessary beans to handle metrics collection. This includes support for @Counted, @Timed, @Gauge, and other Micrometer annotations.
why @Bean TimedAspect
The reason you need to manually define a @Bean for TimedAspect is that @Timed works a little differently from other Micrometer annotations like @Counted, @Gauge, and @Metered. Micrometer uses an aspect-oriented programming (AOP) approach to apply the behavior of @Timed, which is why it requires the TimedAspect bean to enable this functionality.
In contrast, @Counted and similar annotations do not require such an aspect bean, as they are automatically handled by Micrometer without requiring AOP or custom configuration.
PromoQL - Basic Components
Metric Name: The name of the metric you want to query. For example, http_requests_total is a metric that tracks the total number of HTTP requests.
Labels: Metrics are often associated with labels, which are key-value pairs used to differentiate between time-series data. For example, a metric like http_requests_total{status=”200”, method=”GET”} will have labels status=”200” and method=”GET”.
Selectors: You can query specific time-series by filtering on label values using a selector. For example: http_requests_total{status=”200”}: Fetches the http_requests_total metric where the status is “200”.
Operators : PromQL supports a range of operators for working with time-series data, Ex rate(), sum()
PromoQL - Filtering by Label
http_requests_total{status=”500”}
PromoQL - Aggregation functions
sum(http_requests_total) - sum of a metric across all time-series
PromoQL - Rate function
rate(http_requests_total[5m]) - This calculates the per-second rate of http_requests_total over the last 5 minutes.
PromoQL - Time Range Query
avg(rate(cpu_usage_seconds_total[1h])) - This query calculates the average per-second rate of cpu_usage_seconds_total over the past hour.
PromoQL - Comparison
http_requests_total > 100 This will return all time-series where the value of http_requests_total is greater than 100
PromoQL - Grouping by Labels:
sum(http_requests_total) by (status) This will give you the total number of HTTP requests, grouped by the status label (e.g., “200”, “404”, etc.).