CloudWatchエージェント設定チートシート(Linux版)

# はじめに
最近CloudWatchエージェントのコンフィグファイルをよく作るようになってきたので、よく使うメトリクスやログ取得などの記録のために記載します。
どなたかの役に立てば幸いです。

# 前提条件
* Linux系のEC2
* CloudWatchエージェントはインストール済もしくは同時に入れる。インストール方法は本記事では省略
* Application Signalsと併用して使う

詳細確認したい場合は基本的に下記の公式ドキュメントを読めば大体わかります。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Application_Signals.html

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-network-performance.html

本記事では、上記の情報を集約した解説と設定例を書いていきます。

# CloudWatchエージェントとは
* Amazon EC2やオンプレミスサーバーの内部のシステムのメトリクス・ログ・トレースをCloudWatchに送信するエージェント
* エージェントのパラメータにないメトリクス等も`StatsD`および `collectd`を使ってカスタムメトリクスとして送付できる
* 送付先はCloudWatchだけではなく、Amazon Managed Service for Prometheusにも送付可能。両方に送ることもできる

# CloudWatchエージェントのコンフィグファイルの全体像
## 基本的なこと
* JSON形式で作成
* デフォルトでは`/opt/aws/amazon-cloudwatch-agent/etc/cloudwatch-agent.json`に保管
* エージェントが起動すると`/opt/aws/amazon-cloudwatch/etc/amazon-cloudwatch-agent.d`ディレクトリにコピーが保存される
* `agent`、`metrics`、`logs`、`traces`の4つのセクションからなる

# CloudWatchエージェントコンフィグファイルの設定例
先に全体像を書いておきます。ここからスタートするとだいぶ楽できると思います。

## CloudWatchエージェントコンフィグファイルの設定例（必須項目のみ）
必須項目のみ有効化したものは次の通りになります。

```json.CloudWatchエージェントのコンフィグファイル例（必須項目のみ）
{
    "metrics":{
        "metrics_collected":{}
    }
}
        
```
つまり、必須項目だけでは何も設定しないのと同義です。

## CloudWatchエージェントコンフィグファイルの設定例（楽したい人向け）
各セクションでよく使うものを中心に入れています。

```json.CloudWatchエージェントのコンフィグファイル例（楽したい人向け）
{
    "agent":{
        "metrics_collection_interval": 60,
        "credentials": {
            "role_arn": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        }
        "logfile": "/opt/aws/cloudwatch-agent/logs/aws-amazon-cloudwatch-agent.log"
    },
    "metrics":{
        "namespace": "CWAgent",
        "metrics_collected":{
            "cpu":{
                "measurement": [
                    "cpu_usage_idle",
                    "cpu_usage_iowait",
                    "cpu_usage_user",
                    "cpu_usage_system",
                    "cpu_usage_steal"
                ],
                "totalcpu": "true"
            },
            "disk":{
                "measurement": [
                    "disk_free",
                    "disk_used",
                    "disk_used_percent"
                ],
                "resources": [
                    "*"
                ]
            },
            "diskio":{
                "mesurement": [
                    "diskio_reads",
                    "diskio_writes",
                    "diskio_read_bytes",
                    "diskio_write_bytes",
                    "diskio_read_time",
                    "diskio_write_time",
                    "diskio_io_time",
                    "diskio_io_in_progress"
                    ]
                },
            "swap":{
                "measurement": [
                    "swap_used_percent",
                    "swap_used",
                    "swap_free"
                ],
                "resources": [
                    "*"
                ]
            },
            "mem":{
                "measurement": [
                    "mem_used_percent",
                    "mem_used",
                    "mem_free",
                    "mem_available"
                ],
                "resources": [
                    "*"
                ]
            },
            "net":{
                "measurement": [
                    "err_in",
                    "err_out",
                    "drop_in",
                    "drop_out"
                ],
            "netstat":{
                "measurement": [
                    "tcp_established",
                    "tcp_syn_sent",
                    "tcp_close"
                ]
            },
            "ethtool":{
                "metrics_include": [
                    "bw_in_allowance_exceeded",
                    "bw_out_allowance_exceeded",
                    "pps_allowance_exceeded"
                ]
            }
        }
    },
    "logs":{
        "logs_collected": {
            "files": {
                "collect_list": [
                    {
                        "file_path": "/opt/aws/cloudwatch-agent/logs/aws-amazon-cloudwatch-agent.log",
                        "log_group_name": "cloudwatch-agent",
                        "log_stream_name":"{instance_id}",
                        "timezone": "UTC"
                    },
                    {
                        "file_path": "/path/to/logfile.log",
                        "log_group_name": "log_name",
                        "log_stream_name": "{instance_id}",
                        "timezone": "UTC"
                    }
                ]
            }
        },
        "metrics_collected": {
            "application_signals": {}
        }
    },
    "traces": {
        "traces_collected": {
            "application_signals": {}
        }
    }
}
```

