AWS環境で IoT デバイスの監視を行う際に役立ちそうなツールの紹介


AWS 環境で IoT デバイスの監視を行う際に役立ちそうなツールを調べていたところ、 `amazon-cloudwatch-publisher` というツールが GitHub の [AWS Labs リポジトリ](https://github.com/awslabs) にて公開されていたので、勉強がてら検証してみました。

### ・amazon-clourwatch-publisher

[GitHub - awslabs/amazon-cloudwatch-publisher: Push metrics and logs to CloudWatch from any system that can run Python](https://github.com/awslabs/amazon-cloudwatch-publisher)

## 何ができるのか？

デバイス内のログファイルや、CPUやメモリ使用率などのメトリクスデータを、簡単に CloudWatch に連携できるようになります。

**・ログファイル**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/a7240ee4-e065-29c1-e510-3a5c8b77713b.png)

**・メトリクスデータ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/6a6d6e8b-e445-2a7f-93d5-f4d5abfbce14.png)

`README.md` に結構詳しく記載されていますので、使用前に一読されることをお勧めします。

## 検証環境

**IoT デバイス**

- Raspberry Pi 3B+（以下、**ラズパイ**）
  - Python 3.9.2
  - pip 20.3.4 from /usr/lib/python3/dist-packages/pip (python 3.9)

**AWS CLI 実行用端末**

- Windows 10 Pro 64bit 機（以下、Windows 機）
- ラズパイに `amazon-cloudwatch-publisher`（以下、**Publisher**） 以外を入れたくなかったため、AWS CLI をインストールした Windows 機を使用してコマンドを実行しています
- もちろん、ラズパイに AWS CLI をインストールして頂いてもOKです

ラズパイの OS は以下の通りです。

```bash
$ cat /etc/os-release 
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
```


## 今回の検証内容

ラズパイに Publisher をインストールしてデバイス内のログファイルとメトリクスデータをクラウドに連携し、AWS マネジメントコンソールから、それらを確認することろまでやってみたいと思います。


## デバイスのセットアップ

まず最初に、ラズパイのセットアップを行い、**ラズパイが AWS IoT に認識される**ようにします。 
手順としては、AWS 公式ドキュメントの内容をなぞっていく形になります。
[ステップ 2: AWS IoT で Raspberry Pi をプロビジョニングする - AWS IoT Core (amazon.com)](https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-dc-install-provision.html)

### (1) デバイス証明書を格納するディレクトリを作成する

ラズパイに `pi` ユーザでログインし、適当に以下のようなディレクトリを作成しました。

```bash:ラズパイ
$ mkdir -p ~/certs/aws
```

### (2) デバイス証明書の作成及びアクティブ化
Windows機で AWS CLI を使い、デバイス証明書（**X.509証明書**）の作成及びアクティブ化を行います。
コマンドを実行すると、**証明書と鍵ファイル**が出力されるので、それらをラズパイの (1) で作成したディレクトリ「`/home/pi/certs/aws`」に転送します。
レスポンスの `certificateArn` は後工程で使用するため控えておきます。

```bash:Windows機
$ aws iot create-keys-and-certificate --set-as-active --certificate-pem-outfile ".\device.pem.crt" --public-key-outfile ".\public.pem.key" --private-key-outfile ".\private.pem.key"
{
    "certificateArn": "arn:aws:iot:ap-northeast-1:123XXXXXXXXX:cert/adXXXXXXXXXXXXXXXX",
    "certificateId": "adXXXXXXXXXXXXXXXX",
    "certificatePem": "-----BEGIN CERTIFICATE-----\nXXXXXXXX_SAMPLE_XXXXXXXX\n-----END CERTIFICATE-----\n",
    "keyPair": {
        "PublicKey": "-----BEGIN PUBLIC KEY-----\nXXXXXXXX_SAMPLE_XXXXXXXX\n-----END PUBLIC KEY-----\n",
        "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nXXXXXXXX_SAMPLE_XXXXXXXX\n-----END RSA PRIVATE KEY-----\n"
    }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/5858af56-8be2-85af-f960-6325ceffed61.png)

### (3) 証明書ディレクトリ及びファイルのパーミッションを設定
(1) で作成した「`/home/pi/certs/aws`」ディレクトリ及び証明書と鍵ファイルのパーミッションを設定しておきます。
本来であればきちんとした設定を行うべきですが、今回は**検証が目的**であるため**緩めの設定**をしています。
※本番環境で利用される場合はご注意ください。

```bash:ラズパイ
$ ls -l certs/
drwxr-xr-x 2 pi pi 4096 Aug 22 22:26 aws

