Monitor Spring Boot applications with Nightingale
Add Actuator and micrometer-registry-prometheus and the application exposes /actuator/prometheus itself; the template ships JVM dashboards split by application name.
Last reviewed
Spring Boot applications need no external agent. Add the spring-boot-starter-actuator and micrometer-registry-prometheus dependencies, expose the prometheus endpoint, and the application serves JVM, HTTP request, datasource pool, executor and custom metrics on /actuator/prometheus. Actuator is built on Micrometer underneath.
The two JVM dashboards are written against Actuator metric names (jvm_memory_used_bytes, http_server_requests_seconds and so on); one of them separates services by the application label. The rules cover heap near the limit, long GC pauses, rising HTTP 5xx and abnormal thread counts.
What's in the template
- 2 dashboards, 71 panels in total
- 5 alert rules, each with runbook steps
How to connect
For Spring Boot 3.x, add to application.properties:
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.prometheus.metrics.export.enabled=true
On 2.x the last line is management.metrics.export.prometheus.enabled=true. Check that http://localhost:8080/actuator/prometheus responds, then scrape it with the Categraf prometheus input and set an application label to the service name. Do not set exposure.include to *.
- Open the integration center in Nightingale, find SpringBoot, and import the dashboards and alert rules into a business group.
- Imported rules start disabled. Check that the metrics are arriving first, then enable the rules one by one with thresholds that fit your environment.
Bundled dashboards
| Dashboard | Panels |
|---|---|
| JVM (Actuator) with application name | 37 |
| JVM Dashboard | 34 |
Bundled alert rules
5 rules. Each lists its trigger condition (PromQL) and the steps to take when it fires. Thresholds are meant to be adjusted after import.
SpringBoot heap memory usage above 85%
S2 Warning · for 1 min · Trigger:
sum by (instance) (jvm_memory_used_bytes{area="heap"}) * 100 / sum by (instance) (jvm_memory_max_bytes{area="heap"}) > 85
Runbook:
- Check jvm_gc_pause_seconds to see whether full GC became more frequent and how long the pauses are;
- Capture a heap with jmap -histo:live <pid> or the arthas heapdump, then sort by object count to find the abnormally growing classes;
- Tell traffic growth (raise -Xmx) apart from a memory leak (must be fixed in code — a bigger heap only postpones it);
- You can restart the instance to recover, but capture the heap snapshot first or you lose the evidence.
SpringBoot HTTP request latency exceeds 10s
S2 Warning · for 1 min · Trigger:
max by (instance, uri) (http_server_requests_seconds_max{status!~"5.."}) > 10
Runbook:
- Take uri from the alert labels to identify the endpoint;
- Use arthas trace or APM distributed tracing to see which segment consumes the time (database, downstream RPC, or local computation);
- For a slow database, follow the slow-query path and add indexes; for a slow downstream, check its state and add a circuit breaker or fallback;
- Check whether the thread pool is saturated by slow requests and amplifying the queue — isolate the pool if so.
SpringBoot HTTP errors
S2 Warning · for 1 min · Trigger:
sum by (instance, uri) (rate(http_server_requests_seconds_count{status=~"5.."}[5m])) > 0
Runbook:
- Take uri from the alert labels to identify the endpoint, then search the application log for stack traces on that path;
- Tell total failure from partial failure — partial failure usually means one bad downstream instance or a data edge case;
- If it lines up with a recent release, roll back rather than keep investigating;
- Check whether downstream dependencies (database, cache, third-party APIs) are failing at the same time.
SpringBoot non-heap memory usage above 85%
S2 Warning · for 1 min · Trigger:
sum by (instance) (jvm_memory_max_bytes{area="nonheap"}) > 0 and sum by (instance) (jvm_memory_used_bytes{area="nonheap"}) * 100 / sum by (instance) (jvm_memory_max_bytes{area="nonheap"}) > 85
Runbook:
- Run jcmd <pid> VM.native_memory summary (requires NativeMemoryTracking) or the arthas memory command to see each region's usage;
- Steadily growing Metaspace usually means a class loader leak — common with repeated hot deploys, dynamic proxies and script engines;
- As an emergency measure raise -XX:MaxMetaspaceSize and restart;
- For the root cause, look for a custom ClassLoader that is never released, and check jmap -clstats for an abnormal class loader count.
SpringBoot event errors
S2 Warning · for 1 min · Trigger:
sum by (instance) (increase(logback_events_total{level="error"}[5m])) > 0
Runbook:
- Take instance from the alert labels, then search your log system for ERROR-level stack traces in that time window;
- Group by exception type to tell an intermittent problem (downstream jitter, timeout retries) from a reproducible one (code bug, misconfiguration);
- Fix reproducible ones in code; for intermittent ones confirm retry and fallback logic actually works;
- If the ERROR volume spiked in line with a release, roll back first.
Related
- SpringBoot template source: the raw JSON for dashboards, rules and collector config. Pull requests welcome.
- Walkthrough: monitor Java applications
- Import dashboards and alert rules
- Verify that metrics are stored
- All integrations