Spring Boot Actuator

  1. Actuator is a Spring Boot module that exposes operational information about a running application through ready-made HTTP endpoints.
  2. It is used to monitor and troubleshoot an application: is it up, is the database connected, how much memory is used, which URLs and beans exist.
  3. You add one dependency (spring-boot-starter-actuator) and the endpoints appear under /actuator, with no code to write.
  4. Monitoring tools, load balancers and Kubernetes use the same endpoints to check whether the application is healthy.

Features

  • Reports application and database health (UP or DOWN).
  • Shows application information such as name, description and version.
  • Exposes metrics: JVM memory, CPU, threads, and HTTP request counts and timing.
  • Lists all URL mappings, Spring beans and configuration properties.
  • Shows and changes logger levels while the application is running.
  • Lets you choose which endpoints are exposed over HTTP.

Actuator Endpoints

Endpoint What it shows
/actuator List of all exposed endpoints with links.
/actuator/health Application status, including the MySQL database and disk space.
/actuator/info Application details from the info.* properties.
/actuator/metrics List of all metric names.
/actuator/metrics/{name} Value of one metric, such as jvm.memory.used or http.server.requests.
/actuator/env Environment and configuration properties.
/actuator/beans Every Spring bean in the application context.
/actuator/mappings Every URL mapping, with the controller method that handles it.
/actuator/loggers Logger names and their current levels.
/actuator/configprops Values bound to @ConfigurationProperties classes.
/actuator/conditions Which auto-configurations were applied and why.
/actuator/threaddump The state of all running threads.

Exposure settings in application.properties

  • management.endpoints.web.exposure.include chooses which endpoints are available over HTTP. By default only health is exposed.
  • management.endpoint.health.show-details=always shows the database and disk details, not just UP.
  • management.info.env.enabled=true makes /actuator/info display the info.* properties.
  • management.endpoint.env.show-values=ALWAYS shows real values in /actuator/env. This is for learning only, because it also reveals the database password.

Hands-on Experiment: Creating a spring boot application to understand how Actuator exposes operational information about a running Spring Boot application.

The following steps are involved in developing this hands-on experiment.

Step 1: Generate the Project

Step 2: Project Structure

Step 3: pom.xml

Step 4: application.properties

Step 5: Create Entity Class

Step 6: Create Repository Interface

Step 7: Create Service Class

Step 8: Create Controller Class

Step 9: Main Application Class

Step 10: Run the Main Application Class

Step 1: Configure the Project on Spring Initializr

Go to start.spring.io and set:

  • Project: Maven
  • Language: Java
  • Spring Boot version: 3.2.x
  • Group: com.example
  • Artifact: actuatordemo
  • Name: actuatordemo
  • Package name: com.example.actuatordemo
  • Packaging: Jar
  • Java: 17
  • Dependencies: Spring Web, Spring Data JPA, MySQL Driver, Actuator.

Click Generate to download the ZIP, then extract and import it into your IDE as a Maven project.

Step 2: Generated Project Structure

Step 3: Explore pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>student-actuator-demo</artifactId>
    <version>1.0.0</version>
    <name>student-actuator-demo</name>
    <description>Spring Boot Actuator added to the Student application</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- Adds the /actuator endpoints -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Step 4: application.properties

spring.application.name=student-actuator-demo
server.port=8082

# MySQL (database is created automatically if it does not exist) - change username/password as needed
spring.datasource.url=jdbc:mysql://localhost:3306/studentdb?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=password

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

# ---------- Actuator settings ----------
# By default only "health" is exposed over HTTP. Expose the endpoints we want to explore.
management.endpoints.web.exposure.include=health,info,metrics,env,beans,mappings,loggers,configprops,conditions,threaddump

# Show full health details (database, disk space) instead of just UP/DOWN
management.endpoint.health.show-details=always

# Show real values in /actuator/env (LEARNING ONLY - this also reveals the database password!)
management.endpoint.env.show-values=ALWAYS

# Make the "info" endpoint show the info.* properties below
management.info.env.enabled=true
info.app.name=Student Application
info.app.description=Student CRUD application with Spring Boot Actuator
info.app.version=1.0.0
info.developer.name=devCode language: PHP (php)

Step 5: Create Entity Class

package com.example.actuatordemo.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "students")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Column(unique = true)
    private String email;

    private String department;

    public Student() {
    }

    public Student(String name, String email, String department) {
        this.name = name;
        this.email = email;
        this.department = department;
    }

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }

    public String getDepartment() { return department; }
    public void setDepartment(String department) { this.department = department; }
}

Step 6: Create below Repository Interface

package com.example.actuatordemo.repository;

import com.example.actuatordemo.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {

    boolean existsByEmail(String email);
}

Step 7: Create below Service class

package com.example.actuatordemo.service;

import com.example.actuatordemo.entity.Student;
import com.example.actuatordemo.repository.StudentRepository;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;

@Service
public class StudentService {

    private final StudentRepository studentRepository;

    public StudentService(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }

    public Student addStudent(Student student) {
        if (studentRepository.existsByEmail(student.getEmail())) {
            throw new ResponseStatusException(HttpStatus.CONFLICT,
                    "Email already registered: " + student.getEmail());
        }
        return studentRepository.save(student);
    }

    public List<Student> getAllStudents() {
        return studentRepository.findAll();
    }

    public Student getStudentById(Long id) {
        return studentRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,
                        "Student not found with id: " + id));
    }

    public Student updateStudent(Long id, Student updated) {
        Student existing = getStudentById(id);
        existing.setName(updated.getName());
        existing.setDepartment(updated.getDepartment());
        return studentRepository.save(existing);
    }

    public void deleteStudent(Long id) {
        if (!studentRepository.existsById(id)) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Student not found with id: " + id);
        }
        studentRepository.deleteById(id);
    }
}

Step 8: Create Controller class

package com.example.actuatordemo.controller;

import com.example.actuatordemo.entity.Student;
import com.example.actuatordemo.service.StudentService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/students")
public class StudentController {

    private final StudentService studentService;

    public StudentController(StudentService studentService) {
        this.studentService = studentService;
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Student addStudent(@RequestBody Student student) {
        return studentService.addStudent(student);
    }

    @GetMapping
    public List<Student> getAllStudents() {
        return studentService.getAllStudents();
    }

    @GetMapping("/{id}")
    public Student getStudentById(@PathVariable Long id) {
        return studentService.getStudentById(id);
    }

    @PutMapping("/{id}")
    public Student updateStudent(@PathVariable Long id, @RequestBody Student student) {
        return studentService.updateStudent(id, student);
    }

    @DeleteMapping("/{id}")
    public String deleteStudent(@PathVariable Long id) {
        studentService.deleteStudent(id);
        return "Student deleted with id: " + id;
    }
}

Step 9: Main Application

package com.example.actuatordemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ActuatorDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(ActuatorDemoApplication.class, args);
    }
}

Step 10: Run the ActuatorDemoApplication

Scroll to Top