ローカルのdocker-compose内でX-Ray Daemonを実行

DevContainerをdocker-composeを利用して構築しています。

localstack等でローカルでも本番に近い環境を整備しているのですが、今回新たにX-Ray Daemonを導入したので書いておきます。


## Dockerfile

最初は公式のイメージをそのまま利用しようと思ったのですが、xrayプログラムを起動する `xray` ユーザのUIDが10001となっていて、 `~/.aws` 配下のファイルのバインドなどでPermissionが扱いにくく、参考URLの通りに自身でDockerfile作りました。

```dockerfile
FROM amazonlinux

ARG AWS_REGION=ap-northeast-1

RUN yum install -y unzip
RUN curl -o daemon.zip https://s3.A⁢W⁢SR⁢E⁢G⁢I⁢O⁢N.a⁢m⁢a⁢z⁢o⁢n⁢a⁢w⁢s.c⁢o⁢m/a⁢w⁢s−x⁢r⁢a⁢y−a⁢s⁢s⁢e⁢t⁢s.{AWS_REGION}/xray-daemon/aws-xray-daemon-linux-3.x.zip
RUN unzip daemon.zip && cp xray /usr/bin/xray
ENTRYPOINT ["/usr/bin/xray", "-t", "0.0.0.0:2000", "-b", "0.0.0.0:2000"]
EXPOSE 2000/udp
EXPOSE 2000/tcp
```


## DevContainerのdocker-composeに組込み

docker-composeに以下のように組み込んでいます。

`AWS_PROFILE` にはテスト環境などX-Ray Traceを送信して良い環境を設定してください。


```yaml
  xray:
    build:
      context: dockerfiles/devcontainer/xray
    restart: unless-stopped
    command: --local-mode --log-level debug
    environment:
      AWS_REGION: ap-northeast-1
      AWS_PROFILE: myprofile
      AWS_SDK_LOAD_CONFIG: 1
    volumes:
      - ~/.aws:/root/.aws/:ro
    networks:
      - dev-container-network
```

今回は`--local-mode` と `--log-level` のオプションを渡していますが、他にも以下のようなオプションがあります。

```
bash-5.2# xray -h
Usage: X-Ray [options]
        -a      --resource-arn  Amazon Resource Name (ARN) of the AWS resource running the daemon.
        -o      --local-mode    Don't check for EC2 instance metadata.
        -m      --buffer-memory Change the amount of memory in MB that buffers can use (minimum 3).
        -n      --region        Send segments to X-Ray service in a specific region.
        -b      --bind          Overrides default UDP address (127.0.0.1:2000).
        -t      --bind-tcp      Overrides default TCP address (127.0.0.1:2000).
        -r      --role-arn      Assume the specified IAM role to upload segments to a different account.
        -c      --config        Load a configuration file from the specified path.
        -f      --log-file      Output logs to the specified file path.
        -l      --log-level     Log level, from most verbose to least: dev, debug, info, warn, error, prod (default).
        -p      --proxy-address Proxy address through which to upload segments.
        -v      --version       Show AWS X-Ray daemon version.
        -h      --help          Show this screen
```





## トレース情報を収集してみる
Pythonのプログラムからboto3のイベントをキャプチャーしてX-Rayに投げ込んでみます。

以下の通り `daemon_address="xray:2000"` とローカルのXRay Daemonを指定するところがポイントです。


```python
from aws_xray_sdk.core import patch_all, xray_recorder
import boto3
xray_recorder.configure(service=f"devcontainer", daemon_address="xray:2000")
patch_all()

with xray_recorder.in_segment("test-segment") as subsegment:
    boto3.client('s3').list_buckets()
```

XRay Daemon側のログを確認すると以下のように表示されました。

```
xray_1        | 2024-04-15T08:41:16Z [Debug] processor: sending partial batch
xray_1        | 2024-04-15T08:41:16Z [Debug] processor: segment batch size: 1. capacity: 50
xray_1        | 2024-04-15T08:41:16Z [Info] Successfully sent batch of 1 segments (0.028 seconds)
```

以下が上記のローカルで実行したPythonコードから投げ込んだ情報をX-Ray側で表示したところになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116068/7f5136da-90f7-daf3-1b98-3c212ec90dc8.png)


## 参考URL

https://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-daemon-local.html