[アップデート] Amazon CloudWatch エージェントが X-Ray と OpenTelemetry のトレース収集機能をサポートしました

2023.08.14

いわさです。

Amazon CloudWatch エージェントを使って、アプリケーションサーバーなどから CloudWatch へメトリクスやログを送信することが出来ます。
今回、CloudWatch エージェントがアップデートされ、バージョン 1.300025.0 以降であればエージェントでトレースデータが処理出来るようになりました。

本日時点でエージェントが対応しているのは AWS X-Ray と OpenTelemetry トレースです。
例えば X-Ray の場合だと従来であれば X-Ray SDK からセグメントデータを送信するために X-Ray デーモンのセットアップが必要だったのですが、今後は CloudWatch エージェントのみで送信することが出来るようになります。
また、デフォルトで X-Ray デーモンと同じ形式でリスナーが起動されるので、X-Ray SDK を利用するアプリケーションの修正は不要です。

本日は X-Ray デーモンを使う場合と CloudWatch エージェントを使う場合でそれぞれ次のように EC2 環境をセットアップし、実際にセグメントデータを送信してみましたので紹介します。

また、この調査をしていく中で、公式ドキュメントの履歴から 2023 年 8 月 8 日より Amazon Linux 2023 がサポート対象に追加されていることに気がつきましたので、Amazon Linux 2023 で X-Ray デーモンと CloudWatch エージェントそれぞれをセットアップして使ってみたいと思います。

従来の X-Ray デーモン

まずは、これまでのやり方であった X-Ray デーモンを使う方法から紹介します。
EC2、Elastic Beanstalk、ECS などでは X-Ray デーモンを統合した環境で X-Ray SDK を使用することが多いと思います。

デーモンダウンロードしてインストール、実行される

X-Ray デーモンを EC2 にセットアップする手順は以下に記載されています。

$ curl https://s3.us-east-2.amazonaws.com/aws-xray-assets.us-east-2/xray-daemon/aws-xray-daemon-3.x.rpm -o /home/ec2-user/xray.rpm
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3641k  100 3641k    0     0  2270k      0  0:00:01  0:00:01 --:--:-- 2271k
[ec2-user@ip-172-31-40-205 bin]$ sudo dnf install -y /home/ec2-user/xray.rpm
Last metadata expiration check: 0:03:40 ago on Sun Aug 13 21:11:33 2023.
Dependencies resolved.
========================================================================================================================================================================================
 Package                                  Architecture                               Version                                     Repository                                        Size
========================================================================================================================================================================================
Installing:
 xray                                     x86_64                                     3.3.7-1                                     @commandline                                     3.6 M

Transaction Summary
========================================================================================================================================================================================
Install  1 Package

:

Installed:
  xray-3.3.7-1.x86_64

Complete!

$ ss -anu
State              Recv-Q             Send-Q                                             Local Address:Port                           Peer Address:Port             Process
UNCONN             0                  0                                                      127.0.0.1:2000                                0.0.0.0:*
UNCONN             0                  0                                             172.31.40.205%enX0:68                                  0.0.0.0:*
UNCONN             0                  0                                                      127.0.0.1:323                                 0.0.0.0:*
UNCONN             0                  0                                [fe80::4fe:f5ff:fe68:69a1]%enX0:546                                    [::]:*
UNCONN             0                  0                                                          [::1]:323                                    [::]:*

インストール&実行されており、127.0.0.1:2000で待機していますね。

セグメントデータを送信する

ではセグメントデータを送信してみます。
実際には X-Ray SDK が使われるのでセグメント形式など普段は意識しないと思うのですが、実際に独自に手動送信する際には X-Ray セグメントデータの形式に準拠している必要があります。
この記事ではあまり掘り下げませんが、手動送信したい方は次のドキュメントを確認し挑戦してみてください。

上記に従って次のようにサンプルデータを作成し、送信してみました。

$ cat hoge.txt
{"format": "json", "version": 1}
{"name" : "hoge1", "id" : "1111111111111111", "trace_id" : "1-64D949E3-111111111111111111111111", "start_time" : 1691961827, "end_time" : 1691961828}
$ cat hoge.txt > /dev/udp/127.0.0.1/2000

送信後、X-Ray デーモンのログファイルを確認してみましょう。
なお、ログ・ファイルのパスはservice xray statusなどから確認しています。

$ cat /var/log/xray/xray.log
2023-08-13T21:15:13Z [Info] Initializing AWS X-Ray daemon 3.3.7
2023-08-13T21:15:13Z [Info] Using buffer memory limit of 9 MB
2023-08-13T21:15:13Z [Info] 144 segment buffers allocated
2023-08-13T21:15:14Z [Info] Using region: ap-northeast-1
2023-08-13T21:15:14Z [Info] HTTP Proxy server using X-Ray Endpoint : https://xray.ap-northeast-1.amazonaws.com
2023-08-13T21:15:14Z [Info] Starting proxy http server on 127.0.0.1:2000
2023-08-13T21:31:08Z [Info] Successfully sent batch of 1 segments (0.105 seconds)

バッチ送信に成功していますね。
AWS マネジメントコンソールも見てみましょう。

手動で作成したセグメントに埋め込んだ名前で送信されていることが確認出来ました。

実際には AWS SDK がデフォルトあるいはカスタマイズした送信先に上記形式でセグメントデータをうまいこと送信してくれています。
ランタイム別にガイダンスが用意されており、例えば .NET 用の X-Ray SDK であれば次に記載されています。

X-Ray デーモンリスナーの指定はAWS_XRAY_DAEMON_ADDRESS環境変数で行うようですね。

CloudWatch エージェント

続いて、今回のアップデートでもある CloudWatch エージェントを使った送信も試してみましょう。
X-Ray デーモンは無しで試したいので、先程とは別の新規 Amazon Linux 2023 環境にセットアップしています。

