原文參考:https://dzone.com/articles/spring-boot-actuator-in-spring-boot-20
Spring Boot Actuator提供了一些actuator endpoint來實作對你的應用程式進行監控和互動,當然,你也可以建立自定義的enpoint.在接下來的部分,我們會建立一個簡單的程式,完成以下功能:
使Actuator endpoints 提供程式的git版本資訊,jdk版本資訊,
對 enpoint的通路增加安全校驗
建立一個自定義的endpoint
一、建立project
環境:spring boot 2.0+,java8,maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
為了讓這個例子看起來有點功能,我們建立一個簡單的RestController
@RestController
public class HelloActuatorController {
@RequestMapping(value = "/helloactuator", method= GET)
public String helloActuator() {
return "Hello Spring Boot Actuator";
}
}
啟動程式,在浏覽器輸入http://localhost:8080/helloactuator,将會看到"Hello Spring boot Actuator"
二、Spring提供的Endpoint
有了上面的準備,現在,在浏覽器輸入http://localhost:8080/actuator 就可以看到spring actuator預設提供了哪些内容,傳回的内容可以看到Actuator endpoints的大概情況,如果我們需要添加自定義的endpoint時,需要避免命名的沖突。
如上所示,隻能看到3個Actuator enpdoinds.為了展示更多的endpoints,需要在application.properties(application.yml)中增加include或exclude的配置,為了能顯示所有的endpoints,配置如下
重新開機應用,這時除了shutdown endpoint之外的Actuator endpoints都是可以使用的。這些endpoints可以參考https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
三、以info endpoint為例,增加代碼的git版本資訊
在pom.xml 中添加如下配置
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.2.4</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<prefix>git</prefix>
<verbose>false</verbose>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
<format>properties</format>
<gitDescribe>
<skip>false</skip>
<always>false</always>
<dirty>-dirty</dirty>
</gitDescribe>
</configuration>
</plugin>
maven build之後,會發現在target/classes下多了一個git.properties.
接下來重新啟動程式,通路http://localhost:8080/actuator
{
"git": {
"branch": "master",
"commit": {
"id": "d7d7202",
"time": "2018-03-24T13:24:51Z"
}
}
}
上面顯示的資訊隻有git.properties的一部分,如果想要顯示所有的資訊,可以在application.properties上增加下面的配置,就可以看到所有的資訊了
management.info.git.mode=full
四、增加Build資訊
和增加git 版本資訊的方式一樣,我的來增加maven build的資訊,隻要在項目的META-INFO目錄下存在build-info.properties檔案,info endpoint就會将build資訊顯示出來,那怎樣産生build-info檔案呢?
需要引用spring-boot-maven-plugin插件
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
重新啟動程式,可以看到下面的build 資訊
{
"git": {...}, // 7 items
"build": {
"artifact": "myspringactuatorplanet",
"name": "myspringactuatorplanet",
"time": "2018-03-24T13:40:03.907109600Z",
"version": "0.0.1-SNAPSHOT",
"group": "com.mydeveloperplanet"
}
}
大部分的時候,我們并不希望這些資訊被每個人都能通路到,是以需要對endpoind的增加安全校驗,為了達到這個目的,首先,需要在pom.xml檔案中增加Spring Security的依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
添加了上面的依賴之後,重新啟動程式在浏覽器上通路8080端口的請求,在第一次通路的時候會彈出一個使用者登陸的頁面,使用者名user,密碼預設情況下是一串随機碼,并在每次啟動程式後都會更新,并列印在springboot的啟動日志上
Using generated security password: 8da882c3-4bbb-4e71-88c2-13399d9f0724
可見預設的安全校驗是對所有的http請求有效的,那現在假設我們隻想使用者驗證的方式隻作用于部分endpoint上,比如對springboot自帶的endpoint起作用,而我們自定義的helloactuator不起作用,該怎麼做呢?
根據spring的文檔,我們需要新增一個配置類
@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
現在,隻有Actuator endpoints需要驗證了,這裡需要提醒的是,上面的配置隻作用于Actuator endpoints,我原以為EndpointRequest.toAnyEndpoint包含http://localhost:8080/actuator.但其實不是的,因為它并沒有被當做是一個真正的endpoint。這個問題在springboot早已經存在,詳細資訊可以參考https://github.com/spring-projects/spring-boot/issues/12353.
現在的密碼是每次啟動springboot的時候自動生成的,可以通過增加userDetaisServise來避免,當然這種操作隻是為了示範的友善,請不要适用到生産環境中。
@Bean
@Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user);
}
現在Actuator endpoints就可以通過username=user password=password進行通路了。
五、關于Health Endpoint
在預設情況下Health endpoint不會顯示詳細資訊,這些資訊通過spring自帶的healthindicators進行解析收集,但預設情況下我們隻能看到下面的資料。
{
"status": "UP"
}
為了能展示自帶的healthindicators所收集的資訊,需要在application.properties增加如下的配置,這樣,所有通過healthindicators生成的資訊都能被展示出來。
management.endpoint.health.show-details=when-authorized
這個值預設為never,表示不會展示任何health indicators收集的資訊,現在設為when-authorized,讓有權限的使用者通路時顯示health資訊。
重新運作程式,通路請求http://localhost:8080/actuator/health 将會看到下面的資訊
{
"status": "UP",
"details": {
"diskSpace": {
"status": "UP",
"details": {
"total": 408943587328,
"free": 75006865408,
"threshold": 10485760
}
}
}
}
我們也可以建立自定義的health indicators來展示軟體的更多資訊。建立自定義的health indicators需要實作HealthIndicator接口,下面的例子,我們将會檢查當請求觸發時,系統時間的分鐘數是奇數還是偶數,這樣我們可以很容易的測試health indicator狀态的改變,當分鐘數為偶數的時候,indicator傳回UP狀态,如果是奇數傳回DOWN狀态。是以,我們自定義類OddOrEvenMinuteHealthCheck的代碼如下所示。
@Component
public class OddOrEvenMinuteHealthIndicator implements HealthIndicator {
@Override
public Health health() {
int errorCode = 0;
LocalTime now = LocalTime.now();
if (now.getMinute() % 2 != 0) {
errorCode = 1;
}
if (errorCode != 0) {
return Health.down().withDetail("Error Code", errorCode).build();
}
return Health.up().build();
}
}
重新啟動springboot,通路http://localhost:8080/actuator/health,将會多出下面的資訊
"oddOrEvenMinute": {
"status": "UP"
},
在一個分鐘數為奇數的時間點通路,這時status變為DOWN
"oddOrEvenMinute": {
"status": "DOWN",
"details": {
"Error Code": 1
}
},
HeathIndicator提供的狀态DOWN,OUT_OF_SERVICE,UP,UNKNOWN,我們也可以增加我們自定義的狀态碼,比如,我們可以增加ODD和EVEN狀态,隻要在新增的狀态碼加到application.properties中,如下是以
management.health.status.order=DOWN, OUT_OF_SERVICE, UNKNOWN, ODD, EVEN, UP
最後,需要在OddOrEvenMinuteHealthCheck修改對應的狀态即可
if (errorCode != 0) {
return Health.status("ODD").withDetail("Error Code", errorCode).build();
}
return Health.status("EVEN").build();
六、總結
這篇文章,我們對spring actuator進行了了解,知道怎麼樣啟用Actuator endpoints,如果增加git 版本資訊和maven建構資訊到info actuator endpoint,以及如何給endpoint增加安全加校驗,最後,如何給health enpoint自定義一個health indicators.