$ls -l certs/aws
-rw-r--r-- 1 pi pi 1240 Aug 22 22:26 device.pem.crt
-rw-r--r-- 1 pi pi 1702 Aug 22 22:26 private.pem.key
-rw-r--r-- 1 pi pi  460 Aug 22 22:26 public.pem.key
```

### (4) AWS IoT でデバイスをプロビジョニングする
まず最初に、ラズパイ用の AWS IoT のモノのリソース（Thing）を作成します。
レスポンスの `thingName` は後工程で使用するため控えておきます。

```bash:Windows機
$ aws iot create-thing --thing-name "MyThing01"
{
    "thingName": "MyThing01",
    "thingArn": "arn:aws:iot:ap-northeast-1:123XXXXXXXXX:thing/MyThing01",
    "thingId": "efd786af-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/c6fc9029-385d-ae6a-41e1-7531429f1326.png)

Windows 機に、ポリシードキュメント用の Json ファイルを作成します。
検証が目的であるため、`Resource` には `*` を指定しています。

```json:Windows機
{
    "Version": "2012-10-17",
    "Statement": [
        {
			"Effect": "Allow",
			"Action": [
				"iot:Publish",
				"iot:Subscribe",
				"iot:Receive",
				"iot:Connect"
			],
			"Resource": [
				"*"
			]
	 	}
	]
}
```

ポリシーを作成します。
レスポンスの `policyName` は後工程で使用するため控えておきます。

```bash:Windows機
$ aws iot create-policy --policy-name "MyThing01Policy" --policy-document "file://ポリシードキュメント.json"
{
    "policyName": "MyThing01Policy",
    "policyArn": "arn:aws:iot:ap-northeast-1:123XXXXXXXXX:policy/MyThing01Policy",
    "policyDocument": "{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Action\": [\n\t\t\t\t\"iot:Publish\",\n\t\t\t\t\"iot:Subscribe\",\n\t\t\t\t\"iot:Receive\",\n\t\t\t\t\"iot:Connect\"\n\t\t\t],\n\t\t\t\"Resource\": [\n\t\t\t\t\"*\"\n\t\t\t]\n\t \t}\n\t]\n}\n",
    "policyVersionId": "1"
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/e2166e7a-1794-1315-de5e-4ec09c12b19b.png)


作成したポリシーをデバイス証明書にアタッチします。
`--target` には、前工程で作成したデバイス証明書の Arn が入り、具体的には `arn:aws:iot:ap-northeast-1:123XXXXXXXXX:cert/adXXXXXXXXXXXXXXXX` のような値になります。

```bash:Windows機
$ aws iot attach-policy --policy-name "MyThing01Policy" --target "certificateArn"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/c06c8fd4-3754-b57f-5ea4-67f59f9db3ad.png)

デバイス証明書を AWS IoT のモノのリソースにアタッチします。
`--principal` には、前工程で作成したデバイス証明書の Arn が入ります。

