Actuatorは、Spring Boot 2.0で最も変更された機能、と言っても過言ではありません。
細かい点を上げればキリが無いので、とりあえず1.xからの移行で気をつけるべき点をいくつか紹介します。
デフォルトでURLプレフィックスが付くようになった
おそらく、Boot 1.xで作った既存アプリを2.0にアップグレードした際、Actuatorで一番出るエラーが「404 Not Found」だと思います(少なくとも僕はそうでした)。
実は2.0から、全Actuatorエンドポイントに/actuator
というプレフィックスが付加されました。つまり、いままではlocalhost:8080/info
のように指定していたURLを、localhost:8080/actuator/info
をとしなければならないのです。
このプレフィックスは、下記のプロパティで変更可能です。
# デフォルト値は"/actuator"
management.endpoints.web.base-path=/admin
また、Actuatorエンドポイント用のポート番号を変えたり、コンテキストパスを付加する事もできます。ポート番号を指定しないとコンテキストパスも付かないので、注意してください。
management.server.port=9999
management.server.servlet.context-path=/admin-context
つまり、上記3つの設定をすべて書いた場合のActuatorエンドポイントは、localhost:9999/admin-context/admin/info
のようになります。
デフォルトで/info
と/health
しか公開されなくなった
これも404エラーの原因になります。/env
、/beans
などはデフォルトで公開されません。
公開したいエンドポイントは、下記のように設定します。
management.endpoints.web.exposure.include=env,beans,loggers
1つでも指定してしまうと、
/info
と/health
も明示的に指定しない限り公開されなくなります。
すべてのエンドポイントを公開したい場合は*
と指定します。
management.endpoints.web.exposure.include=*
逆に、公開しないエンドポイントはmanagement.endpoints.web.exposure.exclude
で指定します。例えば下記のように記述すると、/env
・/info
以外の全エンドポイントが公開されます。
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,info
公開設定がされていても、個別に有効化されていないエンドポイントは公開されません。例えば下記のように記述すると、/beans
・/health
のみが公開されます。/auditevents
は公開指定ではあるものの無効化されているため、公開されません。
management.endpoints.web.exposure.include=auditevents,beans,health
# /auditeventsは無効化されているので公開されない
management.endpoint.auditevents.enabled=false
各エンドポイントの有効化設定は
management.endpoint.xxxxx.enabled
で可能です(xxxxx
にエンドポイント名が入ります)
デフォルトでセキュリティ保護対象ではなくなった
Spring Boot 1.5から、sensitiveなActuatorエンドポイントがセキュリティ保護対象(ACTUATOR
ロールのユーザーでないとアクセスできない)になっていました。
Spring Boot 2.0では、そもそもsensitiveという概念が無くなり、公開されている全エンドポイントがセキュリティ保護対象ではなくなりました。
エンドポイントをセキュリティ保護するには、明示的にSpring Securityを入れて、セキュリティ設定をJava Configで記述する必要があります。
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Spring Securityを追加!-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
...
</dependencies>
...
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 一般ユーザーと、Actuatorにアクセスするユーザーを作成
// (ユーザー名、パスワード、ロール名は任意)
auth.inMemoryAuthentication()
.passwordEncoder(NoOpPasswordEncoder.getInstance()) // 本番ではNoOpPasswordEncoder禁止!
.withUser("actuator").password("password").roles("ACTUATOR").and()
.withUser("user").password("password").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// BASIC認証の有効化
http.httpBasic();
// ActuatorエンドポイントはACTUATORロールのみアクセス可能、
// その他はログイン済みであればどのロールでもアクセス可能
http.authorizeRequests()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR")
.anyRequest().authenticated();
// 本番ではCSRFは無効化しないで!
http.csrf().disable();
}
}
EndpointRequest
クラスは、サーブレット用とリアクティブ用で2つあるので注意してください。今回はサーブレットベースを想定しているので、org.springframework.boot.actuate.autoconfigure.security.servlet
パッケージのEndpointRequest
クラスを利用してください。
$ curl -v -u actuator:password localhost:8080/actuator/health | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'actuator'
> GET /actuator/health HTTP/1.1
> Host: localhost:8080
> Authorization: Basic YWN0dWF0b3I6cGFzc3dvcmQ=
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200
< Set-Cookie: JSESSIONID=C472F3844F17FC8EBC779A35DEFB085F; Path=/; HttpOnly
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Fri, 09 Mar 2018 07:03:55 GMT
<
{ [20 bytes data]
100 15 0 15 0 0 165 0 --:--:-- --:--:-- --:--:-- 166
* Connection #0 to host localhost left intact
{
"status": "UP"
}
最後に
上記3点を注意すれば、1.xで作成したアプリを2.0にアップグレードして、とりあえず動かすことはできるでしょう。
しかし、Actuatorには他にも変更点がいっぱいありますので、公式ドキュメントのActuatorの章は一通り読んでおきましょう!
https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready.html
これの解説ブログも書きたいのですが・・・まあ、気長に待っていてください!