Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions jdk_8_maven/cs/rest/original/spring-actuator-demo/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Spring Boot Actuator: Health Check, Auditing, Metrics Gathering and Monitoring

## Tutorials

1. [Spring Boot Actuator: Health check, Auditing, Metrics gathering and Monitoring](https://www.callicoder.com/spring-boot-actuator/)
2. [Spring Boot Actuator metrics monitoring with Prometheus and Grafana](https://www.callicoder.com/spring-boot-actuator-metrics-monitoring-dashboard-prometheus-grafana/)

## Steps to Setup

**1. Clone the application**

```bash
git clone https://github.com/callicoder/spring-boot-actuator-demo.git
```

**2. Build and run the app using maven**

```bash
mvn package
java -jar target/actuator-demo-0.0.1-SNAPSHOT.jar
```

Alternatively, you can run the app directly without packaging like this -

```bash
mvn spring-boot:run
```

The app will start running at <http://localhost:8080>.

## Explore Actuator Endpoints

All the actuator endpoints will be available at <http://localhost:8080/actuator>.

Some of the actuator endpoints are protected with Spring Security's HTTP Basic Authentication. You can use the username `actuator` and password `actuator` for http basic authentication.
72 changes: 72 additions & 0 deletions jdk_8_maven/cs/rest/original/spring-actuator-demo/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>actuator-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>actuator-demo</name>
<description>Spring Boot Actuator Demo Project</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Micrometer Prometheus registry -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

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


</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.example.actuatordemo.config;

import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.context.ShutdownEndpoint;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {

/*
This spring security configuration does the following

1. Restrict access to the Shutdown endpoint to the ACTUATOR_ADMIN role.
2. Allow access to all other actuator endpoints.
3. Allow access to static resources.
4. Allow access to the home page (/).
5. All other requests need to be authenticated.
5. Enable http basic authentication to make the configuration complete.
You are free to use any other form of authentication.
*/

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))
.hasRole("ACTUATOR_ADMIN")
.requestMatchers(EndpointRequest.toAnyEndpoint())
.permitAll()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.antMatchers("/", "/slowApi")
.permitAll()
.antMatchers("/**")
.authenticated()
.and()
.httpBasic();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.example.actuatordemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@RestController
public class SampleController {

@GetMapping("/")
public String sayHello(@RequestParam(value = "name", defaultValue = "Guest") String name) {
return "Hello " + name + "!!";
}

@GetMapping("/slowApi")
public String timeConsumingAPI(@RequestParam(value = "delay", defaultValue = "0") Integer delay) throws InterruptedException {
if(delay == 0) {
Random random = new Random();
delay = random.nextInt(10);
}

TimeUnit.SECONDS.sleep(delay);
return "Result";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.actuatordemo.health;

import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;

@Component
public class CustomHealthIndicator extends AbstractHealthIndicator {

@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
// Use the builder to build the health status details that should be reported.
// If you throw an exception, the status will be DOWN with the exception message.

builder.up()
.withDetail("app", "Alive and Kicking")
.withDetail("error", "Nothing! I'm good.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Logging
logging.file=app.log

# Spring Security default user name and password
spring.security.user.name=actuator
spring.security.user.password=actuator
spring.security.user.roles=ACTUATOR_ADMIN

# INFO ENDPOINT CONFIGURATION
info.app.name=@project.name@
info.app.description=@project.description@
info.app.version=@project.version@
info.app.encoding=@project.build.sourceEncoding@
info.app.java.version=@java.version@

# SHUTDOWN ENDPOINT (ShutdownEndpoint)
management.endpoint.shutdown.enabled=true

# HEALTH ENDPOINT
management.endpoint.health.show-details=always

# ENDPOINTS WEB CONFIGURATION
management.endpoints.web.exposure.include=*
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'

# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.

static_configs:
- targets: ['127.0.0.1:9090']

- job_name: 'spring-actuator'
metrics_path: '/actuator/prometheus'
scrape_interval: 5s
static_configs:
- targets: ['HOST_IP:8080']
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.actuatordemo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ActuatorDemoApplicationTests {

@Test
public void contextLoads() {
}

}