```bash:Windows機
$ aws iot attach-thing-principal --thing-name "MyThing01" --principal "certificateArn"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/f627e664-2b1d-7ed9-6f23-f417953c6dc8.png)

これでプロビジョニングは終わりとなります。

## デバイスに Publisher をインストールする
ラズパイで git clone して、clone してきたリポジトリ内の `README.md` を参考にしながら進めていきます。

### (1) git clone を実行する
ラズパイで `amazon-cloudwatch-publisher` を git clone してきます。

```bash:ラズパイ
$ git clone https://github.com/awslabs/amazon-cloudwatch-publisher.git
```

### (2) ロールエイリアスを作成する
今回、ラズパイと AWS IoT の認証は、前工程で作成した**X.509 証明書** を用いて行います。
そのために必要な**ロールエイリアス**の作成を、まず最初に行います。
こちらの AWS 公式ドキュメントが参考になるので、この内容をなぞっていく形で進めていきます。

[How to Eliminate the Need for Hardcoded AWS Credentials in Devices by Using the AWS IoT Credentials Provider | AWS Security Blog (amazon.com)](https://aws.amazon.com/jp/blogs/security/how-to-eliminate-the-need-for-hardcoded-aws-credentials-in-devices-by-using-the-aws-iot-credentials-provider/)


以下、AWS マネジメントコンソールから抜粋した、ロールエイリアスの説明となります。
> AWS IoT ロールのエイリアスは、認証されたデバイスに、デバイスの証明書にアタッチされたポリシーに含まれていない AWS サービスへの一時的なアクセス権を付与します。

Windows 機に、ポリシードキュメント用の Json ファイルを作成します。

```json:Windows機
{
    "Version": "2012-10-17",
    "Statement": [
        {
			"Effect": "Allow",
			"Principal": {
				"Service": "credentials.iot.amazonaws.com"
			},
			"Action": [
				"sts:AssumeRole"
			]
		}
	]
}
```

IAM Role を作成します。
レスポンスの `RoleName` と `Arn` は、後工程で使用するため控えておきます。

```bash:Windows機
$ aws iam create-role --role-name MyIoTCloudWatchPublisherRole --assume-role-policy-document file://ポリシードキュメント.json
{
    "Role": {
        "Path": "/",
        "RoleName": "MyIoTCloudWatchPublisherRole",
        "RoleId": "ARXXXXXXXXXXXXXXXXXXX",
        "Arn": "arn:aws:iam::123XXXXXXXXX:role/MyIoTCloudWatchPublisherRole",
        "CreateDate": "2022-08-22T23:31:06+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "credentials.iot.amazonaws.com"
                    },
                    "Action": [
                        "sts:AssumeRole"
                    ]
                }
            ]
        }
    }
}
```

ラズパイが AWS にメトリクスデータやログファイルを送信できるように、それらのアクションを定義したポリシードキュメント用の Json ファイルを、Windows 機に作成します。
こちらも、検証が目的であるため、`Resource` には `*` を指定しています。

```json:Windows機
{
    "Version": "2012-10-17",
    "Statement": [
        {
			"Effect": "Allow",
			"Action": [
				"cloudwatch:PutMetricData",
				"logs:CreateLogGroup",
				"logs:CreateLogStream",
				"logs:DescribeLogGroups",
				"logs:DescribeLogStreams",
				"logs:PutLogEvents"
			],
			"Resource": [
				"*"
			]
	 	}
	]
}
```

IAM Role にアタッチするポリシーを作成します。
レスポンスの `Arn` は、後工程で使用するため控えておきます。

```bash:Windows機
$ aws iam create-policy --policy-name MyIoTCloudWatchPublisherPolicy --policy-document file://ポリシードキュメント.json
{
    "Policy": {
        "PolicyName": "MyIoTCloudWatchPublisherPolicy",
        "PolicyId": "ANXXXXXXXXXXXXXXXXXXX",
        "Arn": "arn:aws:iam::123XXXXXXXXX:policy/MyIoTCloudWatchPublisherPolicy",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2022-08-22T23:35:47+00:00",
        "UpdateDate": "2022-08-22T23:35:47+00:00"
    }
}
```

IAM Role に ポリシーをアタッチします。

```bash:Windows機
$ aws iam attach-role-policy --policy-arn arn:aws:iam::123XXXXXXXXX:policy/MyIoTCloudWatchPublisherPolicy --role-name MyIoTCloudWatchPublisherRole
```

ロールエイリアスを作成します。
レスポンスの `roleAlias` は、後工程で使用するため控えておきます。

```bash:Windows機
$ aws iot create-role-alias --role-alias MyIoTCloudWatchPublisherRoleAlias --role-arn arn:aws:iam::123XXXXXXXXX:role/MyIoTCloudWatchPublisherRole
{
    "roleAlias": "MyIoTCloudWatchPublisherRoleAlias",
    "roleAliasArn": "arn:aws:iot:ap-northeast-1:123XXXXXXXXX:rolealias/MyIoTCloudWatchPublisherRoleAlias"
}
```

デバイス証明書にアタッチしているポリシー `MyThing01Policy` を編集します。
具体的には`Statement` の２つ目の要素を追記します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/6b0d5b6a-fce9-a0da-c5f7-edbf5da41c9c.png)

### (3) configs ファイルの編集を行う
git clone してきたリポジトリ内の `configs` ディレクトリ内に、デバイス種類に応じた設定ファイルが格納されています。

```bash:ラズパイ
$ ls -l configs/
-rw-r--r-- 1 pi pi 1030 Aug 23 22:17 amazon-cloudwatch-publisher-iot.json
-rw-r--r-- 1 pi pi 1036 Aug 23 22:17 amazon-cloudwatch-publisher-osx.json
-rw-r--r-- 1 pi pi 1006 Aug 23 22:17 amazon-cloudwatch-publisher-rpi.json
-rw-r--r-- 1 pi pi  663 Aug 23 22:17 amazon-cloudwatch-publisher-ssm.json
```

今回は、ラズパイを使っているため、`amazon-cloudwatch-publisher-rpi.json` を使用します。
検証用に、以下のような書き換えを行いました。

1. 認証周りの `authentication` の記述が Cognito 認証用の記述になっているため、X.509 証明書を用いた記述に書き換える
2. CloudWatch に連携するログファイルの指定を（好きなものに）書き換える

１つ目については、`amazon-cloudwatch-publisher-iot.json` が X.509 証明書を用いた認証になっているため、これを参考にします。
２つ目については、今回は `/var/log/syslog` を CloudWatch に連携するため、そのように書き換えます。

最終的に、`amazon-cloudwatch-publisher-rpi.json`は以下のように編集しました。

```json:ラズパイ
{
  "agent": {
    "instance": {
      "prefix": "rpi",
      "command": "cat /proc/cpuinfo | grep Serial | awk '{print $NF}'"
    },
    "authentication": {
      "iotUrl": "IOT_URL",
      "roleAlias": "IOT_ROLE_ALIAS",
      "thingName": "IOT_THING_NAME",
      "certificate": [
        "IOT_CERT_PATH_AND_FILENAME",
        "IOT_KEY_PATH_AND_FILENAME"
      ]
    },
    "region": "REGION",
    "metrics_collection_interval": 60,
    "logs_collection_interval": 10,
    "logfile": "/opt/aws/amazon-cloudwatch-publisher/logs/amazon-cloudwatch-publisher.log",
    "debug": false
  },
  "metrics": {
    "namespace": "System/IoTDevice"
  },
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/syslog"
          }
        ]
      }
    },
    "log_group_name": "/system/iot/{instance_id}",
    "retention_in_days": 7
  }
}

