Kubernetes上で実行されているDatadog AgentでJava JMX カスタムメトリクスを取得する方法

## はじめに
今回は、Kubernetes上で実行されているDatadog AgentでJMXカスタムメトリクスを取得する方法を記述していきたいと思います。

## 本記事を読むにあたっての前提条件
* 本記事で指すアプリケーションはTomcat＋SpringBootで作られたアプリケーションのことです。

* 本記事はKubernetes上で実行されているDatadog AgentでJava JMXカスタムメトリクスを取得するための設定方法に取り上げています。Java JMXカスタムメトリクスをアプリケーションのコード上でどう設定するか等については触れません。
* なお、Datadog-AgentはDaemonSetで動かします。

## 実行環境
* Kubernetes環境
  - EKS 
* application
  - Java 
    *  Tomcat + SpringBoot
## 設定方法

### Datadog Agent側
#### Configmap.yamlの設定

```yaml:configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: <任意の名前>
  namespace: kube-support
  labels: {}
data:
  metrics-yaml: |
    jmx_metrics:
      - include:
          domain: <取得したいカスタムメトリクスのドメイン>
          type: Pool
          name: ConnectionPool
          attribute:
            PoolStats.available:
              #aliasには任意の文字列を入れてください。
              alias: <application_name>.poolstats.available 
              metric_type: gauge
```
今回は、コネクションプールを取得しようとしているので上記のような設定を行っています。

#### Datadog-agent.yamlの設定

```diff_yaml:datadog-agent.yaml(imageの変更)
spec:
    spec:
      containers:
        - name: agent
-          image: "gcr.io/datadoghq/agent:latest"
+          image: "gcr.io/datadoghq/agent:latest-jmx"          
          imagePullPolicy: IfNotPresent
```
```diff_yaml:datadog-agent.yaml(metric.yamlのmount)
          volumeMounts:
+            - {name: metrics-yaml, mountPath: /etc/datadog-agent/conf.d/tomcat.d/metrics.yaml,subPath: metrics.yaml}
      volumes:
+        - {name: metrics-yaml, configMap: {name: <任意の名前>, items: [{key: metrics-yaml, path: metrics.yaml}]}}
```
<b>※Kubernetesマニフェストファイルの重要な部分のみ本記事では記載しています</b>

