DatadogのAutodiscoveryでFargate上で動作するnginxとjavaアプリケーションを監視する

AWS　Fargate上にアプリケーションを移行後、以前まで悩まされたオートスケーリング周りでのトラブルが減り運用がかなり楽になしました。
ただこれまで利用していたMackerelではFargateのリソース監視がまだできないのでFargate対応を早くから謳っているDatadogのAutodiscoveryでリソース監視をしてみます。

# Fargateの監視
各方面で書かれいるのでさらっと流します。
[Monitor AWS Fargate applications with Datadog](https://www.datadoghq.com/blog/monitor-aws-fargate/) 
に書かれているように設定すればOKです。
`ecs-cli` で運用しているのでdocker-compose形式の記述で以下のように追記してやります。

```docker-compose.yml
version: '3'
services:
   :
   :
  datadog-agent:
    image: datadog/agent:latest
    environment:
      - DD_API_KEY=[api key]
      - ECS_FARGATE=true
   
```

環境変数のAPIキーと`ECS_FARGAT`にtrueを設定してあげればコンテナ毎のリソースの取得が可能になります。

![スクリーンショット 2018-09-10 15.10.10.png](https://qiita-image-store.s3.amazonaws.com/0/63155/b5a6c11d-dedc-0f83-a151-b81617fafd79.png)


# nginxの監視
## nginxのstub_statusの有効化
nginxのstub_statusの値を取得させるため、nginx.conf に以下のように追記します。

```nginx.conf
location /server-status {
   stub_status on;
   access_log off;
   allow 127.0.0.1;
   allow 172.16.0.0/12;
   deny all;
}
```
これで `/server-status` にアクセスすればステータスが取得できるようになります。

## docker labelの追加
stub_statusの値が取得できるようにdocker labelを追記します。
こちらが参考になりました。 [DOCKER EXAMPLE: NGINX DOCKERFILE](https://docs.datadoghq.com/agent/autodiscovery/#docker-example-nginx-dockerfile)

```docker-compose.yml
version: '3'
services:
  nginx:
    image: nginx:mainline-alpine
    labels:
      - Env=dev
      - com.datadoghq.ad.check_names=["nginx"]
      - com.datadoghq.ad.instances=[{"nginx_status_url":"http://localhost/server-status"}]
      - com.datadoghq.ad.init_configs=[{}]
  datadog-agent:
    image: datadog/agent:latest
    environment:
      - DD_API_KEY=[api key]
      - ECS_FARGATE=true
```
通常はホストのIPなどを組込変数の `%%host%%` などを使うのですが、
Fargateでは同一タスク内で起動している他コンテナへは`localhost`でアクセスできるので`localhost`で問題ありません。
これでコネクション数やreading、writingなどが見られるようになります。

![スクリーンショット 2018-09-10 15.13.42.png](https://qiita-image-store.s3.amazonaws.com/0/63155/b64ba33a-0112-9c44-4770-09a14dda5e8d.png)

# javaの監視
## jmxの有効化
datadogでjavaの監視周りを調べるとjmx経由で取得しているようなので、`JAVA_OPTS`に以下を追記します。
ポートは今回は2003にしましたが、空いているポートであれば良いと思います。
こちらはDockerfile側でもEXPOSEする必要があります。

```
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=2003
-Dcom.sun.management.jmxremote.rmi.port=2003
```

## docker labelの追加
こちらもdocker labelを追記してきます。
jmxを使う場合には`datadog/agent:latest-jmx`というdocker imageを使用します。

```
version: '3'
services:
  java-app:
    image: java-app:latest
    environment:
      - ENV=dev
      - JAVA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=2003 -Dcom.sun.management.jmxremote.rmi.port=2003
    command:
      /bin/sh -c
        "java -jar app-$$ENV.jar"
    labels:
      - Env=dev
      - com.datadoghq.ad.check_names=["jmx"]
      - com.datadoghq.ad.instances=[{"jmx_url":"service:jmx:rmi:///jndi/rmi://localhost:2003/jmxrmi"}]
      - com.datadoghq.ad.init_configs=[{}]
  datadog-agent:
    image: datadog/agent:latest-jmx
    environment:
      - DD_API_KEY=[api key]
      - ECS_FARGATE=true
```

これで、threadやheapのグラフが見れるようになりました。

![スクリーンショット 2018-09-10 15.27.24.png](https://qiita-image-store.s3.amazonaws.com/0/63155/85cd8e04-a0b7-9774-35f9-304076d3f7b4.png)

# 最後に
AWS Fargateの監視ずっと悩んでいたのですが、現状ではdatadogか自作するかしかないのかもしれません。
Mackerelも年内に何かしら出してくれると言っていたので、そちらが出れば試してみたいと思います。
docker-composeファイルの全文も載せておきます。

```docker-compose.yml
version: '3'
services:
  java-app:
    image: java-app:latest
    ulimits:
      nproc: 65536
      nofile:
        soft: 65536
        hard: 65536
    environment:
      - ENV=dev
      - JAVA_OPTS=-Xms1024m -Xmx2048m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -Duser.country=JP -Duser.language=ja -Duser.timezone=Asia/Tokyo -Djava.awt.headless=true -XX:-OmitStackTraceInFastThrow -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=2003 -Dcom.sun.management.jmxremote.rmi.port=2003
    command:
      /bin/sh -c
        "java -jar app-$$ENV.jar"
    labels:
      - Env=dev
      - com.datadoghq.ad.check_names=["jmx"]
      - com.datadoghq.ad.instances=[{"jmx_url":"service:jmx:rmi:///jndi/rmi://localhost:2003/jmxrmi"}]
      - com.datadoghq.ad.init_configs=[{}]
    logging:
      driver: awslogs
      options:
        awslogs-group: "java-app"
        awslogs-region: "ap-northeast-1"
        awslogs-stream-prefix: "dev"
  nginx:
    image: nginx:mainline-alpine
    labels:
      - Env=dev
      - com.datadoghq.ad.check_names=["nginx"]
      - com.datadoghq.ad.instances=[{"nginx_status_url":"http://localhost/server-status"}]
      - com.datadoghq.ad.init_configs=[{}]
    logging:
      driver: awslogs
      options:
        awslogs-group: "nginx"
        awslogs-region: "ap-northeast-1"
        awslogs-stream-prefix: "dev"
  datadog-agent:
    image: datadog/agent:latest-jmx
    environment:
      - DD_API_KEY=[api key]
      - ECS_FARGATE=true
    logging:
      driver: awslogs
      options:
        awslogs-group: "datadog-agent"
        awslogs-region: "ap-northeast-1"
        awslogs-stream-prefix: "dev"
```