インストール

CloudWatch エージェントのインストール手順は以下に記載されています。

ここはそのままなのでおそらくあまりトラブルは無い気がします。

$ sudo dnf install amazon-cloudwatch-agent
Last metadata expiration check: 1:31:27 ago on Sun Aug 13 20:59:34 2023.
Dependencies resolved.
========================================================================================================================================================================================
 Package                                             Architecture                       Version                                           Repository                               Size
========================================================================================================================================================================================
Installing:
 amazon-cloudwatch-agent                             x86_64                             1.300025.0-1.amzn2023                             amazonlinux                              69 M

Transaction Summary
========================================================================================================================================================================================
Install  1 Package

Total download size: 69 M
Installed size: 341 M
Is this ok [y/N]: y
Downloading Packages:
amazon-cloudwatch-agent-1.300025.0-1.amzn2023.x86_64.rpm                                                                                                 35 MB/s |  69 MB     00:01
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                    33 MB/s |  69 MB     00:02
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                                1/1
  Running scriptlet: amazon-cloudwatch-agent-1.300025.0-1.amzn2023.x86_64                                                                                                           1/1
create group cwagent, result: 0
create user cwagent, result: 0

  Installing       : amazon-cloudwatch-agent-1.300025.0-1.amzn2023.x86_64                                                                                                           1/1
  Running scriptlet: amazon-cloudwatch-agent-1.300025.0-1.amzn2023.x86_64                                                                                                           1/1
  Verifying        : amazon-cloudwatch-agent-1.300025.0-1.amzn2023.x86_64                                                                                                           1/1

Installed:
  amazon-cloudwatch-agent-1.300025.0-1.amzn2023.x86_64

Complete!

設定

続いて設定です。
CloudWatch エージェントはインストール後に設定を行います。

流れとしては上記ドキュメントに記載されているように、設定ファイルの作成と反映操作を行います。
反映操作を行うとamazon-cloudwatch-agentデーモン用の設定ファイルが更新され、サービス再起動されます。

以下ハイライト部分を追加し、サービスを再起動することでトレース収集機能を有効化(リスナー起動)出来ます。

{
        "agent": {
                "metrics_collection_interval": 60,
                "run_as_user": "root"
        },
        "metrics": {
                "metrics_collected": {
                        "disk": {
                                "measurement": [
                                        "used_percent"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "mem": {
                                "measurement": [
                                        "mem_used_percent"
                                ],
                                "metrics_collection_interval": 60
                        }
                }        },
        "traces": {
                "traces_collected": {
                        "xray": {
                        }
                }
        }
}

次のドキュメントの「CloudWatch agent configuration file: Traces section」にて今回の機能に必要な設定仕様が記載されています。
このドキュメントだけ見るとtraces_collectedから開始しちゃいそうなのですが、実際にはtracesの下に存在している必要がありますのでご注意ください。これで結構詰まりました。

$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -s -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
****** processing amazon-cloudwatch-agent ******
I! Trying to detect region from ec2 D! [EC2] Found active network interface Successfully fetched the config and saved in /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_config.json.tmp
Start configuration validation...
2023/08/14 01:43:20 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_config.json.tmp ...
2023/08/14 01:43:20 I! Valid Json input schema.
2023/08/14 01:43:20 D! pipeline hostDeltaMetrics has no receivers
2023/08/14 01:43:20 Configuration validation first phase succeeded
I! Detecting run_as_user...
I! Trying to detect region from ec2
D! [EC2] Found active network interface
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -schematest -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml
Configuration validation second phase succeeded
Configuration validation succeeded

$ ss -anu
State              Recv-Q             Send-Q                                             Local Address:Port                           Peer Address:Port             Process
UNCONN             0                  0                                             172.31.44.152%enX0:68                                  0.0.0.0:*
UNCONN             0                  0                                                      127.0.0.1:323                                 0.0.0.0:*
UNCONN             0                  0                                                      127.0.0.1:2000                                0.0.0.0:*
UNCONN             0                  0                                [fe80::4d5:41ff:feae:80af]%enX0:546                                    [::]:*
UNCONN             0                  0                                                          [::1]:323                                    [::]:*

設定を反映させると、上記のように127.0.0.1:2000のリスナーが起動していることが確認出来ました。

セグメントデータを送信する

最後に、リスナーに向けてセグメントデータを送信します。
送信方法・形式は X-Ray デーモンの場合と同じ方法で行います。

$ cat hoge2.txt
{"format": "json", "version": 1}
{"name" : "hoge2", "id" : "1111111111111112", "trace_id" : "1-64D949E3-111111111111111111111112", "start_time" : 1691961829, "end_time" : 1691961830}
$ cat hoge2.txt > /dev/udp/127.0.0.1/2000

マネジメントコンソールを確認してみましょう。

CloudWatch エージェント経由で送信した hoge2 という名前のセグメントデータが受信出来ていることが確認出来ました。
実際の X-Ray SDK を使ってより具体的なセグメントデータの送信パターンを試してみたいところですが、今回確認した範囲では X-Ray SDK 側の修正は不要でそのまま CloudWatch エージェントに移行も出来そうですね。

さいごに

本日は Amazon CloudWatch エージェントのトレース収集機能を X-Ray デーモンなしで送信出来るかを確認しました。

X-Ray デーモンのメンテナンスが今後どうなるのかについては触れられていませんが、併用している環境では管理するエージェントを減らすことが出来そうです。
今回は EC2 で試したので X-Ray デーモンのセットアップや管理が不要になることが確認できました。試してないですが ECS であれば X-Ray デーモン用のサイドカーコンテナを無くせるのだろうか。こちらも試してみたいですね。