## CloudWatchエージェントのコンフィグファイルのセクション
* agent、metrics、logs、traces の4つのセクションにそれぞれ記述していきます

# CloudWatchエージェントのコンフィグファイル各セクション
## Agentsセクション
エージェントの全体的な設定に関することを記載する。
* `metrics_collection_interval`：メトリクスの送信間隔。秒単位の数値。 60未満に設定した場合、各メトリクスは高解像度メトリクスとして収集される。デフォルトは60
* `region`：CloudWatchのエンドポイントのリージョンを指定。（ap-northeast-1など）この値を指定しない場合は、EC2インスタンスのあるリージョンに送付
* `credentials`：ほかのアカウントへメトリクス・ログ・トレースを送る場合に利用。`role_arn`フィールドを含めて、IAMロールのARNを指定
* `logfile`：CloudWatchエージェントのログの格納場所を指定。デフォルトは`/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log`
* `run_as_user`：CloudWatchエージェントが実行するために使用するユーザーを指定。指定しない場合はルートユーザー

```json.Agentセクション設定例
"agent":{
        "metrics_collection_interval": 60,
        "region": ap-northeast-1,
        "credentials": {
            "role_arn": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        },
        "logfile": "/opt/aws/cloudwatch-agent/logs/aws-amazon-cloudwatch-agent.log",
        "run_as_user": "cwagent"
    }

```

## Metricsセクション
収集するカスタムメトリクスを選択。カスタムメトリクスを送る必要がない場合は省略可能。

### Metricsセクション共通
* `namespace`：エージェントによって収集されるメトリクスのCloudWatch名前空間を指定。デフォルトは`CWAgent`
* `append_dimensions`：EC2のメトリクスに追加のディメンションを追加。以下の4つのパラメータ
    * `"ImageId":"${aws:ImageId}"`: インスタンスのAMI ID
    * `"InstanceId":"${aws:InstanceId}"`：インスタンスID
    * `"InstanceType":"${aws:InstanceType}"`：インスタンスのインスタンスタイプ
    * `"AutoScalingGroupName":"${aws:AutoScalingGroupName}"`：インスタンスの属するAuto Scalingグループ名
* `aggregation_dimensions`:ディメンションを集約したいときに使用する。Auto Scalingなどを使うときに使用
* `endpoint_override`：FIPSエンドポイントやインターフェースVPCエンドポイントを使う場合に利用。URL文字列で記載
* `metrics_collected`：収集したいメトリクスをここでまとめる。次のセクションで詳細を記載
* `metrics_destinations`：メトリクスの送付先
    * `cloudwatch`： Amazon CloudWatch
    * `amp`： Amazon Managed Service for Prometheus
        * `workspace_id`： Amazon Managed Service for Prometheus ワークスペースに対応する ID
* `force_flush_interval`：メトリクスをメモリバッファ内に滞留させる最大時間（秒単位の数値）。デフォルトは60だが設定にかかわらず、バッファ内のメトリクスのサイズが1MBに達するか、異なるタイプのメトリクスの数が1,000個に達すると、メトリクスは即座にサーバーへ送信

```json.Metricsセクション設定例
"metrics":{
        "namespace": "CWAgent",
        "append_dimensions": "InstanceId":"${aws:InstanceId}",
        "endpoint_override": "vpce-XXXXXXXXXXXXXXXXXXXXXXXXX.monitoring.ap-northeast-1.vpce.amazonaws.com",
        "metrics_destinations": "cloudwatch",
        "metrics_collected":{
        ---（中略）
        }
}
```

