スプリングブーツアクチュエータ

スプリングブートアクチュエータ

1. 概要

この記事では、Spring BootActuatorを紹介します。 We’ll cover the basics first, then discuss in detail what’s available in Spring Boot 1.x vs 2.x.

Spring Boot 1.xでこの監視ツールを使用、構成、拡張する方法を学習します。 次に、リアクティブプログラミングモデルを利用してBoot2.xとWebFluxを使用して同じことを行う方法について説明します。

Spring Boot Actuatorは、2014年4月から、最初のSpring Bootリリースと共に利用できます。

release of Spring Boot 2を使用して、アクチュエーターが再設計され、新しいエキサイティングなエンドポイントが追加されました。

このガイドは3つの主要セクションに分かれています。

参考文献:

Spring Boot Webアプリケーションを構成する

Spring Bootアプリケーションのより便利な設定のいくつか。

Spring Bootでカスタムスターターを作成する

カスタムSpring Bootスターターを作成するための迅速かつ実用的なガイド。

Spring Bootでのテスト

ユニットテストを効率的に記述するために、Spring Bootがテストをサポートする方法について学びます。

2. アクチュエータとは何ですか?

本質的に、Actuatorは本番環境向けの機能をアプリケーションにもたらします。

この依存関係により、アプリの監視、指標の収集、トラフィックまたはデータベースの状態の理解は簡単になります。

このライブラリの主な利点は、これらの機能を実際に実装することなく、製品グレードのツールを入手できることです。

アクチュエータは主にexpose operational information about the running applicationに使用されます–ヘルス、メトリック、情報、ダンプ、環境など。 HTTPエンドポイントまたはJMX Beanを使用して、それと対話できるようにします。

この依存関係がクラスパスに設定されると、すぐにいくつかのエンドポイントを使用できます。 ほとんどのSpringモジュールと同様に、さまざまな方法で簡単に構成または拡張できます。

2.1. 入門

Spring Boot Actuatorを有効にするには、パッケージマネージャーにspring-boot-actuator依存関係を追加する必要があります。 Mavenの場合:


    org.springframework.boot
    spring-boot-starter-actuator

Spring Bootの部品表(BOM)でバージョンが指定されているため、これはブートバージョンに関係なく有効であることに注意してください。

3. Spring Boot1.xアクチュエータ

1.xでは、アクチュエータはR / Wモデルに従います。つまり、読み取りまたは書き込みが可能です。 E.g. メトリックまたはアプリケーションの状態を取得できます。 または、アプリを正常に終了するか、ログ設定を変更できます。

作動させるために、Actuatorは、Spring MVCがHTTPを介してエンドポイントを公開することを要求します。 他のテクノロジーはサポートされていません。

3.1. エンドポイント

1.xでは、アクチュエータは独自のセキュリティモデルをもたらします。 Spring Security構造を利用しますが、アプリケーションの他の部分から独立して構成する必要があります。

また、ほとんどのエンドポイントは機密性が高く、完全に公開されていない、つまりほとんどの情報が省略されますが、一部のエンドポイントは機密情報ではありません。 /info

