Showing posts with label Grafana. Show all posts
Showing posts with label Grafana. Show all posts

9/17/2025

Hands-On Guide: Monitoring Spring Boot on Kubernetes with Prometheus & Grafana

 



Effective monitoring is the backbone of reliable systems. In a Kubernetes world full of microservices, being able to track performance, resource usage, and health is not optional—it’s essential for debugging, scaling, and maintaining stable services.

In this guide, we’ll build a complete monitoring stack around a Spring Boot app, running locally on Kubernetes via Minikube. We’ll use:

  • Prometheus for metrics collection

  • Grafana for dashboards

  • Helm to simplify installation

By the end, you’ll have a fully working monitoring setup—perfect for local experiments and a foundation for production deployments.


Technology Stack

  • Minikube → single-node Kubernetes cluster for local development

  • Spring Boot → demo application exposing metrics via Actuator + Micrometer

  • Prometheus → scrapes metrics from services, stores them as time-series

  • Grafana → visualizes metrics with dashboards

  • Helm → package manager for Kubernetes apps


Prerequisites

Install these tools before you start:


Step 1: Start a Local Kubernetes Cluster


Check out the demo git repository: https://github.com/dhanuka84/grafana-prometheus-app-monitoring


Use the provided script:

cd scripts

./start-minikube.sh


This boots a Minikube cluster with 4 CPUs and 8GB RAM—a solid baseline for Prometheus + Grafana.



Step 2: Install the Monitoring Stack (Grafana + Prometheus)


With our cluster running, the next step is to deploy the kube-prometheus-stack Helm chart. This chart is a community-managed collection that bundles Prometheus, Grafana, and other necessary components (like Alertmanager and Prometheus Operator) into a single, manageable package.

The install.sh script handles this for us.


Bash



# From the scripts directory
./install.sh

This script does two key things:

  1. Adds the prometheus-community Helm repository.

  2. Installs the kube-prometheus-stack chart into a dedicated monitoring namespace in our cluster.

The Prometheus Operator, which is part of this stack, is particularly important. It introduces custom resource definitions (CRDs) like ServiceMonitor, which allows Prometheus to dynamically discover and scrape new services without manual configuration changes.



Step 3: Prepare the Spring Boot Application


The sample application in the app directory is a simple Spring Boot web service. Let's look at the key parts that enable monitoring.

1. Dependencies (pom.xml):

The magic starts with two key dependencies:

  • spring-boot-starter-actuator: This adds production-ready features like health checks and metrics endpoints.

  • micrometer-registry-prometheus: This provides the necessary Micrometer backend to format the metrics in a way that Prometheus can understand.

2. Configuration (application.yml):

We need to tell the Actuator to expose the Prometheus endpoint.


YAML



management:
  endpoints:
    web:
      exposure:
        include: "prometheus,health"

This configuration exposes the /actuator/prometheus endpoint, which will be scraped by our Prometheus server.

3. Containerization (Dockerfile):

The Dockerfile is standard for a Java application. It builds the project and packages the resulting JAR file into a container image.


3.1. Spring Boot Actuator: The Framework

What it is: Actuator is a Spring Boot sub-project that adds production-ready features to your application. It provides built-in endpoints for monitoring and managing your app.

How it's used here:

Dependency: The pom.xml file includes the core dependency that brings this functionality into the project.


XML


<!-- File: app/pom.xml -->

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-actuator</artifactId>

</dependency>


Endpoint Exposure: The application.yml file tells Actuator which of its powerful endpoints should be made available over HTTP. In this project, it specifically exposes the /actuator/prometheus and /actuator/health endpoints.
YAML
# File: app/src/main/resources/application.yml

management:

  endpoints:

    web:

      exposure:

        include: "prometheus,health"


In short: Actuator creates the /actuator/prometheus endpoint that Prometheus will visit.

3.2. Micrometer: The Metrics Collector & Formatter

What it is: Micrometer is an instrumentation library that acts as a facade for various monitoring systems. It captures application metrics (like JVM memory, CPU usage, HTTP request times) in a standardized way.

How it's used here: The magic happens with this specific dependency in the pom.xml:

XML

<!-- File: app/pom.xml -->

<dependency>

    <groupId>io.micrometer</groupId>

    <artifactId>micrometer-registry-prometheus</artifactId>

    <scope>runtime</scope>