### `metrics_collected`サブセクション
`metrics_collected`サブセクションの中に収集したいメトリクスを含める。Linux系で使える一覧は次の通り。
* `cpu`：CPU使用関係のメトリクス
* `disk`：DISK仕様関係のメトリクス
* `diskio`：DISKのI/O(読み書き)関係のメトリクス
* `swap`：swapメモリ関係のメトリクス
* `mem`：メモリ関係のメトリクス（※memoryではないので要注意）
* `net`：ネットワークのパケットやNIC関係のメトリクス
* `netstat`：ネットワークのTCP/UDP関係のメトリクス
* `processes`：プロセスの状態に関するメトリクス
* `nvidia_gpu`：NVIDIA GPU関係のメトリクス。NVIDIA GPUを搭載したインスタンスのみ使用可
* `jmx`：Java Management Extensions (JMX) 関係のメトリクス。Javaのアプリを使う場合は使用する
* `otlp`：OpenTelemetry SDKで収集するOpenTelemetory関係のもの。Application Signalsでは使用しないため、ここでは省略
* `procstat`：個別のプロセスからメトリクスを収集する場合に使用。要procstatプラグイン。ここでは省略
* `statsd`：`StatsD`プロトコルを使用してカスタムメトリクスを取得する場合に使用。ここでは省略
* `ethtool`：ネットワーク関係のメトリクスのうち、Amazon EC2のインフラ面に特化したメトリクス。拡張ネットワーキングを有効化したインスタンスのみ使用可

ミドルウェア以上をApplication Signalsで収集することが多いため、ここではインフラ周りで収集する`cpu`, `disk`, `diskio`, `swap`, `mem`, `net`, `netstat`, `ethtool`のメトリクスを詳細に記載する
各サブセクションのメトリクスの詳細は次のドキュメントを参考にする。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/metrics-collected-by-CloudWatch-agent.html#linux-metrics-enabled-by-CloudWatch-agent

#### `cpu`サブセクション
CPU関係のメトリクスの設定を行う
* 収集するCPU メトリクスの`resources`または`totalcpu`フィールドを少なくとも1つ含める必要がある

* `resources`:`*`のみ、`*`を指定するとCPUごとのメトリクスが収集される
* `totalcpu`:すべてのCPUで集計されたCPUを含めるか否かの設定。デフォルトは`true`
* `metrics_collection_interval`：Agentsセクションの設定を上書きして送付したい場合に使用。基本的にはAgentsセクションと同じ
* `append_dimensions`：CPUメトリクスのみに使用する追加ディメンション
* `measurement`：収集するメトリクスの配列。利用できる値は次の通り

|メトリクス | 簡単な説明 |
|---|---|
|cpu_time_active|任意の容量でCPUがアクティブになっている時間の長さ。1/100秒単位で測定 単位: なし|
|cpu_time_guest|ゲストOSでCPUが仮想CPUを実行している時間の長さ。1/100 秒単位で測定 単位: なし|
|cpu_time_guest_nice|優先度が低く、他のプロセスにより中断される場合がある、ゲストオペレーティングシステムの仮想CPUを CPUで実行している時間。1/100 秒単位で測定。単位: なし|
|cpu_time_idle|CPUがアイドル状態の時間の長さ。1/100 秒単位で測定 単位: なし|
|cpu_time_iowait|CPUがI/O 操作の完了を待機している時間の長さ。1/100 秒単位で測定 単位: なし|
|cpu_time_irq|CPU が中断を処理している時間の長さ。1/100 秒単位で測定 単位: なし|
|cpu_time_nice|プロセスの優先度が低く、優先度の高いプロセスによって簡単に中断される場合がある、ユーザーモードになっているCPUの時間。1/100 秒単位で測定 単位: なし|
|cpu_time_softirq|CPUがソフトウェアの中断を処理している時間の長さ。1/100 秒単位で測定 単位: なし|
|cpu_time_steal|CPUがCPUリソースを割り当てられなかった時間の長さ。これは、仮想化環境で他のOSに費やされる時間。1/100 秒単位で測定 単位: なし|
|cpu_time_system|CPU がシステムモードになっている時間の長さ。1/100 秒単位で測定 単位: なし|
|cpu_time_user|CPU がユーザーモードになっている時間の長さ。1/100 秒単位で測定 単位: なし|
|cpu_usage_active|任意の容量でCPUがアクティブになっている時間の割合。 単位: パーセント|
|cpu_usage_guest|ゲストオペレーティングシステムで CPU が仮想 CPU を実行している時間の割合。 単位: パーセント|
|cpu_usage_guest_nice|優先度が低く、他のプロセスにより中断される場合がある、ゲストOSの仮想CPU をCPUで実行している時間の割合。単位: パーセント|
|cpu_usage_idle|CPU がアイドル状態の時間の割合。 単位: パーセント|
|cpu_usage_iowait|CPU が I/O 操作の完了を待機している時間の割合。単位: パーセント|
|cpu_usage_irq|CPU が中断を処理している時間の割合。 単位: パーセント|
|cpu_usage_nice|プロセスの優先度が低く、優先度の高いプロセスによって簡単に中断される場合がある、ユーザーモードになっているCPUの時間の割合。単位: パーセント|
|cpu_usage_softirq|CPU がソフトウェアの中断を処理している時間の割合。単位: パーセント|
|cpu_usage_steal| CPU がCPUリソースを割り当てられなかった時間の割合。仮想化環境で他のOSに費やされる時間。単位: パーセント|
|cpu_usage_system|CPU がシステムモードになっている時間の割合。単位: パーセント|
|cpu_usage_user|CPU がユーザーモードになっている時間の割合。単位: パーセント|