```

### (4) installers ファイルの編集を行う
git clone してきたリポジトリ内の `installers` ディレクトリ内に、デバイス種類に応じたインストール用スクリプトが格納されています。

```bash:ラズパイ
$ ls -l installers/
-rwxr-xr-x 1 pi pi 2546 Aug 23 22:17 install-osx.bash
-rwxr-xr-x 1 pi pi 2286 Aug 23 22:17 install-rpi.bash
```

今回は、ラズパイを使っているため、`install-rpi.bash` を使用します。
こちらも、以下のような書き換えを行いました。

1. Cognito 認証ではなく、X.509 証明書を用いた認証を行うためそれ用に書き換える
2. `/var/log/syslog` を参照できるように、daemon の設定ファイル作成の箇所を書き換える

最終的に、`install-rpi.bash`は以下のように編集しました。
※上記２点以外も書き換えたため、要所にコメントを入れています。

```bash:ラズパイ
#!/usr/bin/env bash
set -e

#
# Create a user for the script and make sure it's in a group with sudo powers
sudo_groups="sudo wheel"
for sudo_group in $sudo_groups; do
  getent group $sudo_group && break
done
useradd -g $sudo_group -s /sbin/nologin cwpublisher

# Install dependencies
pip3 install -r requirements.txt

# Create folders and copy source and config
mkdir -p /opt/aws/amazon-cloudwatch-publisher/bin/
mkdir -p /opt/aws/amazon-cloudwatch-publisher/etc/
mkdir -p /opt/aws/amazon-cloudwatch-publisher/logs/
cp amazon-cloudwatch-publisher /opt/aws/amazon-cloudwatch-publisher/bin/
cp configs/amazon-cloudwatch-publisher-rpi.json /opt/aws/amazon-cloudwatch-publisher/etc/amazon-cloudwatch-publisher.json
chown -R cwpublisher: /opt/aws/amazon-cloudwatch-publisher
chmod -R u+rwX,g-rwx,o-rwx /opt/aws/amazon-cloudwatch-publisher

