---
title: Metrics Forwarder Serviceを使ってSpring Boot ActuatorのメトリクスをPWS/PCFに送る
tags: ["Cloud Foundry", "Pivotal Web Services", "Pivotal Cloud Foundry", "Spring Boot", "Java", "Metrics Forwarder", "PCF Metrics", "Micrometer"]
categories: ["Programming", "Java", "org", "springframework", "boot"]
date: 2017-10-29T15:36:07Z
updated: 2017-11-05T17:41:04Z
---

[Metrics Forwarder for PCF](https://docs.pivotal.io/metrics-forwarder/index.html)を使うと簡単にSpring Boot Actuatorのメトリクスを[PCF Metrics](https://docs.pivotal.io/pcf-metrics/1-4/index.html)に送れます。Pivotal Cloud Foundryユーザーは次のTileをインストールすればこれらが利用可能です。

* https://network.pivotal.io/products/apm
* https://network.pivotal.io/products/p-metrics-forwarder

PCF Metricsは[Pivotal Web Services](https://run.pivotal.io)でも去年から[利用可能](https://metrics.run.pivotal.io/)です。つい最近Metrics Forwarderも[利用可能](https://console.run.pivotal.io/marketplace/services/f4532de3-af6d-4fc9-8dbe-f86fa06711ec)になったので、簡単ですが使い方を紹介します。

**目次**

<!-- toc -->

### アプリケーションの設定

アプリケーション側は`spring-boot-starter-actuator`を入れるだけです。

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

一般的にSpring Boot Actuatorのメトリクスを外部に送信しするには[Metrics Writer](https://docs.spring.io/spring-boot/docs/1.5.x/reference/html/production-ready-metrics.html#production-ready-metric-writers)を設定する必要があります。例えばRedisに送信する場合は次の設定を行います。

``` java
@Bean
@ExportMetricWriter
MetricWriter metricWriter(MetricExportProperties export) {
    return new RedisMetricRepository(connectionFactory,
        export.getRedis().getPrefix(), export.getRedis().getKey());
}
```

Cloud Foundryを使う場合は、**この設定は不要**です。Metrics Fowarder Serviceがバインドされている場合は、アプリケーションのステージングのタイミングでこのMetrics Forwarder Serviceへメトリクスを送信するためのMetrics Writerが自動で組み込まれるためです。Metrics Fowarder Serviceをバインドさえすれば、他の設定は不要です(**out of the box**な機能と言います)。楽チンです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/ccb6743f-8fbf-e7be-b3ce-7bb82059d8af.png)

ちなみに自動で組み込まれるMetrics Writerの実装は[https://github.com/cloudfoundry/java-buildpack-metric-writer](https://github.com/cloudfoundry/java-buildpack-metric-writer)です。

### Metrics Forwarder Serviceのサービスインスタンス作成

[Marketplace](https://console.run.pivotal.io/marketplace)から"Metrics Forwarder for PCF"を選択してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/bac588e7-0cb9-63e0-bfd4-0f7e1fe83571.png)


Planを選択してください。どれもfreeですが、Rate Limitの制限が異なります。デモ用途なら`4x4000`にしてください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/17981f4b-74db-7dea-b8f1-0405c3f4cf9f.png)

インスタンス名をここでは`demo-metrics-forwarder`にして、ADDをクリックすればMetrics Forwarderのサービスインスタンスが作成されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/d9ee100c-204e-50b5-f44f-6497ced73681.png)

コマンドラインで作成する場合は

```
cf create-service metrics-forwarder 4x4000 demo-metrics-forwarder
```

でOK。

### アプリケーションのデプロイ

次のようなプロジェクト直下に次の`manifest.yml`を作成し、`name`と`path`を環境に合わせて修正してください。

``` yml
applications:
- name: <your-application-name>
  buildpack: java_buildpack
  memory: 1g
  path: target/<your-application>-0.0.1-SNAPSHOT.jar
  services:
  - demo-metrics-forwarder
```

あとは

```
cf push
```

でデプロイしてください。起動時のログにMetric Writerのインストールログが出力されることを確認されることを確認してください。


### PCF Metricsでメトリクス確認

[Apps Manager](https://console.run.pivotal.io/)からデプロイしたアプリケーションの画面に行き、"View in PCF Metrics"をクリックしてください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/3d79b3a6-d51c-cb66-408c-d137312084d9.png)

デフォルトで次のようなコンテナのメトリクスが取得できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/0afaa42d-f43b-4510-3dfb-d3376879cbae.png)

"ADD CHART"をクリックすると、メトリクスを追加できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/411a5997-4e42-9dee-b915-0defaef9cca1.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/95765986-23d6-1fb8-90a2-f81a36c2211d.png)

"Choose how to aggregate the data across instances"はインスタンス数が2以上の場合で、メトリクスを集約する場合の集約方法です。(view instancesトグルで切り替えられます。集約する場合はトグルをOFF)

* Average ... 全インスタンスの平均値
* Maximum ... 全インスタンスの最大値
* Minimum ... 全インスタンスの最小値
* Total ... 全インスタンスの合計

です。特別なメトリクスでなければ、Couterの場合はTotalをGaugeの場合はAverageを選択すれば良いでしょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/9b1c888a-b4b3-4ee0-4b4f-15f455f1658c.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/8372151e-99f7-7062-6933-3b9cca498709.png)