#### `disk`サブセクション
マウントされたボリュームのメトリクスのみを収集する。
* `resources`:`*`を指定するとすべてのマウントポイントを送信。マウントポイントを指定する
* `ignore_file_system_types`：除外するファイルシステムを指定
* `metrics_collection_interval`：Agentsセクションの設定を上書きして送付したい場合に使用。基本的にはAgentsセクションと同じ
* `append_dimensions`：DISKのみに使用する追加ディメンション
* `measurement`：収集するメトリクスの配列。利用できる値は次の通り

|メトリクス | 簡単な説明 |
|---|---|
|disk_free|ディスクの空き容量。単位: バイト|
|disk_inodes_free|ディスクで使用可能なインデックスノードの数。単位: 数|
|disk_inodes_total|ディスクで予約されているインデックスノードの合計数。単位: 数|
|disk_inodes_used|ディスクで使用されているインデックスノードの数。単位: 数|
|disk_total|使用済み容量と空き容量を含む、ディスクの合計容量。単位: バイト|
|disk_used|ディスクの使用済み容量。単位: バイト|
|disk_used_percent|ディスクスペース合計に対する使用済みの割合。単位: パーセント|

#### `diskio`サブセクション
DISK のI/Oメトリクスを収集する
* `resources`:`*`を指定するとすべてのデバイスのI/Oを送信。デバイスを指定
* `metrics_collection_interval`：Agentsセクションの設定を上書きして送付したい場合に使用。基本的にはAgentsセクションと同じ
* `append_dimensions`：DISK I/Oのみに使用する追加ディメンション
* `measurement`：収集するメトリクスの配列。利用できる値は次の通り

|メトリクス | 簡単な説明 |
|---|---|
|diskio_iops_in_progress|デバイスドライバーに発行されたがまだ完了していない I/O リクエストの数。単位: 数|
|diskio_io_time|ディスクが I/O リクエストをキューに入れている時間の長さ。`sum`のみ使用可能。単位: ミリ秒|
|diskio_reads|ディスク読み取り操作の回数。`sum`のみ使用可能。単位: 数
|diskio_read_bytes|ディスクから読み込まれたバイト数。`sum`のみ使用可能。単位: バイト|
|diskio_read_time|読み取りリクエストがディスクで待機した時間の長さ。複数の読み込みリクエストが同時に待機している場合、その分数値が増える。5つのリクエストが平均100ミリ秒待機している場合、500になる。`sum`のみ使用可能。単位: ミリ秒|
|diskio_writes|ディスク書き込み操作の回数。`sum`のみ使用可能。単位: 数|
|diskio_write_bytes|ディスクへの書き込みバイト数。`sum`のみ使用可能。単位: バイト|
|diskio_write_time|書き込みリクエストがディスクで待機した時間の長さ。複数の書き込みリクエストが同時に待機している場合、その分数値が増える。5つのリクエストが平均100ミリ秒待機している場合、500になる。`sum`のみ使用可能。単位: ミリ秒|

#### `swap`サブセクション
Swapメモリのメトリクスの収集に使用する
* `metrics_collection_interval`：Agentsセクションの設定を上書きして送付したい場合に使用。基本的にはAgentsセクションと同じ
* `append_dimensions`：Swapのみに使用する追加ディメンション
* `measurement`：収集するメトリクスの配列。利用できる値は次の通り

|メトリクス | 簡単な説明 |
|---|---|
|swap_free|使用されていないスワップスペースの量。単位: バイト|
|swap_used|現在使用中のスワップスペースの量。単位: バイト|
|swap_used_percent|現在使用中のスワップスペースの割合。単位: パーセント|

#### `mem`サブセクション
メモリ関係のメトリクスを収集する。`memory`ではなく、`mem`であることに要注意（よくハマる）
* `metrics_collection_interval`：Agentsセクションの設定を上書きして送付したい場合に使用。基本的にはAgentsセクションと同じ
* `append_dimensions`：Memoryのみに使用する追加ディメンション
* `measurement`：収集するメトリクスの配列。利用できる値は次の通り

