stickman holding flower
linkedin logo
github logo

%0

eurasian blackbird

Monitoring a dockerized spring boot application

with prometheus and grafana

March, 12th. 2024

Monitoring a dockerized spring boot application
I have a digital ocean droplet that runs my dockerized dictionary application’s backend . It is just a stand alone container. I decided to add monitoring to it and we are here.
  • 1. My application should expose some metrics.
  • 2. Prometheus and Grafana instances should be deployed as containers. Prometheus should be able to collect metrics from the application.
  • 3. Grafana should use this prometheus as data source and be able to create dashboards.
Let's start from the application side
There could be many options but I wanted to go with the easiest way: actuator. For this path, first I needed to add two libraries to my application:
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
	<groupId>io.micrometer</groupId>
	<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
ai representative woman
The spring-boot-starter-actuator library provides a set of built-in endpoints and tools for monitoring and managing your Spring Boot application. It includes features such as health checks, metrics, environment information, and more, which are exposed via HTTP endpoints.
By adding micrometer-registry-prometheus to your Spring Boot application, you enable it to export metrics in a format that Prometheus can scrape and store.
Spring boot has autoconfiguration for many libraries but here we must indicate which endpoints we want to expose. In application.properties file, add:
management.endpoints.web.exposure.include=health,prometheus,metrics
That’s all for the application part. I should now see some metrics at: /actuator/metrics endpoint. You can inspect other endpoints too.
Deploying Prometheus and Grafana instances
For these two brothers, I needed to create a docker-compose.yml file.
version: "3.0"
services:
  prometheus:
    image: prom/prometheus:v2.35.0
    container_name: prometheus
    restart: unless-stopped
    ports:
      - 9090:9090
    volumes:
      - ./data/prometheus/config:/etc/prometheus/
      - ./prometheusConfig.yml:/prometheusConfig.yml
    command:
      - '--config.file=/prometheusConfig.yml'
    networks:
      - hachiko-network
  grafana:
    image: grafana/grafana-oss:8.5.2
    container_name: grafana
    restart: unless-stopped
    ports:
      - 3000:3000
    volumes:
      - ./data/grafana:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
      - GF_SERVER_DOMAIN=localhost
    user: "$UID:$GID"
    networks:
      - hachiko-network
networks:
  hachiko-network:
    driver: bridge
and I put prometheusConfig.yml in the same directory on the server:
global:
  scrape_interval: 1m
  evaluation_interval: 1m 
 
 
scrape_configs:
  - job_name: 'hachiko-dictionary'
    scrape_interval: 1m
    scrape_timeout: 1m
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets:
        - hachiko-dictionary:8080
  - job_name: 'prometheus'
    scrape_interval: 1m
    scrape_timeout: 1m
    static_configs:
    - targets:
      - prometheus:9090
First of all, notice the network definitions. I needed to create a network to enable service-to-service communication using container names.
Secondly, see that my app runs on port :8080 as many other spring boot application out there.
Finally, in the grafana definition I put user: "$UID:$GID" to get it working. Otherwise it threw permission errors. It may not be needed in a self-hosted environment, but i needed it in this Digital Ocean droplet.
ai representative woman
In the provided Docker Compose configuration for Prometheus, the volumes line is used to mount the configuration file (prometheusConfig.yml) and the configuration directory (./data/prometheus/config) into the Prometheus container. This allows you to customize the Prometheus configuration and store it outside of the container, making it easier to manage and update the configuration. The command line is used to specify the location of the configuration file within the container. The networks line is used to specify the network that the Prometheus container should be connected to. This allows the Prometheus container to communicate with other containers on the same network using their container names.
After running this docker file with command: docker compose up -d , I had the containers up and running. My app, prometheus, and grafana:
terminal showing docker instances running

terminal showing docker instances running

Now, I needed to check if prometheus is able to scrape my application. I went to server-ip:9090/targets and saw that my application was up and running:
prometheus ui running two instances running

prometheus ui running two instances running

Looks like it’s time to go to the Grafana.
Setting up Grafana
When I hit server-ip:3000 , I saw a login screen. Default credentials are admin and admin. After logging in, I added a new data source. I selected prometheus and entered url as server-ip:9090. I did not change anything else and clicked Save & test. If you see a green notification, you are almost done.
It is time to create dashboards. https://grafana.com/grafana/dashboards/ has some ready to go dashboards. So I picked the dashboard with id 4701 . Copy it and enter when creating dashboard. Select the newly created data source and viola! You have a dashboard.
grafana dashboard seems working

grafana dashboard seems working