# Write configuration file details
# X.509 証明書を用いた認証用に書き換えています
# sed コマンドの IOT_CERT_PATH_AND_FILENAME と IOT_KEY_PATH_AND_FILENAME の箇所は、
# /(slash)を含む文字列で置換する場合に挙動がおかしくなるため書き換えています
read -p "Region: " region
read -p "IOT_URL: " iot_url
read -p "IOT_ROLE_ALIAS: " iot_role_alias
read -p "IOT_THING_NAME: " iot_thing_name
read -p "IOT_CERT_PATH_AND_FILENAME: " iot_cert_path_and_filename
read -p "IOT_KEY_PATH_AND_FILENAME: " iot_key_path_and_filename
sed -i "s/REGION/$region/" /opt/aws/amazon-cloudwatch-publisher/etc/amazon-cloudwatch-publisher.json
sed -i "s/IOT_URL/$iot_url/" /opt/aws/amazon-cloudwatch-publisher/etc/amazon-cloudwatch-publisher.json
sed -i "s/IOT_ROLE_ALIAS/$iot_role_alias/" /opt/aws/amazon-cloudwatch-publisher/etc/amazon-cloudwatch-publisher.json
sed -i "s/IOT_THING_NAME/$iot_thing_name/" /opt/aws/amazon-cloudwatch-publisher/etc/amazon-cloudwatch-publisher.json
sed -i "s|IOT_CERT_PATH_AND_FILENAME=*|$iot_cert_path_and_filename|" /opt/aws/amazon-cloudwatch-publisher/etc/amazon-cloudwatch-publisher.json
sed -i "s|IOT_KEY_PATH_AND_FILENAME=*|$iot_key_path_and_filename|" /opt/aws/amazon-cloudwatch-publisher/etc/amazon-cloudwatch-publisher.json

# Write the daemon configuration file
# syslog の所有グループが adm のため、[Service] の Group は adm を設定しています
# ついでに、[Service] の Restart に always を設定しています
cat << EOF > /etc/systemd/system/amazon-cloudwatch-publisher.service
[Unit]
Description=amazon-cloudwatch-publisher
Requires=network.target
After=network.target
[Service]
Type=simple
User=cwpublisher
Group=adm
ExecStart=/opt/aws/amazon-cloudwatch-publisher/bin/amazon-cloudwatch-publisher
Restart=always
[Install]
WantedBy=multi-user.target
EOF