|メトリクス | 簡単な説明 |
|---|---|
|mem_active|最後のサンプル期間中に何らかの方法で使用されたメモリの量。単位: バイト|
|mem_available|すぐにプロセスに渡すことができる使用可能なメモリの量。単位: バイト|
|mem_available_percent|すぐにプロセスに渡すことができる使用可能なメモリの割合。単位: パーセント|
|mem_buffered|バッファに使用されているメモリの量。単位: バイト|
|mem_cached|ファイルキャッシュに使用されているメモリの量。単位: バイト|
|mem_free|使用されていないメモリの量。単位: バイト|
|mem_inactive|最後のサンプル期間中に何らかの方法で使用されていないメモリの量。単位: バイト|
|mem_total|メモリの合計量。単位: バイト|
|mem_used|現在使用中のメモリの量。単位: バイト|
|mem_used_percent|現在使用中のメモリの割合。単位: パーセント|

#### `net`サブセクション
ネットワークインターフェースに関するメトリクスを収集する。
* `resources`:`*`を指定するとすべてのネットワークインターフェースに関するメトリクスを送信。デバイスを指定する場合は`eth0`などのネットワークインターフェース名を指定する。
* `metrics_collection_interval`：Agentsセクションの設定を上書きして送付したい場合に使用。基本的にはAgentsセクションと同じ
* `append_dimensions`：ネットワークのみに使用する追加ディメンション
* `measurement`：収集するメトリクスの配列。利用できる値は次の通り

|メトリクス | 簡単な説明 |
|---|---|
|net_bytes_recv|ネットワークインターフェイスで受信されたバイトの数。`sum`のみ使用可能。単位: バイト|
|net_bytes_sent|ネットワークインターフェイスで送信されたバイトの数。`sum`のみ使用可能。単位: バイト|
|net_drop_in|このネットワークインターフェイスで受信されたパケットのうち、削除されたものの数。`sum`のみ使用可能。単位: 数|
|net_drop_out|このネットワークインターフェイスで送信されたパケットのうち、削除されたものの数。`sum`のみ使用可能。単位: 数|
|net_err_in|このネットワークインターフェイスによって検出された受信エラーの数。`sum`のみ使用可能。単位: 数|
|net_err_out|このネットワークインターフェイスによって検出された送信エラーの数。`sum`のみ使用可能。単位: 数|
|net_packets_sent|このネットワークインターフェイスで送信されたパケットの数。`sum`のみ使用可能。単位: 数|
|net_packets_recv|このネットワークインターフェイスで受信されたパケットの数。`sum`のみ使用可能。単位: 数|

#### `netstat`サブセクション
ネットワークのうち、TCP接続状態とUDP接続メトリクスを収集する。
* `metrics_collection_interval`：Agentsセクションの設定を上書きして送付したい場合に使用。基本的にはAgentsセクションと同じ
* `append_dimensions`：netstatのみに使用する追加ディメンション
* `measurement`：収集するメトリクスの配列。利用できる値は次の通り

|メトリクス | 簡単な説明 |
|---|---|
|netstat_tcp_close|状態のないTCP接続の数。単位: 数|
|netstat_tcp_close_wait|クライアントからの終了リクエストを待機しているTCP接続の数。単位: 数|
|netstat_tcp_closing|クライアントからの確認付き終了リクエストを待機しているTCP接続の数。単位: 数|
|netstat_tcp_established|確立されたTCP接続の数。単位: 数|
|netstat_tcp_fin_wait1|接続の終了プロセス時にFIN_WAIT1状態になっているTCP接続の数。単位: 数|
|netstat_tcp_fin_wait2|接続の終了プロセス時にFIN_WAIT2状態になっているTCP接続の数。単位: 数|
|netstat_tcp_last_ack|クライアントが接続終了メッセージの確認を送信するのを待機しているTCP接続の数。単位: 数|
|netstat_tcp_listen|Listen状態になっているしているTCPポートの数。単位: 数|
|netstat_tcp_none|非アクティブなクライアントを持つTCP接続の数。単位: 数|
|netstat_tcp_syn_sent|接続リクエストを送信したあとに一致する接続リクエストを待機しているTCP接続の数。単位: 数|
|netstat_tcp_syn_recv|接続リクエストを送受信したあとに接続リクエスト確認を待機しているTCP接続の数。単位: 数|
|netstat_tcp_time_wait|クライアントが接続終了リクエストの確認を受信したことが確認されるのを現在待機しているTCP接続の数。単位: 数|
|netstat_udp_socket|現在の UDP 接続の数。単位: 数|