Bootがすぐに使用できる最も一般的なエンドポイントの一部を次に示します。

  • /health –アプリケーションの状態情報を表示します(認証されていない接続を介してアクセスされた場合は単純な‘status'、認証された場合は完全なメッセージの詳細)。デフォルトでは機密ではありません

  • /info –任意のアプリケーション情報を表示します。デフォルトでは機密ではありません

  • /metrics –現在のアプリケーションの「メトリック」情報を表示します。デフォルトでも敏感です。

  • /trace –トレース情報を表示します(デフォルトでは、最後のいくつかのHTTP要求)

on the official docsを超える既存のエンドポイントの完全なリストを見つけることができます。

3.2. 既存のエンドポイントの構成

各エンドポイントは、次の形式を使用してプロパティでカスタマイズできます:endpoints.[endpoint name].[property to customize]

次の3つのプロパティを使用できます。

  • このエンドポイントがHTTP経由でアクセスされるid –

  • enabled – trueの場合、アクセスできます。それ以外の場合はアクセスできません。

  • sensitive – trueの場合、HTTPを介して重要な情報を表示するための認証が必要です

たとえば、次のプロパティを追加すると、/beansエンドポイント:がカスタマイズされます

endpoints.beans.id=springbeans
endpoints.beans.sensitive=false
endpoints.beans.enabled=true

3.3. /healthエンドポイント

The /health endpoint is used to check the health or state of the running application.通常、実行中のインスタンスがダウンしたり、その他の理由で異常になった場合に警告するために、監視ソフトウェアによって実行されます。 E.g. DBとの接続の問題、ディスク容量の不足…

デフォルトでは、HTTPを介した不正アクセスについてはヘルス情報のみが表示されます。

{
    "status" : "UP"
}

このヘルス情報は、アプリケーションコンテキストで構成されたHealthIndicatorインターフェースを実装するすべてのBeanから収集されます。

HealthIndicatorによって返される一部の情報は本質的に機密性がありますが、ディスク容量、メッセージングブローカー接続、カスタムチェックなどのより詳細な情報を公開するようにendpoints.health.sensitive=falseを構成できます。

また、implement our own custom health indicator –アプリケーションに固有の任意のタイプのカスタムヘルスデータを収集し、/healthエンドポイントを介して自動的に公開することもできます。

@Component
public class HealthCheck implements HealthIndicator {

    @Override
    public Health health() {
        int errorCode = check(); // perform some specific health check
        if (errorCode != 0) {
            return Health.down()
              .withDetail("Error Code", errorCode).build();
        }
        return Health.up().build();
    }

    public int check() {
        // Our logic to check health
        return 0;
    }
}

出力は次のようになります。

{
    "status" : "DOWN",
    "myHealthCheck" : {
        "status" : "DOWN",
        "Error Code" : 1
     },
     "diskSpace" : {
         "status" : "UP",
         "free" : 209047318528,
         "threshold" : 10485760
     }
}

3.4. /infoエンドポイント

/infoエンドポイントによって表示されるデータをカスタマイズすることもできます(例:

info.app.name=Spring Sample Application
info.app.description=This is my first spring boot application
info.app.version=1.0.0

サンプル出力:

{
    "app" : {
        "version" : "1.0.0",
        "description" : "This is my first spring boot application",
        "name" : "Spring Sample Application"
    }
}

3.5. /metricsエンドポイント

The metrics endpoint publishes information about OS, JVM as well as application level metrics。 有効にすると、メモリ、ヒープ、プロセッサ、スレッド、ロードされたクラス、アンロードされたクラス、スレッドプールなどの情報と、いくつかのHTTPメトリックも取得します。

このエンドポイントの出力は、箱から出してすぐに次のようになります。

{
    "mem" : 193024,
    "mem.free" : 87693,
    "processors" : 4,
    "instance.uptime" : 305027,
    "uptime" : 307077,
    "systemload.average" : 0.11,
    "heap.committed" : 193024,
    "heap.init" : 124928,
    "heap.used" : 105330,
    "heap" : 1764352,
    "threads.peak" : 22,
    "threads.daemon" : 19,
    "threads" : 22,
    "classes" : 5819,
    "classes.loaded" : 5819,
    "classes.unloaded" : 0,
    "gc.ps_scavenge.count" : 7,
    "gc.ps_scavenge.time" : 54,
    "gc.ps_marksweep.count" : 1,
    "gc.ps_marksweep.time" : 44,
    "httpsessions.max" : -1,
    "httpsessions.active" : 0,
    "counter.status.200.root" : 1,
    "gauge.response.root" : 37.0
}

カスタムメトリックを収集するために、「ゲージ」、つまりデータの単一値のスナップショット、および「カウンター」、つまり incrementing/decrementing metrics.

独自のカスタムメトリックを/metricsエンドポイントに実装しましょう。 たとえば、ログインフローをカスタマイズして、成功したログイン試行と失敗したログイン試行を記録します。

@Service
public class LoginServiceImpl {

    private final CounterService counterService;

    public LoginServiceImpl(CounterService counterService) {
        this.counterService = counterService;
    }

    public boolean login(String userName, char[] password) {
        boolean success;
        if (userName.equals("admin") && "secret".toCharArray().equals(password)) {
            counterService.increment("counter.login.success");
            success = true;
        }
        else {
            counterService.increment("counter.login.failure");
            success = false;
        }
        return success;
    }
}

出力は次のようになります。

{
    ...
    "counter.login.success" : 105,
    "counter.login.failure" : 12,
    ...
}

ログイン試行およびその他のセキュリティ関連イベントは、監査イベントとしてActuatorですぐに使用できることに注意してください。

3.6. 新しいエンドポイントの作成

Spring Bootが提供する既存のエンドポイントを使用するだけでなく、まったく新しいエンドポイントを作成することもできます。

まず、新しいエンドポイントにEndpoint<T>インターフェースを実装させる必要があります。

@Component
public class CustomEndpoint implements Endpoint> {

    @Override
    public String getId() {
        return "customEndpoint";
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public boolean isSensitive() {
        return true;
    }

    @Override
    public List invoke() {
        // Custom logic to build the output
        List messages = new ArrayList();
        messages.add("This is message 1");
        messages.add("This is message 2");
        return messages;
    }
}

この新しいエンドポイントにアクセスするために、そのidを使用してマップします。 /customEndpointを打ってそれを行使することができます。

出力:

[ "This is message 1", "This is message 2" ]

3.7. さらなるカスタマイズ

セキュリティ上の理由から、アクチュエータのエンドポイントを非標準のポートで公開することを選択する場合があります。management.portプロパティを使用して簡単に構成できます。

また、すでに述べたように、1.xで。 アクチュエータは、Spring Securityに基づいて独自のセキュリティモデルを構成しますが、アプリケーションの他の部分からは独立しています。 したがって、management.addressプロパティを変更して、ネットワーク経由でエンドポイントにアクセスできる場所を制限できます。

#port used to expose actuator
management.port=8081

#CIDR allowed to hit actuator
management.address=127.0.0.1

#Whether security should be enabled or disabled altogether
management.security.enabled=false

さらに、/infoを除くすべての組み込みエンドポイントは、デフォルトで機密性があります。 アプリケーションがSpring Securityを使用している場合、application.propertiesファイルでデフォルトのセキュリティプロパティ(ユーザー名、パスワード、ロール)を定義することにより、これらのエンドポイントを保護できます。

security.user.name=admin
security.user.password=secret
management.security.role=SUPERUSER

4. Spring Boot2.xアクチュエータ

2.xでは、アクチュエータは基本的な意図を維持しますが、モデルを簡素化し、機能を拡張し、より良いデフォルトを組み込みます。

まず、このバージョンはテクノロジーにとらわれません。 また、アプリケーションと統合することで、セキュリティモデルを簡素化します。

最後に、さまざまな変更の中で、一部が壊れていることを覚えておくことが重要です。 これには、HTTP要求/応答とJava APIが含まれます。

さらに、最新のバージョンは、古いRW(読み取り/書き込み)モデルとは対照的に、CRUDモデルをサポートするようになりました。

4.1. テクノロジーサポート

2番目のメジャーバージョンでは、Actuatorはテクノロジーに依存しなくなりましたが、1.xではMVCに関連付けられていたため、Servlet APIに関連付けられていました。

2.xでは、アクチュエータは、MVCに依存することなく、プラガブルおよび拡張可能なモデルを定義します。

したがって、この新しいモデルでは、基盤となるWebテクノロジーとしてMVCとWebFluxを利用できます。

さらに、適切なアダプターを実装することにより、今後の技術を追加できます。

最後に、追加のコードなしでエンドポイントを公開するために、JMXが引き続きサポートされます。

4.2. 重要な変更

以前のバージョンとは異なり、Actuator comes with most endpoints disabled

したがって、デフォルトで使用できるのは/health/infoの2つだけです。

それらすべてを有効にしたい場合は、management.endpoints.web.exposure.include=*.を設定することもできます。あるいは、有効にする必要があるエンドポイントをリストすることもできます。

Actuatorは、セキュリティ構成を通常のアプリセキュリティルールと共有するようになりました。 したがって、セキュリティモデルは劇的に簡素化されます。

したがって、アクチュエータのセキュリティルールを微調整するには、/actuator/**のエントリを追加するだけです。

@Bean
public SecurityWebFilterChain securityWebFilterChain(
  ServerHttpSecurity http) {
    return http.authorizeExchange()
      .pathMatchers("/actuator/**").permitAll()
      .anyExchange().authenticated()
      .and().build();
}

brand new Actuator official docsの詳細を見つけることができます。

また、by default, all Actuator endpoints are now placed under the /actuator path.

以前のバージョンと同じように、新しいプロパティmanagement.endpoints.web.base-path.を使用して、このパスを微調整できます。

4.3. 事前定義されたエンドポイント

いくつかの利用可能なエンドポイントを見てみましょう。それらのほとんどはすでに1.xで利用可能でした。

それにもかかわらず、some endpoints have been added, some removed and some have been restructured:

  • /auditevents –は、ユーザーのログイン/ログアウトなどのセキュリティ監査関連のイベントを一覧表示します。 また、他のフィールドの中でプリンシパルまたはタイプでフィルタリングできます

  • /beans – rは、BeanFactoryで使用可能なすべてのBeanを順番に切り替えます。 /auditeventsとは異なり、フィルタリングをサポートしていません

  • 以前は/autoconfigとして知られていた/conditions –は、自動構成に関する条件のレポートを作成します

  • /configprops –を使用すると、すべての@ConfigurationPropertiesBeanをフェッチできます

  • /env –は、現在の環境プロパティを返します。 さらに、単一のプロパティを取得できます

  • /flyway –は、Flywayデータベースの移行に関する詳細を提供します

  • /health –は、アプリケーションのヘルスステータスを要約します

  • /heapdump –は、アプリケーションで使用されるJVMからヒープダンプをビルドして返します

  • /info –は一般情報を返します。 カスタムデータ、ビルド情報、最新のコミットに関する詳細など

  • /liquibase – b/flywayと同じように動作しますが、Liquibase用です

  • /logfile –は通常のアプリケーションログを返します

  • /loggers –を使用すると、アプリケーションのログレベルをクエリおよび変更できます

  • /metrics –は、アプリケーションのメトリックを詳しく説明します。 これには、汎用メトリックとカスタムメトリックが含まれる場合があります

  • /prometheus –は前のメトリックと同様のメトリックを返しますが、Prometheusサーバーで動作するようにフォーマットされています

  • /scheduledtasks –は、アプリケーション内でスケジュールされたすべてのタスクに関する詳細を提供します

  • /sessions –は、SpringSessionを使用している場合のHTTPセッションを一覧表示します

  • /shutdown –は、アプリケーションの正常なシャットダウンを実行します

  • /threaddump –は、基盤となるJVMのスレッド情報をダンプします

4.4. 健康指標

前バージョンと同様に、カスタムインジケーターを簡単に追加できます。 他のAPIとは異なり、カスタムヘルスエンドポイントを作成するための抽象化は変更されていません。 ただし、a new interface ReactiveHealthIndicator has been added to implement reactive health checks

簡単なカスタムリアクティブヘルスチェックを見てみましょう。

@Component
public class DownstreamServiceHealthIndicator implements ReactiveHealthIndicator {

    @Override
    public Mono health() {
        return checkDownstreamServiceHealth().onErrorResume(
          ex -> Mono.just(new Health.Builder().down(ex).build())
        );
    }

    private Mono checkDownstreamServiceHealth() {
        // we could use WebClient to check health reactively
        return Mono.just(new Health.Builder().up().build());
    }
}

A handy feature of health indicators is that we can aggregate them as part of a hierarchy.したがって、前の例に従って、すべてのダウンストリームサービスをdownstream-servicesカテゴリにグループ化できます。 このカテゴリは、ネストされたすべてのserviceが到達可能である限り、正常です。

複合ヘルスチェックは1.xからCompositeHealthIndicator.に存在します。また、2.xでは、対応するものにCompositeReactiveHealthIndicatorを使用できます。

Spring Boot 1.xとは異なり、endpoints. sensitiveフラグは削除されました。 完全なヘルスレポートを非表示にするために、新しいmanagement.endpoint.health.show-details.を利用できます。このフラグはデフォルトでfalseです。

4.5. Spring Boot2のメトリクス

In Spring Boot 2.0, the in-house metrics were replaced with Micrometer support.したがって、重大な変更が予想されます。 アプリケーションがGaugeService or CounterServiceなどのメトリックサービスを使用していた場合、それらは使用できなくなります。

代わりに、Micrometerと直接やり取りすることが期待されています。 Spring Boot 2.0では、タイプMeterRegistryのBeanが自動構成されます。

さらに、MicrometerはActuatorの依存関係の一部になりました。 したがって、アクチュエータの依存関係がクラスパスにある限り、うまくいくはずです。

さらに、/metricsエンドポイント:から完全に新しい応答を取得します

{
  "names": [
    "jvm.gc.pause",
    "jvm.buffer.memory.used",
    "jvm.memory.used",
    "jvm.buffer.count",
    // ...
  ]
}

前の例で確認できるように、1.xで得られた実際のメトリックはありません。

特定のメトリックの実際の値を取得するために、目的のメトリック、つまり/actuator/metrics/jvm.gc.pauseに移動して、詳細な応答を取得できます。

{
  "name": "jvm.gc.pause",
  "measurements": [
    {
      "statistic": "Count",
      "value": 3.0
    },
    {
      "statistic": "TotalTime",
      "value": 7.9E7
    },
    {
      "statistic": "Max",
      "value": 7.9E7
    }
  ],
  "availableTags": [
    {
      "tag": "cause",
      "values": [
        "Metadata GC Threshold",
        "Allocation Failure"
      ]
    },
    {
      "tag": "action",
      "values": [
        "end of minor GC",
        "end of major GC"
      ]
    }
  ]
}

ご覧のように、メトリックスはより完全になりました。 異なる値だけでなく、関連するメタデータも含みます。

4.6. /infoエンドポイントのカスタマイズ

/infoエンドポイントは変更されません。 As before, we can add git details using the Maven or Gradle respective dependency


    pl.project13.maven
    git-commit-id-plugin

同様に、we could also include build information including name, group, and version using the Maven or Gradle plugin:


    org.springframework.boot
    spring-boot-maven-plugin
    
        
            
                build-info
            
        
    

4.7. カスタムエンドポイントの作成

前に指摘したように、カスタムエンドポイントを作成できます。 ただし、Spring Boot 2は、これを達成する方法を再設計して、新しいテクノロジーに依存しないパラダイムをサポートしています。

Let’s create an Actuator endpoint to query, enable and disable feature flags in our application

@Component
@Endpoint(id = "features")
public class FeaturesEndpoint {

    private Map features = new ConcurrentHashMap<>();

    @ReadOperation
    public Map features() {
        return features;
    }

    @ReadOperation
    public Feature feature(@Selector String name) {
        return features.get(name);
    }

    @WriteOperation
    public void configureFeature(@Selector String name, Feature feature) {
        features.put(name, feature);
    }

    @DeleteOperation
    public void deleteFeature(@Selector String name) {
        features.remove(name);
    }

    public static class Feature {
        private Boolean enabled;

        // [...] getters and setters
    }

}

エンドポイントを取得するには、Beanが必要です。 この例では、これに@Componentを使用しています。 また、このBeanを@Endpointで装飾する必要があります。

エンドポイントのパスは、@Endpointidパラメータによって決定されます。この場合、リクエストは/actuator/features.にルーティングされます。

準備ができたら、次を使用して操作の定義を開始できます。

  • @ReadOperation – HTTPにマップされますGET

  • @WriteOperation – HTTPPOSTにマップされます

  • @DeleteOperation – HTTPDELETEにマップされます

アプリケーション内の前のエンドポイントでアプリケーションを実行すると、Spring Bootはそれを登録します。

これを確認する簡単な方法は、ログを確認することです。

[...].WebFluxEndpointHandlerMapping: Mapped "{[/actuator/features/{name}],
  methods=[GET],
  produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features],
  methods=[GET],
  produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features/{name}],
  methods=[POST],
  consumes=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features/{name}],
  methods=[DELETE]}"[...]

前のログでは、WebFluxが新しいエンドポイントをどのように公開しているかを確認できます。 MVCに切り替えるとしたら、コードを変更することなく、そのテクノロジーを委任するだけです。

また、この新しいアプローチで留意すべきいくつかの重要な考慮事項があります。

  • MVCとの依存関係はありません

  • 以前のメソッドとして存在していたすべてのメタデータ(sensitive, enabled…)はもう存在しません。 ただし、@Endpoint(id = “features”, enableByDefault = false)を使用してエンドポイントを有効または無効にすることができます

  • 1.xとは異なり、特定のインターフェイスを拡張する必要はもうありません

  • 古い読み取り/書き込みモデルとは対照的に、@DeleteOperationを使用してDELETE操作を定義できるようになりました

4.8. 既存のエンドポイントの拡張

アプリケーションの本番インスタンスがSNAPSHOTバージョンにならないようにしたいとします。 これを行うには、この情報を返すアクチュエータエンドポイントのHTTPステータスコードを変更します。つまり、アプリがたまたまSNAPSHOTだった場合は/info.になります。 別のHTTPステータスコードを取得します。

We can easily extend the behavior of a predefined endpoint using the @EndpointExtension annotations、またはそのより具体的な特殊化@EndpointWebExtensionまたは@EndpointJmxExtension:

@Component
@EndpointWebExtension(endpoint = InfoEndpoint.class)
public class InfoWebEndpointExtension {

    private InfoEndpoint delegate;

    // standard constructor

    @ReadOperation
    public WebEndpointResponse info() {
        Map info = this.delegate.info();
        Integer status = getStatus(info);
        return new WebEndpointResponse<>(info, status);
    }

    private Integer getStatus(Map info) {
        // return 5xx if this is a snapshot
        return 200;
    }
}

4.9. すべてのエンドポイントを有効にする

In order to access the actuator endpoints using HTTP, we need to both enable and expose them。 デフォルトでは、/shutdownを除くすべてのエンドポイントが有効になっています。 デフォルトでは、/healthおよび/infoエンドポイントのみが公開されます。

すべてのエンドポイントを公開するには、次の構成を追加する必要があります。

management.endpoints.web.exposure.include=*

特定のエンドポイントを明示的に有効にするには(たとえば、/shutdown), weを使用します。

management.endpoint.shutdown.enabled=true

1つ(たとえば/loggers)を除くすべての有効なエンドポイントを公開するには、次を使用します。

management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=loggers

5. 概要

この記事では、Spring Boot Actuatorについて説明しました。 アクチュエータの意味と、それが私たちにとって何を意味するのかを定義し始めました。

次に、現在のSpring Bootバージョン1.xのアクチュエータに注目しました。 使い方を議論し、微調整して拡張します。

次に、Spring Boot 2でアクチュエータについて説明しました。 私たちは新機能に焦点を合わせ、WebFluxを利用してエンドポイントを公開しました。

また、この新しいイテレーションで発見できる重要なセキュリティの変更についても話しました。 人気のあるエンドポイントと、それらがどのように変化したかについて説明しました。

最後に、アクチュエータをカスタマイズおよび拡張する方法を示しました。

いつものように、この記事で使用されているコードは、Spring Boot 1.xSpring Boot 2.xの両方のGitHubで見つけることができます。