# Install the publisher as a daemon that runs at boot, and then start it
systemctl enable amazon-cloudwatch-publisher
systemctl start amazon-cloudwatch-publisher
```

### (5) installers を実行する
ラズパイに `pi` ユーザでログインし、installers を実行します。

```bash:ラズパイ
$ sudo bash installers/install-rpi.bash
```

実行すると、途中で、`Region`, `IOT_URL`, `IOT_ROLE_ALIAS` などの変数値を入力するように促されるため、適宜入力をしていきます。
参考までに、今回の検証で私が入力した値は以下のようになります。

| 変数                       | 入力値                                                      | 備考                                                         |
| -------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------ |
| Region                     | ap-northeast-1                                              | リージョン                                                   |
| IOT_URL                    | XXXXXXXXXXXXXX.credentials.iot.ap-northeast-1.amazonaws.com | `$ aws iot describe-endpoint --endpoint-type iot:CredentialProvider` の取得値 |
| IOT_ROLE_ALIAS             | MyIoTCloudWatchPublisherRoleAlias                           | 前項で作成したロールエイリアスの名称                         |
| IOT_THING_NAME             | MyThing01                                                   | 前項で作成した Thing の名称                                  |
| IOT_CERT_PATH_AND_FILENAME | /home/pi/certs/aws/device.pem.crt                           | デバイス証明書のパス                                         |
| IOT_KEY_PATH_AND_FILENAME  | /home/pi/certs/aws/private.pem.key                          | 秘密鍵のパス                                                 |

インストールが完了すると、`amazon-cloudwatch-publisher` サービスが作られ（起動もかかる）、同時に、サービスを起動する`cwpublisher` というユーザも作られます。

```bash:ラズパイ
$ sudo bash installers/install-rpi.bash
```

## Publisher インストール後の動作確認
AWS マネジメントコンソールにログインし、動作確認を行います。

### ログファイルの確認
今回は、ラズパイ内の `/var/log/syslog` が CloudWatch に連携されるように設定を行ったので、そこの確認を行います。

ロググループ名は、設定ファイルに記載したものになっています。
保持期間が、設定ファイルでは 7日間 で指定したつもりでしたが、なぜか「**失効しない**」になっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/0b972cb7-2b1b-16de-f04a-f25b18bf6631.png)

ログファイル名が、ログストリーム名になるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/46237be2-e89b-bfc6-7d4e-84ff046ac1d2.png)

ログファイルの内容（中身）が、CloudWatch で確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/eff72731-0bf1-1182-b6fe-e27d7b679aac.png)

### メトリクスの確認

カスタムメトリクス名は、設定ファイルに記載したものになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/32f7f689-4e76-5dd4-a3af-ffe8845aaf86.png)

ディメンションについては、Python プログラム本体「`/amazon-cloudwatch-publisher`」の [242 行目](https://github.com/awslabs/amazon-cloudwatch-publisher/blob/main/amazon-cloudwatch-publisher#L242)あたりで設定されているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/40916a8c-af0b-0b25-efbd-dd6660eb389b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/bc6c5fa7-c46b-498a-e029-409acb6b3853.png)

git clone してきたままの Python プログラム本体「`/amazon-cloudwatch-publisher`」を編集せずにそのまま使用すると、以下の13メトリクスが取得できるようです。

今回は検証していませんが、プログラム本体を修正すれば、自分で好きなメトリクスを取得して CloudWatch と連携することもできそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/433e7cae-1c04-747d-5773-8587a7b357fe.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/15d33b21-2b1d-9422-1cab-f68be9ae0048.png)

Publisher 自体のログは、`/opt/aws/amazon-cloudwatch-publisher/logs/amazon-cloudwatch-publisher.log` に出力されます。※configs ファイルで設定しています。

## さいごに

今回は、IoT デバイスの監視で役立つかもしれない `amazon-cloudwatch-publisher` というツールを紹介しました。

もちろん、Publisher を使うだけでは監視としては不十分で、

- メトリクスデータが異常値だった場合、それを検出してアラーム（CloudWatch Alarm）をあげる
- ログファイルに "error" や "failed" などのエラー系メッセージが含まれていた場合に、それを検知してアラームをあげる

などの「異常が起きた場合に、人間がそれを知る仕組み」も構築する必要があると思います。

とはいえ、ログファイルやメトリクスデータと CloudWatch の連携が簡単に実現できるのは便利だなと感じました。
初回は、ポリシーやロールエイリアス作成周りが面倒ではありますが、2台目以降は使い回せるので楽を出来ると思います。
機会があれば、ラズパイ以外のデバイスを使ってみたり、独自のメトリクスデータを連携してみたり、色々試してみようと思います。