#### `ethtool`サブセクション
ENA（Elastic Network Adapter）を使用している場合のみ設定可能なネットワークパフォーマンスに関するメトリクス。
##### ENAを使用できる前提条件
* Nitroベースのインスタンスタイプであること
* インスタンスがインターネットに接続されていること

##### ENAが有効化されているかの確認(AWS CLI)
`describe-instances`コマンドを使用
```AWS CLIコマンド例
aws ec2 describe-instances \
    --instance-ids {$InstanceID} \
    --query "Reservations[].Instances[].EnaSupport"
```
`true`が帰ってくれば問題なし

##### `ethtool`サブセクションの設定
* `interface_include`： セクションにリストされている名前を持つインターフェイスからのみメトリクスを収集する。このセクションを省略すると、interface_exclude にリストされていないすべてのイーサネットインターフェイスからメトリクスを収集する。デフォルトのイーサネットインターフェイスは`eth0`
* `interface_exclude`： メトリクスを収集しないイーサネットインターフェイスを指定。ただし、ループバックインターフェースはこの設定に限らず常にメトリクスを収集しない
* `metrics_include`：`ethtool`で収集されるメトリクスを指定。利用できる値は次の通り

|メトリクス | 簡単な説明 |
|---|---|
|bw_in_allowance_exceeded|インバウンド集計の帯域幅がインスタンスの最大値を超えたために、キューおよび (または) ドロップされたパケットの数。単位: なし|
|bw_out_allowance_exceeded|アウトバウンド集計の帯域幅がインスタンスの最大値を超えたために、キューおよび (または) ドロップされたパケットの数。単位: なし|
|conntrack_allowance_exceeded|接続トラッキングがインスタンスの最大数を超え、新しい接続を確立できなかったためにドロップされたパケットの数。単位: なし|
|linklocal_allowance_exceeded|ローカルプロキシサービスへのトラフィックの PPS がネットワークインターフェイスの最大値を超えたためにドロップされたパケットの数。DNSサービス、インスタンスメタデータサービス、およびAmazon Time Sync Serviceへのトラフィックに影響する。単位: なし|
|pps_allowance_exceeded|双方向PPSがインスタンスの最大値を超えたために、キューおよび (または) ドロップされたパケットの数。単位: なし|

#### metrics_collectedサブセクション設定例
上記のサブセクションの説明を踏まえた、`metrics_collected`の説明は次の通り。
```json.metrics_collectedサブセクション設定例
"metrics_collected":{
    "cpu":{
        "measurement": [
            "cpu_usage_idle",
            "cpu_usage_iowait",
            "cpu_usage_user",
            "cpu_usage_system",
            "cpu_usage_steal"
        ],
        "totalcpu": "true"
    },
    "disk":{
        "measurement": [
            "disk_free",
            "disk_used",
            "disk_used_percent"
        ],
        "resources": [
            "*"
        ]
    },
    "diskio":{
        "mesurement": [
            "diskio_reads",
            "diskio_writes",
            "diskio_read_bytes",
            "diskio_write_bytes",
            "diskio_read_time",
            "diskio_write_time",
            "diskio_io_time",
            "diskio_io_in_progress"
            ]
        },
    "swap":{
        "measurement": [
            "swap_used_percent",
            "swap_used",
            "swap_free"
        ],
        "resources": [
            "*"
        ]
    },
    "mem":{
        "measurement": [
            "mem_used_percent",
            "mem_used",
            "mem_free",
            "mem_available"
        ],
        "resources": [
            "*"
        ]
    },
    "net":{
        "measurement": [
            "err_in",
            "err_out",
            "drop_in",
            "drop_out"
        ],
    "netstat":{
        "measurement": [
            "tcp_established",
            "tcp_syn_sent",
            "tcp_close"
        ]
    },
    "ethtool":{
        "metrics_include": [
            "bw_in_allowance_exceeded",
            "bw_out_allowance_exceeded",
            "pps_allowance_exceeded"
        ]
    }
}
```
## Logsセクション
CloudWatch Logs、CloudWatch Application SignalsとContainer Insightsに送付するログの指定を行う
* `service.name`：テレメトリ検索のためのサービス名を指定
* `deployment.environment`：テレメトリ検索のための環境名を設定
* `logs_collected`：logs セクションが含まれている場合に必要。Linuxでは、filesフィールドでサーバーから収集するログファイルを指定。後述
* `log_stream_name`：ログストリーム名を指定
* `endpoint_override`：FIPSエンドポイントやインターフェースVPCエンドポイントを使う場合に利用。URL文字列で記載
* `force_flush_interval`：ログがサーバーに送信されるまでにメモリバッファ内に残留する最大時間を秒単位で指定。このフィールドの設定にかかわらず、バッファ内のログのサイズが1MBに達すると、ログは即座にサーバーへ送信する。デフォルト値は5