:::note info
初めて、Datadog Agentの構築を行う場合は、[Kubernetes に Datadog Agent をインストールする
](https://docs.datadoghq.com/ja/containers/kubernetes/installation/?tab=daemonset)を参考にしつつ本記事で記載している設定を行なってください。
:::


#### <b>point</b>
:::note info
* JMXを取得するためには、DatadogのimageをJMXに対応しているものにする必要があります。
  * ```gcr.io/datadoghq/agent:latest-jmx```
  * ```public.ecr.aws/datadog/agent:latest-jmx```など
    * ref: [Datadog document JMX](https://docs.datadoghq.com/ja/integrations/java/?tab=docker#%E3%82%B3%E3%83%B3%E3%83%95%E3%82%A3%E3%82%AE%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)
* カスタムメトリクスを取得するためにmetric.yamlをmountします。
  * ref: [JMX を使用したオートディスカバリー :オートディスカバリーコンテナ識別子](https://docs.datadoghq.com/ja/agent/guide/autodiscovery-with-jmx/?tab=%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8Aagent#%E3%82%AA%E3%83%BC%E3%83%88%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AB%E3%83%90%E3%83%AA%E3%83%BC%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E8%AD%98%E5%88%A5%E5%AD%90) 
* metric.yamlの書き方については以下のGithubリポジトリを参考にしています。
  * ref:[metric.yaml](https://github.com/DataDog/integrations-core/blob/d6414d311d2aeba4cd76c40255bea1e0b821bb26/tomcat/datadog_checks/tomcat/data/metrics.yaml#L73-L81) 
:::

### Deployment.yamlの設定

```diff_yaml:deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: tomcat_sample_application
  name: tomcaat_sample_application
spec:
  template:
    metadata:
      annotations:
+        ad.datadoghq.com/tomcaat_sample_application.check_names: '["tomcat"]'
+        ad.datadoghq.com/tomcaat_sample_application.init_configs: '[{"is_jmx": true, "collect_default_metrics": true}]'
+        ad.datadoghq.com/tomcaat_sample_application.instances: '[{"host": "%%host%%","port":"8086"}]'
+        ad.datadoghq.com/tomcaat_sample_application.logs: '[{"source":"tomcat","service":"tomcat"}]'
      containers:
        - name: tomcat_sample-application
          image: tomcat_sample-application
          env:
+            - name: POD_IP
+             valueFrom:
+                fieldRef:
+                  fieldPath: status.podIP
+            - name: JAVA_TOOL_OPTIONS
+              value: "-Dspring.jmx.enabled=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.rmi.port=8086 -Dcom.sun.management.jmxremote.port=8086 -Djava.rmi.server.hostname=$(POD_IP)"
```
<b>※Kubernetesマニフェストファイルの重要な部分のみ本記事では記載しています</b>
#### <b>point</b>
:::note info
* アプリケーション側の設定は以下のドキュメントを参考にオートディスカバディアノテーションを書きました。
  * ref: [JMX を使用したオートディスカバリー :オートディスカバリーアノテーション](https://docs.datadoghq.com/ja/agent/guide/autodiscovery-with-jmx/?tab=%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8Aagent#%E3%82%AA%E3%83%BC%E3%83%88%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AB%E3%83%90%E3%83%AA%E3%83%BC%E3%82%A2%E3%83%8E%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)  

* JMXの起動パラメータについてはこちらの記事をご覧ください。
  * ref: [Kubernetes上で立ち上げられたJMX Server（SpringBoot）に接続する時のTips](https://qiita.com/asmg07/items/c885a6ee0a1dbc3d22b9)   
:::
## 動作確認
### Datadog AgentがアプリケーションのJMXに接続できているかについての確認
```terminal:Pod内のターミナル(DatadogAgent)
$agent status
```
```terminal:出力結果（一部抜粋）
========
JMXFetch
========

  Information
  ==================
    runtime_version : 11.0.15
    version : 0.46.0
  Initialized checks
  ==================
    tomcat
      instance_name : tomcat-{Node_IP}-8086
      message : <no value>
      metric_count : metricの数
      service_check_count : 0
      status : OK
  Failed checks
  =============
    no checks
```
statusの部分がOKになっていればアプリケーションとDatadog Agentが接続できています。

:::note warn
metric_countは、350個の制限があります。metric_countが、350個を超える場合には、Datadog サポートチームに問い合わせる必要があります。
ref: [JMX:メトリクスの収集](https://docs.datadoghq.com/ja/integrations/java/?tab=host#%E3%83%A1%E3%83%88%E3%83%AA%E3%82%AF%E3%82%B9%E3%81%AE%E5%8F%8E%E9%9B%86)
:::
#### イメージ
![空白の図 - 3ページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/7093b311-ccb3-2f51-fb3b-6f8e497b4788.png)

### JMX カスタムメトリクスがDatadogに送信できているかについての確認
```terminal:Pod内のターミナル(DatadogAgent)
$agent jmx list collected
```
```terminal:出力結果（一部抜粋）
2022-09-20 00:29:29 GMT | JMX | DEBUG | Connection | Querying bean names on scope: <bean domain>:name=ConnectionPool,type=Pool,*
```
<b>agent jmx list collected で該当のmetricが取得できなかった場合</b>

:::note warn
```agent jmx list collected```で該当のmetricが取得できなかった場合は、```agent jmx list not-matching```コマンドなどを利用してなぜmatchingしていないのか理由を知るのがよいと思います。
* `agent jmx`コマンドの説明
  * ref:[Troubleshooting JMX Integrations:Agent troubleshooting](https://docs.datadoghq.com/integrations/faq/troubleshooting-jmx-integrations/?tab=agentv62#agent-troubleshooting)
:::

#### イメージ
![空白の図 - 3ページ (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/30bea5df-3659-6322-13bf-d8294922968c.png)

### 実際にDatadog でデータが取得できているか確認
最後に、Datadog で反映されているかを確認します。
![スクリーンショット 2022-09-20 9.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/970b93e3-9974-1d36-7136-f49328b30108.png)
Datadog でJava JMX カスタムメトリクスが取得できていることがわかります。


## まとめ
本記事では、Kubernetes上で実行されているDatadog AgentでJava JMXカスタムメトリクスを取得する方法をまとめました。Datadog AgentでJMX カスタムメトリクスを取得する際の参考になれば幸いです。