</dependency>


This library does two critical things:

  1. Collects Metrics: It automatically gathers a wide range of useful metrics from the application.

  2. Formats for Prometheus: It acts as a "translator." It takes the metrics it has collected and formats them into the specific plain-text format that the Prometheus server is designed to scrape and understand.

Analogy: How They Work Together

Think of it like a specialty food shop:

  • Spring Boot Actuator is the shop itself. It provides the storefront window (/actuator/prometheus) where customers can look in. The application.yml config is the "Open" sign on the door.

  • Micrometer is the chef inside the shop who prepares all the food (gathers all the metrics).

  • micrometer-registry-prometheus is the menu in the window, written in a language that a specific customer (the Prometheus server) can read perfectly.

When the Prometheus server "visits" the /actuator/prometheus endpoint, it reads the Micrometer-provided menu and gets all the performance data it needs.



Step 4: Deploy the Application to Kubernetes


Now it's time to deploy our instrumented Spring Boot application into the cluster. The deploy.sh script automates this process.


Bash



# From the scripts directory
./deploy.sh




This script performs several actions:

  1. Builds the Docker Image: It navigates to the app directory and builds the Docker image for our Spring Boot application.

  2. Loads the Image into Minikube: It pushes the newly built image directly into Minikube's internal Docker registry, making it available to the cluster.

  3. Applies Kubernetes Manifests: It applies to all the YAML files located in the k8s directory.

Let's break down the most important manifest, servicemonitor-demo.yaml:


YAML



apiVersion: [monitoring.coreos.com/v1](https://monitoring.coreos.com/v1)
kind: ServiceMonitor
metadata:
  name: demo-metrics-servicemonitor
  namespace: apps
  labels:
    release: prometheus # Must match the Prometheus Operator's label
spec:
  selector:
    matchLabels:
      app: demo-metrics # Selects the Service for our app
  endpoints:
  - port: http
    path: /actuator/prometheus # Specifies the metrics path
    interval: 15s

This ServiceMonitor object is the glue between our application and Prometheus. It tells the Prometheus Operator: "Find any Service with the label app: demo-metrics, and start scraping metrics from its http port on the /actuator/prometheus path every 15 seconds."


Step 5: Access Prometheus and Grafana


Our entire stack is now running! To access the UIs, the port-forward.sh script creates secure tunnels from your local machine to the services running inside the Minikube cluster.

Run the script in a new terminal window, as it will run continuously:


Bash



# From the scripts directory
./port-forward.sh

You can now access:

Log in to Grafana with the default credentials:

  • Username: admin

  • Password: admin123


Make sure below target is up and running



Step 6: Install SpringBoot Grafana Dashboard: Auto-Load with ConfigMap

If you want the dashboard to survive pod restarts or redeploys, create a ConfigMap with the JSON definition:

Bash

# From the root directory
./scripts/dashboard-install.sh 


Because your Helm chart has the Grafana sidecar enabled (grafana.sidecar.dashboards.enabled=true), Grafana automatically loads this dashboard.

Now you can click the SpringBoot dashboard and visualize the metrics




Step 7: Visualize Your Application Metrics


Once logged into Grafana, you can explore the metrics from our Spring Boot application. The kube-prometheus-stack comes with several pre-configured dashboards.

  1. Navigate to Dashboards (four squares icon) on the left menu.

  2. Find a dashboard related to JVM metrics, often named something like "JVM (Micrometer)".

  3. At the top of the dashboard, you may need to select your application from a dropdown menu (e.g., select the demo-metrics job).


You should now see a rich set of visualizations for your application's performance, including:

  • JVM Memory Usage (Heap and Non-Heap)

  • CPU Usage

  • Garbage Collection statistics

  • HTTP Server Requests (count, latency)



Conclusion


Congratulations! You have successfully deployed a complete monitoring stack for a Spring Boot application on a local Kubernetes cluster. You've learned how to:

  • Instrument a Spring Boot app with Actuator and Micrometer.

  • Deploy the industry-standard kube-prometheus-stack using Helm.

  • Dynamically link Prometheus to your application using a ServiceMonitor.

  • Visualize real-time metrics in a Grafana dashboard.

This local setup provides a powerful and safe environment to experiment with custom metrics, build your own Grafana dashboards, and learn how to configure alerts—skills that are directly transferable to production environments.