* `metrics_collected`：CloudWatch Application SignalsとContainer Insightsでオブザーバビリティを収集する場合に使用。後述

### `logs_collected`サブセクション
Linuxの場合は`files`を指定する。`collect_list`フィールドで詳細を記載する。`collect_list`フィールドで設定可能な項目は次の通り
* `file_path`：ファイルパスを指定。`**`や``*`を利用したワイルドカードの指定が可能
* `auto_removal`：`true`に設定するとログファイルをCloudWatch Logsに送信した後削除する。ログローテーションの仕組み削除方法が確立している場合は`false`推奨。デフォルトは`false`
* `log_group_name`：ロググループ名を指定。ロググループ名を指定する場合、`{instance_id}`、`{hostname}`、`{local_hostname}`、`{ip_address}`を変数として使用可能
* `log_group_class`：CloudWatch Logsのログクラスを指定。`STANDARD`または`INFREQUENT_ACCESS`。デフォルトは`STANDARD`
:::note alert
ロググループの作成後に、ロググループクラスを変更することはできません。（公式ドキュメントにも注意書きあり）
:::
* `log_stream_name`：CloudWatch Logsでログストリーム名として何を使用するかを指定。名前の一部として、名前では変数として `{instance_id}`、`{hostname}`、`{local_hostname}`、`{ip_address}` を使用できる
* `retention_in_days`：ログイベントを保持する日数を指定。新規ロググループの場合、デフォルトは無期限になる。既に存在するロググループでこのフィールドを指定すると上書きする。既に存在するロググループでこのフィールドを指定しないと既存のロググループの設定になる
    * 有効な値は 1、3、5、7、14、30、60、90、120、150、180、365、400、545、731、1827、2192、2557、2922、3288、および 3653
* `filters`：CloudWatch Logsに送信するエントリの配列を正規表現で指定。指定しない場青は、すべてのログが送信される
    * `type`：`include`または`exclude`で指定。`include`では、一致したもののみをCloudWatch Logsに送信する。`exclude` では、フィルターに一致する各ログエントリは CloudWatch Logs に送信されない
    * `expression`：フィルタを記載（正規表現）
* `timezone`：ログイベントにつけるタイムゾーンを指定。`UTC`または`Local`。デフォルトは`Local`
* `timestamp_format`：タイムスタンプのフォーマットに指定がある場合に使用
* `multi_line_start_pattern`：複数行にまたがるログの場合の開始パターンを指定。`{timestamp_format}`を使用することも可能
* `encoding`：ログファイルのエンコーディングを指定。デフォルトは`UTF-8`指定できるのは下記の通り
    * `ascii`, `big5`, `euc-jp`, `euc-kr`, `gbk`, `gb18030`, `ibm866`, `iso2022-jp`, `iso8859-2`, `iso8859-3`, `iso8859-4`, `iso8859-5`, `iso8859-6`, `iso8859-7`, `iso8859-8`, `iso8859-8-i`, `iso8859-10`, `iso8859-13`, `iso8859-14`, `iso8859-15`, `iso8859-16`, `koi8-r`, `koi8-u`, `macintosh`, `shift_jis`, `utf-8`, `utf-16`, `utf-16le`, `UTF-16`, `UTF-16LE`, `windows-874`, `windows-1250`, `windows-1251`, `windows-1252`, `windows-1253`, `windows-1254`, `windows-1255`, `windows-1256`, `windows-1257`, `windows-1258`, `x-mac-cyrillic`
* `service.name`：テレメトリ検索のためのサービス名を指定。`collect_list`ごとに変えたい場合はこちらを指定する
* `deployment.environment`：テレメトリ検索のための環境名を設定。`collect_list`ごとに変えたい場合はこちらを指定する

### `metrics_collected`サブセクション
Application SignalsとContainer Insightsを使用する場合に使用。
* `applications_signals`:Application Signalsを有効化する場合に使用。`rules`のオプションで細かく指定可能。`rules`のオプションは省略

* `kubernetes`：Amazon EKS向けのContainer Insightsを利用するために使用
    * 'enhanced_container_insights'：`true`にするとAmazon EKS向けのContainer Insightsを利用可能になる。詳細は省略
    * `accelerated_compute_metrics`：Amazon EKSクラスターでのNvidia GPUメトリクスの収集をオプトアウトするには、これを falseに設定
* `oltp`：OpenTelemetry SDK からメトリクスを収集する際に利用

### Logsセクション設定例

```json.Logsセクション設定例
"logs":{
    "logs_collected": {
        "files": {
            "collect_list": [
                {
                    "file_path": "/opt/aws/cloudwatch-agent/logs/aws-amazon-cloudwatch-agent.log",
                    "log_group_name": "cloudwatch-agent",
                    "log_stream_name":"{instance_id}",
                    "timezone": "UTC"
                },
                {
                    "file_path": "/path/to/logfile.log",
                    "log_group_name": "log_name",
                    "log_stream_name": "{instance_id}",
                    "timezone": "UTC"
                }
            ]
        }
    },
    "metrics_collected": {
        "application_signals": {}
    }
```

## Traceセクション
CloudWatch Application Signals、X-RayやOpenTelemetory instrumentation SDKから収集したTraceを収集してX-Rayに送る場合使用する

* `application_signals`：CloudWatch Application Signals を利用する際に使用
* `xray`：X-Ray SDKからトレースを収集する際に使用
    * `bind_address`：CloudWatchエージェントがX-Rayのトレースのリッスンに使用するUDPアドレスを指定。形式は`ip:port`。このアドレスは、X-Ray SDKで設定されたアドレスと一致する必要がある。デフォルトは`127.0.0.1:2000`
    * `tcp_proxy`：X-Rayリモートサンプリングをサポートするために使用されるプロキシのアドレスを設定
        * `bind_address`：CloudWatch エージェントがプロキシを設定する必要があるTCPアドレスを指定。形式は`ip:port`。このアドレスは、X-Ray SDKで設定されたアドレスと一致する必要がある。デフォルトは`127.0.0.1:2000`
* `oltp`：OpenTelemetry SDKからトレースを収集する際に使用。ADOTでトレースを収集する場合は`oltp`ではなく、`application_signals`を使用する。以下はOpenTelemetory SDKの場合に使えるオプション
    * 'grpc_endpoint'：gRPCリモートプロシージャコールを使用して送信された OpenTelemetryトレースを利用するために使用するCloudWatchエージェントのアドレスを指定。形式は`ip:port`。このアドレスは、OpenTelemetry SDK のgRPCエクスポーター用に設定されたアドレスと一致する必要がある。デフォルトは`127.0.0.1:4317`
    * `http_endpoint`：HTTP経由で送信されるOTLPトレースを利用するために CloudWatch エージェントが使用するアドレスを指定します。形式は`ip:port`。このアドレスは、OpenTelemetry SDKのHTTPエクスポーター用に設定されたアドレスと一致する必要がある。デフォルトは`127.0.0.1:4318`
* `concurrency`：トレースのアップロードに使用できる、X-Ray に対する同時呼び出しの最大数を指定。デフォルト数は`8`
* `local_mode`：`true`にすると、EC2のメタデータを取得しなくなる。デフォルトは`false`
* `endpoint_override`：FIPSエンドポイントやインターフェースVPCエンドポイントを使う場合に利用。URL文字列で記載
* `region_override`：X-Rayエンドポイントに使用するリージョンを指定
* `proxy_override`：プロキシサーバーがある場合、プロキシサーバーのアドレスを指定
* `transit_spans_in_otlp_format`：`true`にするとOpenTelemetry Protocol 形式でトレースを X-Ray に送信。トランザクション検索のスパンイベントを使えるようになる。デフォルトは`false`

### Traceセクション設定例
Traceセクションの設定はシンプルです。Application Signalsを使用したい場合は`trace_collected`に`application_signals`を含むだけになります。

```json.Traceセクション設定例
"traces": {
        "traces_collected": {
            "application_signals": {}
        }
    }
```

# まとめ
CloudWatchエージェントのコンフィグファイルを作成する際に、あっちこっちのドキュメントを行き来しながら作っていくのは大変だったので、一度使う基本的な設定をまとめてみました。
まだまだNVIDIAやJMXなど触れられていない設定例もありますが、いったん全体像をつかむことで基本的な設定例を網羅できたのではないかと思います。
一度にすべて読むというよりは、この中からさらに必要なものをピックアップしてもらえればと思います！
需要があればWindows版も作りたいと思います。