次のようにSpring Boot Actuatorのメトリクスが表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/ae248715-a01e-70ca-b53d-94574c1a2505.png)


### カスタムメトリクスの送信

デフォルトでは汎用的なメトリクスのみ取得できます。Spring Boot Actuatorの`/metrics`エンドポイントのデフォルトの結果と同じです。

アプリケーション固有のメトリクスを送りたい場合は、アプリケーションにSpring Boot Actuatorの`org.springframework.boot.actuate.metrics.CounterService`または`org.springframework.boot.actuate.metrics.GaugeService`をインジェクションしてからメトリクスを設定してください。

``` java
@RestController
public class HelloController {
    private final CounterService counterService;
    private final GaugeService gaugeService;

    public HelloController(CounterService counterService, GaugeService gaugeService) {
        this.counterService = counterService;
        this.gaugeService = gaugeService;
    }

    @GetMapping
    public Object hello() {
        this.counterService.increment("hello");
        long start = System.currentTimeMillis();
        // do something
        long elapsed = System.currentTimeMillis() - start;
        this.gaugeService.submit("insert.elapsed", elapsed);
        return result;
    }
}
```

この例の場合、`counter.hello`と`gauge.insert.elapsed`という名前のメトリクスが追加されます。

これもPCF Metricsで表示可能です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/ad776054-4bb0-b4b3-e73c-9045d8c8954d.png)

サンプルコードは[https://github.com/making/demo-metrics-forwarder](https://github.com/making/demo-metrics-forwarder)です。

> ちなみにMetrics Forwarder Service自体はSpring Boot専用ではなく、buildpackによって自動で組み込まれるMetrics Writerが[HTTP API](http://docs.pivotal.io/metrics-forwarder/api)に対してPOSTしているだけです。このエンドポイントにメトリクスを送信できれば、任意の言語でも利用可能です。Go言語からこのメトリクスを送信するには[https://github.com/pivotal-cf/go-metrics-pcf](https://github.com/pivotal-cf/go-metrics-pcf)を使用してください。

### MicrometerのメトリクスをPCF Metricsに送信

Spring Boot 2からSpring Boot Actuatorのメトリクスは大幅に変更されます。独自のメトリクスフォーマットが[Micrometer](https://micrometer.io)に置き換わります。
現時点ではCloud FoundryのMetrics WriterはSpring Boot 2には未対応ですが、今後Micrometerに[対応予定](https://github.com/cloudfoundry/java-buildpack-metric-writer/issues/2)です。

ここではMicrometerのSpring 1.5サポート([micrometer-spring-legacy](https://github.com/micrometer-metrics/micrometer/tree/master/micrometer-spring-legacy))を使って、MicrometerのメトリクスをMetrics Forwarder Serviceを経由して、PCF Metricsに送信します。

試してみたところ、MicrometerのDropwizardメトリクスラッパーである`io.micrometer.core.instrument.dropwizard.DropwizardMeterRegistry`とSpring Boot Actuatorの[`DropwizardMetricsServices`](https://docs.spring.io/spring-boot/docs/1.5.x/reference/html/production-ready-metrics.html#production-ready-dropwizard-metrics)を連携すれば簡単に送信可能でした。

`pom.xml`に次の依存ライブラリを設定します。ここでは`DropwizardMeterRegistry`の実装ライブラリとして`micrometer-registry-jmx`を使用します。

``` xml
	<properties>
		<!-- ... -->
		<micrometer.version>1.0.0-rc.3</micrometer.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>io.micrometer</groupId>
			<artifactId>micrometer-spring-legacy</artifactId>
			<version>${micrometer.version}</version>
		</dependency>
		<dependency>
			<groupId>io.micrometer</groupId>
			<artifactId>micrometer-registry-jmx</artifactId>
			<version>${micrometer.version}</version>
		</dependency>
	</dependencies>
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>
```

次のようなJava Configを作成してください。

``` java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.codahale.metrics.MetricRegistry;

import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import io.micrometer.core.instrument.dropwizard.DropwizardMeterRegistry;

@Configuration
public class MetricsConfig {
	@Bean
	public MetricRegistry metricRegistry(CompositeMeterRegistry registry) {
		return registry.getRegistries().stream()
				.filter(x -> x instanceof DropwizardMeterRegistry)
				.map(DropwizardMeterRegistry.class::cast)
				.map(DropwizardMeterRegistry::getDropwizardRegistry).findAny()
				.orElseGet(MetricRegistry::new);
	}
}
```

この設定によって、`DropwizardMeterRegistry`の`com.codahale.metrics.MetricRegistry`と`DropwizardMetricsServices`のそれが共有され、MicrometerのメトリクスがSpring Boot Actuator 1.5のメトリクスに反映されます。そして、Metrics WriterによってMetrics Forwarder Serviceに転送されます。

この設定を含めて再度ビルドして`cf push`することで、PCF MetricsでMicrometerのメトリクス(階層化された名前にリネームされます）
を表示可能になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/e6685a0c-0495-60e2-15c3-6598fff76273.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1852/e308b6f8-adba-a6db-95c8-f38b9d08c330.png)

----

Metrics ForwarderとPCF Metricsを使って、Spring Boot ActuatorのメトリクスをOut of the Boxで表示することができることを紹介しました。
今後の[Micrometer](https://micrometer.io/)連携も楽しみです。
