2021/03/10
アマゾンウェブサービスジャパン
ソリューションアーキテクト
三平 悠磨
AWS IoT
におけるデバッグ方法
自己紹介
• 三平 悠磨
•
IoT Specialist SA
• 経歴
• 会話AI開発
• 家庭用ロボット開発
• 好きなサービス
•
AWS IoT Greengrass
•
Amazon Kinesis Video Streams
•
Twitter: @yu_ma_m
本セッションの内容
紹介すること
•
AWS IoTサービスを初めて使う際にありがちな問題と、そのトラブル
シューティング方法
• クラウド側・デバイス側での問題の切り分け方法と確認ポイント
• デバイス側は例として
AWS IoT Device SDK v2 for Python を利用
• 問題の素早い発見や調査のための
Tips
紹介しないこと
•
AWS IoT サービスの詳細な説明
アジェンダ
• サービス紹介
(抜粋)
•
AWS IoT Core
•
Amazon CloudWatch
• 問題別デバッグ方法
•
AWS IoT Core に接続できない
•
Publish / Subscribe できない
• ルールがうまく動かない
全体像
AWS IoT Core 証明書 ポリシー
ルール
ルール
AWS サービス
AWS Lambda Amazon SQS
Amazon S3 Amazon Kinesis Amazon CloudWatch AWS IoT Device SDK
ネットワーク
繋がらない・メッセージが届かない時にどのように問題を切り分けるか?
FreeRTOS AWS IoT Greengrassデバイス
…AWS IoT Device
全体像
AWS IoT Core 証明書 ポリシー
ルール
ルール
AWS サービス
AWS Lambda Amazon SQS
Amazon S3 Amazon Kinesis Amazon CloudWatch AWS IoT Device SDK
ネットワーク
繋がらない・メッセージが届かない時にどのように問題を切り分けるか?
FreeRTOS AWS IoT Greengrassデバイス
…AWS IoT Device
Management AWS IoT Device Defender
デバイスが
AWS IoT
Core に繋がらない
メッセージが届か
ない、送れない
ルールがうまく
動かない
ログやメトリクスの
見方が分からない
AWS IoT Core
メッセージ デバイスゲートウェイ & 認証サービス メッセージ アプリケーション デバイスシャドウ メッセージブローカー API レジストリ Actions API ルールエンジン AWS やその他のサービス Analytics Amazon Kinesis Artificial Intelligence Amazon EMR Messaging Amazon SQS Amazon SNS Database Amazon Redshift Amazon DynamoDB Manage Amazon CloudWatchMQTT
プロトコル
• IoT / M2M
で利⽤される通信プロトコル
• OASIS
標準プロトコル
• AWS IoT Core
は v3.1.1 に準拠
•
リソースや回線帯域が限られているデバイスに最適化
• Publish / Subscribe
メッセージ交換モデル
•
ブローカーがメッセージを仲介
Publish / Subscribe モデル
•
スケーラブルな⾮同期型メッセージ交換モデル
•
最初に Publish もしくは Subscribe されたタイミングで
Topic
が⽣
成される
•
Publisher
は
Topic
に対してメッセージを
Publish(送信) する
•
Message Broker はマッチする
Topic
に
Subscribe(受信) している
Subscriber
へメッセージを
Publish
する
Publisher
Subscriber
data/sensor/123
(Topic)
{“temp”:35.1}
{“temp”:35.1}
Message Broker
publish
publish
Topic とは
•
メッセージ
(データ)
を送る先を⽰す⽂字列
•
最低⼀つの
Topic Level
(階層)
を持つ
•
“/”
(スラッシュ)
で複数
(最⼤8階層)
の
Topic Level
を連結
(先頭に “/” は不要)
例)
foo
foo/bar
foo/bar/buz
トピックレベル
ワイルドカード
•
Subscribe する Topic の指定でワイルドカードを利⽤できる
•
1階層にマッチ: +
•
meguro-building/1f/+/sensor
•
meguro-building/+/+/sensor
•
末尾の複数階層にマッチ: #
•
meguro-building/#
•
meguro-building/1f/#
Publisher
Subscriber
data/sensor/
#
(subscribe)
Message Broker
data/sensor/
456
(publish)
Publisher
data/sensor/
123
(publish)
QoS
とは
QoS=0
1
回のみ送信
最低1回の到達を保証
QoS=1
PUBACK
PUBLISH
PUBLISH
ベストエフォート型。
メッセージの到達を保証していない。
オーバーヘッドは少ない。
保証型。
メーッセージの到達は保証。
オーバーヘッドはQoS=0に⽐べて
⼤きい。
AWS IoT Core
で利用可能な認証方法
1. x.509クライアント証明書
•
TLS 相互認証
•
登録数に上限なし、証明書の持ち込みも可能
2. Amazon Cognito
•
スマートフォンなど、入力装置があるデバイスで利用可能
•
人による認証情報の入力ができない場合はマッチしない
3. AWS IAM
•
SigV4 セキュリティトークンでの認証
•
作成数に上限があるため、大量のデバイスの運用には適さない
4. カスタム認証
•
AWS Lambda で独自の認証方法を実装
•
HTTP ヘッダー、MQTT connect 時の ID/Password 等
IoT
ポリシーによる認可
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action":["iot:Publish"]
"Resource": ["arn:aws:iot:ap-northeast-1-1:123456789012:topic/foo/bar"]
}, {
"Effect": "Allow",
"Action": ["iot:Connect"],
"Resource": ["*"]
}]
}
証明書にアタッチ
各デバイスに許可する動作を
IoT ポリシーとして定義する
•
Connect, Publish, Subscribe, Receive 等
•
SQL⽂を使ったトピックのフィルタ
•
オプションのWHERE句で条件を記
述することが可能
•
JSONをサポート
ルールエンジン – メッセージのフィルタリング
SELECT *
FROM ʻ
data/meguro_building/1f/+/sensor
ʼ
WHERE temp > 35.0
{“temp”: 35.2}
•
トピックのフィルタの例
取得するデータ
->
対象となるTopic
->
条件
->
ルールエンジン - アクション
Amazon CloudWatch
(Alarm, Metrics, Logs)
Amazon DynamoDB
Amazon Elasticsearch Service
Amazon Kinesis Data Firehose
AWS IoT Analytics
AWS IoT Events
AWS IoT SiteWise
Amazon Kinesis
AWS Lambda
HTTP endpoint
MQTT republish
Amazon Simple Storage
Service
Amazon Simple Notification Service
Amazon Simple Queue Service
AWS Step Functions
AWS IoT Core
から 他
の AWS サービスや外
部サービスと連携
ルールエンジン
アクション
Amazon Timestream
[new!]
Amazon CloudWatch
の概要
CloudWatch Alarms
CloudWatch
Events
CloudWatch Metrics
CloudWatch Logs
CloudWatch Logs
Insights
AWSサービス
お客様システム
CloudWatch Dashboards
time-base
event-base
メトリクスを送信 ログを送信 メトリクスに応じた アクションの実⾏ イベントに応じた ターゲットによる処理 メトリクスを送信 ログの分析・可視化モニタリングに関する様々な機能を提供
Amazon CloudWatch
の概要
CloudWatch Alarms
CloudWatch
Events
CloudWatch Metrics
CloudWatch Logs
CloudWatch Logs
Insights
AWSサービス
お客様システム
CloudWatch Dashboards
time-base
event-base
メトリクスを送信 ログを送信 メトリクスに応じた アクションの実⾏ ログの分析・可視化 イベントに応じた ターゲットによる処理 メトリクスを送信モニタリングに関する様々な機能を提供
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/metrics_dimensions.html
AWS IoT
の
CloudWatch Metrics
•
30
以上
の
CloudWatch Metrics が AWS IoT のデフォルトのメトリクスとして利用で
きる
•
メッセージブローカー
メトリクス
• 接続やIn/Outのメッセージ数、認証エラーやスロットルなど
•
ルール
/
ルールアクション
メトリクス
• ルールの実行数やアクションの成功/失敗数など
•
シャドウ
メトリクス
•
ジョブ
メトリクス
• など
• 使い方の例
• ダッシュボードを作成して、デバイスの接続数やメッセージ数を監視
• 認証エラーを監視するアラームを作成して、Amazon SNS 経由で管理者に通知
Amazon CloudWatch
の概要
CloudWatch Alarms
CloudWatch
Events
CloudWatch Metrics
CloudWatch Logs
CloudWatch Logs
Insights
AWSサービス
お客様システム
CloudWatch Dashboards
time-base
event-base
メトリクスを送信 ログを送信 メトリクスに応じた アクションの実⾏ ログの分析・可視化 イベントに応じた ターゲットによる処理 メトリクスを送信モニタリングに関する様々な機能を提供
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/cwl-format.html
AWS IoT
の
CloudWatch Logs
エントリ
•
20
以上
の
CloudWatch Logs ログエントリ
•
メッセージブローカー
のログエントリ
• 接続・切断やメッセージのPublish-In/Out、Subscribe
•
ルールエンジン
のログエントリ
• ルールの一致やアクションのトリガーなど
•
シャドウ
のログエントリ
•
ジョブ
のログエントリ
• など
• 使い方の例
• 問題の起きているデバイスのログのみを検索して、問題の原因を切り分ける
• メトリクスフィルターを作成して、特定のエラーのログ件数をメトリクス化
して監視する
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/cloud-watch-logs.html
CloudWatch Logs
で
AWS IoT Core
のログを参照
ロググループ
: AWSIotLogsV2を確認
生のログの一覧が表示されるが、
デバイス毎に検索
して絞り込んだり、
Amazon CloudWatch
の概要
CloudWatch Alarms
CloudWatch
Events
CloudWatch Metrics
CloudWatch Logs
CloudWatch Logs
Insights
AWSサービス
お客様システム
CloudWatch Dashboards
time-base
event-base
メトリクスを送信 ログを送信 メトリクスに応じた アクションの実⾏ ログの分析・可視化 イベントに応じた ターゲットによる処理 メトリクスを送信モニタリングに関する様々な機能を提供
Amazon CloudWatch Logs Insights
の特徴
•
ロググループに対して分析
•
JSON形式の
フィールドを自動判別
•
サンプルクエリ
•
クエリの自動補完
•
送信されるログごとに
3つのフィールドを生成
•
@timestamp:CloudWatch Logsに出力された時間
•
@message:CloudWatch Logsに送信された実際のログ
•
@logStream:イベント発生元のリソース
クエリコマンドと基本構文
クエリコマンド(
6つ)
基本構文
UNIXのシェルライクなパイプ文字(‘|’)でコマンドを連結
Command1 [Options]
|
Command2 [Options]
|
Command3
[Options]...
FIELDS
PARSE
FILTER
STATS
SORT
LIMIT
さらに、正規表現、算術オペレーション、⽐較オペレーション、数値関数、⽇時関
数、⽂字列関数、汎⽤関数など、多数のサポート⽤の関数やオペレーションを⽤意
操作イメージ
①ロググループを選択
②期間を選択
③クエリを記述
クエリ例
特定デバイスに関連するエラーログのみを検索する
fields @timestamp, @message
| sort @timestamp desc
| filter clientId = “クライアントID (モノの名前)"
| filter logLevel = "ERROR"
ロググループ
: AWSIotLogsV2
特定のイベントを検索する
fields @timestamp, @message
| sort @timestamp desc
| filter eventType = “イベント名"
ロググループ
: AWSIotLogsV2
CloudWatch の AWS IoT ログエントリ
高度なクエリと検索結果の可視化
例
: レイテンシの傾向把握
fields @timestamp, @message
| sort @timestamp desc
| fields server_timestamp – client_timestamp as latency
| stats pct(latency, 50) as p50_ latency, pct(latency, 90) as p90_ latency, max(latency) as max_ latency by bin(5m)
ロググループ
: AWSIotLogsV2
レイテンシ=サーバ時刻 デバイス時刻 と定義
5分間のウィンドウで50%値、
90%値、最⼤値を集計
CloudWatch Insights で可視化
ダッシュボードに追加も可能
各サービスに関する詳細情報
•
Black Belt をご参照ください
•
[AWS IoT Core Black Belt] / [Amazon CloudWatch Black Belt] で検索
• https://aws.amazon.com/jp/blogs/news/webinar-bb-aws-iot-core-2020/
全体像
AWS IoT Core 証明書 ポリシー
ルール
ルール
AWS サービス
AWS Lambda Amazon SQS
Amazon S3 Amazon Kinesis Amazon CloudWatch AWS IoT Device SDK
ネットワーク
繋がらない・メッセージが届かない時にどのように問題を切り分けるか?
FreeRTOS AWS IoT Greengrassデバイス
…AWS IoT Device
Management AWS IoT Device Defender
デバイスが
AWS IoT
Core に繋がらない
メッセージが届か
ない、送れない
ルールがうまく
動かない
問題の切り分けフロー
デバイス
AWS IoT Core
AWS サービス
AWS IoT Core に
接続できない
デバイスからの
(への)
メッセージが届かない
•
ネットワークの確認
•
証明書・ポリシーの確認
•
Device SDK の設定の確認
Yes
No
Connect の成功 (デバイス側)
Connect のログ/メトリクス (クラウド側)
メッセージの
QoS1での送信・受信 (デバイス側)
テスト画面での
Pub/Sub・ログ (クラウド側)
•
トピック・ポリシーの確認
•
Device SDK の設定の確認
Yes
ルールがうまく動かない
No
•
ルール・
IAMロールの確認
•
AWS SDK の設定の確認
Yes
OK
No
ルールのログ・メトリクス
呼び出し先サービスのログ・メトリクス
切り分け時の確認箇所
問題修正時の確認箇所
AWS IoT Core
で最初にやること
エンドポイントの有効化
ログの有効化
(必要に応じて)
初めは無効になっているので
ステータスの確認から有効化
開発時はデバッグもしくは情報
レベルにしておくと便利
問題の切り分けフロー
デバイス
AWS IoT Core
AWS サービス
AWS IoT Core に
接続できない
デバイスからの
(への)
メッセージが届かない
•
ネットワークの確認
•
証明書・ポリシーの確認
•
Device SDK の設定の確認
Yes
No
Connect の成功 (デバイス側)
Connect のログ/メトリクス (クラウド側)
•
トピック・ポリシーの確認
•
Device SDK の設定の確認
Yes
ルールがうまく動かない
No
•
ルール・
IAMロールの確認
•
AWS SDK の設定の確認
Yes
OK
No
切り分け時の確認箇所
問題修正時の確認箇所
AWS IoT Core
に接続できない
問題の切り分け箇所
• デバイス側
•
AWS IoT Device SDK の
ログ
• クラウド側
•
AWS IoT のモニタリング
•
CloudWatch ログ
確認するポイント
• デバイス側
• ネットワークは問題ないか?
•
Device SDK の設定は適切か?
• 証明書は問題ないか?
• クラウド側
• 証明書は有効か?
• 証明書の有効期限は切れていな
いか?
• 証明書にポリシーがアタッチさ
れているか?
• ポリシーは適切か?
AWS IoT Core
への接続が成功しているかを確認する
(
デバイス側
)
AWS IoT Device SDK のログ
を確認する
例
: AWS IoT Device SDK Python v2
(awsiotsdk==1.5.6)
実装例
mqtt_connection =
mqtt_connection_builder.mtls_from_path(
endpoint
=”xxx.iot.region.amazonaws.com",
client_id
=”test-client",
…
)
connect_future = mqtt_connection.connect()
connect_future.result()
…
mqtt_connection.publish(
topic
=”my/topic", …)
Traceback (most recent call last):
File ”publish.py", line 57, in <module>
main()
…
File ”publish.py", line 34, in connect
connect_future.result()
…
File
"/…/lib/python3.X/concurrent/futures/_base.py
", line 388, in __get_result
raise self._exception
awscrt.exceptions.AwsCrtError:
AWS_ERROR_MQTT_UNEXPECTED_HANGUP: The
connection was closed unexpectedly.
失敗時
(例外が発生)
AWS IoT Core
への接続が成功しているかを確認する
(
クラウド側
)
AWS IoT のモニタリング
(CloudWatch メトリクス)
接続成功数
※ マネジメントコンソールのスクリーン ショットは、2021/03現在、 「新しいコンソールエクスペリエンス」 からオプトインできる画面をベースに紹 介していますAWS IoT Core
への接続が成功しているかを確認する
(
クラウド側
)
CloudWatch ログ
fields @timestamp, @message
| sort @timestamp desc
| filter eventType = "Connect"
{ "timestamp": "2021-02-22 09:07:15.137", "logLevel": "INFO", "traceId": "33b7fe1a-ae31-1869-44a6-0ca9c143f549", "accountId": ”123456789012", "status": "Success", "eventType": "Connect", "protocol": "MQTT", "clientId": "test-client", “principalId”: “証明書ID", "sourceIp": ”123.45.67.89", "sourcePort": 12345 } { "timestamp": "2021-02-22 09:07:34.987", "logLevel": "ERROR", "traceId": "59625791-fc22-3e20-010e-c05f96f71121", "accountId": " 123456789012", "status": "Failure", "eventType": "Connect", "protocol": "MQTT", "clientId": "test-client", "principalId": “証明書ID", "sourceIp": " 123.45.67.89", "sourcePort": 12345, "reason": "AUTHORIZATION_FAILURE", "details": "Authorization Failure"
}
例
: 成功時
例
: 失敗時
ロググループ
: AWSIotLogsV2 へのクエリ例
AWS IoT Core
に接続できない
問題の切り分け箇所
• デバイス側
•
AWS IoT Device SDK の
ログ
• クラウド側
•
AWS IoT のモニタリング
•
CloudWatch ログ
確認するポイント
• デバイス側
• ネットワークは問題ないか?
•
Device SDK の設定は適切か?
• 証明書は問題ないか?
• クラウド側
• 証明書は有効か?
• 証明書の有効期限は切れていな
いか?
• 証明書にポリシーがアタッチさ
れているか?
• ポリシーは適切か?
接続失敗時の確認ポイント
(
デバイス側
)
ネットワーク
は問題ないか?
• 有線/無線LANは繋がっているか?
• 名前解決はできているか?
社内ネットワーク
などの制限されたネットワーク環境でよくある問題
•
8883 (もしくは443、MQTTの場合)ポートへの通信が許可されている
か?
•
MQTT プロトコルが許可されているか?
• プロキシ設定は必要か?
デバイス側のエラーの種類も異なります
awscrt.exceptions.AwsCrtError:
AWS_IO_DNS_INVALID_NAME: Host name was invalid
for dns resolution.
参考
: AWS IoT Device SDK
の
Proxy
サポート状況
(2021/03
現在
)
•
HTTP Proxy とは HTTP CONNECT メソッドによる HTTP tunnel をサポートしているプロキシを指しています。
•
Python SDK v1 では
PySocks ライブラリ
によるプロキシ接続のサンプルを提供しており、サンプルには掲載がないです
が
PySocks の機能としてHTTPのBasic認証、SOCKS5の認証をサポートしています。
•
MQTT over WebSocket を利用する場合は SigV4 による認証となります。
•
AWS IoT Greengrass は v1.7 以降で HTTP Proxy をサポートしています。
Device SDK
バージョン
v1
バージョン
v2
Python
プロトコル
: MQTT, MQTT over WebSocket
プロキシ
: SOCKS5, HTTP
プロトコル
: MQTT over WebSocket
プロキシ
: HTTP
Node.js
-
プロトコル
プロキシ
: HTTP
: MQTT over WebSocket
Java
-
プロトコル
: MQTT over WebSocket
プロキシ
: HTTP
C++
-
プロトコル
: MQTT over WebSocket
プロキシ
: HTTP
Embedded C
v3.0.1:
サンプル
を提供
プロトコル
: MQTT、プロキシ: HTTP
https://github.com/aws-samples/aws-iot-device-sdk-embedded-c-http-proxy-supportv4 (202103.00):
-接続失敗時の確認ポイント
(
デバイス側
)
Device SDK の設定
は適切か?
例
: AWS IoT Device SDK Python v2
mqtt_connection = mqtt_connection_builder.mtls_from_path(
endpoint
=
”xxx-ats.iot.your-region.amazonaws.com"
,
client_id
=
"test-client"
,
cert_filepath
=
”xxx-certificate.pem.crt"
,
pri_key_filepath
=
”xxx-private.pem.key"
,
ca_filepath
=
"AmazonRootCA1.pem"
,
…
)
エンドポイント
URLに誤りはないか
証明書を登録したリージョンか
ポリシーで許可したクライアント
ID
(もしくはモノの名前)になっているか?
証明書・秘密鍵のパスやファイル名は正しいか?
間違っている場合は
FileNotFoundError になります
FileNotFoundError: [Errno 2] No such file or
directory: ‘xxx-certificate.pem.crt'
接続失敗時の確認ポイント
(
デバイス側
)
証明書
は問題ないか?
(独自CA利用時など)
• 証明書に問題がある場合など、TLSのレイヤーで接続に失敗している場
合、
CloudWatch にエラーが記録されない
•
OpenSSL コマンドでエンドポイントへの接続をテスト
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/diagnosing-connectivity-issues.html#troubleshooting-authenticationopenssl s_client -connect
xxx-ats
.iot.
aws-region
.amazonaws.com:8443
-CAfile AmazonRootCA1.pem -cert
certificate.pem
-key
privateKey.pem
接続失敗時の確認ポイント
(
クラウド側
)
証明書は
有効
か?
• マネジメントコンソールから作成
した場合、デフォルトでは無効
証明書の
ID (363f08f46…. のような
長い文字列
)の確認方法
• 証明書をダウンロードしたときの
ファイル名を確認
(証明書のIDの
先頭と一致
)
無効になっている場合は
接続失敗時の確認ポイント
(
クラウド側
)
証明書の
有効期限
は切れていないか?
(独自CAの場合)
•
AWS IoT Core で発行した証明書の場
合は、
2049年12月末 (UTC)まで有効
•
AWS IoT Device Defender の監査を利
用することで、
CA証明書やクライア
ント証明書の有効期限切れをチェッ
ク可能
接続失敗時の確認ポイント
(
クラウド側
)
証明書に
ポリシーがアタッチ
されているか?
• モノのグループに対してポリ
シーをアタッチしている場合は、
証明書とモノの紐付け、モノと
グループの紐付け、グループと
ポリシーの紐付けを確認
ポリシーがアタッチされてい
ない場合は、アクションから
「ポリシーのアタッチ」
接続失敗時の確認ポイント
(
クラウド側
)
ポリシー
に適切な
接続の権限
が与えられているか?
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/connect-policy.html{
"Version"
:
"2012-10-17"
,
"Statement"
: [
{
"Effect"
:
"Allow"
,
"Action"
: [
"iot:Connect"
],
"Resource"
: [
"arn:aws:iot:us-east-1:123456789012:client/client1”
]
},
…
]
}
iot:Connect を確認
リージョン・アカウント
ID
は正しいか?
クライアント
IDは正しいか?
(デバイス側の設定と一致させる)
${iot:Connection.Thing.ThingName}
のようなポリシー変数を使う場合は、モノと
証明書が紐付けられていることを確認する
問題の切り分けフロー
デバイス
AWS IoT Core
AWS サービス
AWS IoT Core に
接続できない
デバイスからの
(への)
メッセージが届かない
•
ネットワークの確認
•
証明書・ポリシーの確認
•
Device SDK の設定の確認
Yes
No
メッセージの
QoS1での送信・受信 (デバイス側)
テスト画面での
Pub/Sub・ログ (クラウド側)
•
トピック・ポリシーの確認
•
Device SDK の設定の確認
Yes
ルールがうまく動かない
No
•
ルール・
IAMロールの確認
•
AWS SDK の設定の確認
Yes
OK
No
切り分け時の確認箇所
問題修正時の確認箇所
Publish / Subscribe
できない
問題の切り分け箇所
• クラウド側
•
AWS IoT のテスト画面
•
AWS IoT のモニタリング
•
CloudWatch ログ
• デバイス側
•
AWS IoT Device SDK の
ログ
確認するポイント
• クラウド側
• ポリシーは適切か
• デバイス側
•
Device SDK の実装は適切か
• 番外編
•
Basic Ingest を利用する場合
•
Boto3 を利用する場合
デバイスとのメッセージングを確認する
(
クラウド側
)
AWS IoT
のテスト画面
デバイスからのメッセージを確認
デバイスへメッセージを送信
デバイスがメッセージを送る
トピックにサブスクライブ
トピックにメッセージが届け
ば表示される
デバイスがサブスクライブし
ているトピック
QoS 1 を選択して確実に配信
デバイスとのメッセージングを確認する
(
クラウド側
)
AWS IoT のモニタリング
(
CloudWatch
メトリクス
)
Inbound: デバイスから IoT Core へのメッセージ数
Outbound: IoT Core からデバイスへのメッセージ数
※ マネジメントコンソールのテスト画面を利用している場合は、デバイスだけでなく、
テスト画面で
Publish / Subscribe したメッセージの件数も含まれます
クラウドへのメッセージを確認する
(
デバイス側
)
AWS IoT Device SDK のログ
を確認する
例
: AWS IoT Device SDK Python v2
(awsiotsdk==1.5.6)
実装例
…
connect_future = mqtt_connection.connect()
connect_future.result()
…
publish_future, _ = mqtt_connection.publish(
topic
=”my/topic",
payload
=’{“hello”: “world”}’,
qos
=mqtt.QoS.AT_LEAST_ONCE,
)
publish_future.result(
timeout
=
5
)
Traceback (most recent call last):
File ”publish.py", line 60, in <module>
main()
…
File ”publish.py", line 49, in run
publish_future.result(timeout=5)
File
"/…/lib/python3.X/concurrent/futures/_base.py
", line 441, in result
raise TimeoutError()
concurrent.futures._base.TimeoutError
失敗時
(例外が発生)
デバイス
AWS IoT Core
デバイスからのメッセージを確認する
(
クラウド側
)
CloudWatch ログ
{ "timestamp": "2021-02-22 09:07:15.137", "logLevel": "INFO", "traceId": "33b7fe1a-ae31-1869-44a6-0ca9c143f549", "accountId": ”123456789012", "status": "Success", "eventType": ”Publish-In", "protocol": "MQTT", “topicName”: "トピック名", “clientId”: “クライアントID", “principalId”: “証明書ID", "sourceIp": ”123.45.67.89", "sourcePort": 12345 } { "timestamp": "2021-02-22 09:07:34.987", "logLevel": "ERROR", "traceId": "59625791-fc22-3e20-010e-c05f96f71121", "accountId": " 123456789012", "status": "Failure", "eventType": ”Publish-In", "protocol": "MQTT", “topicName”: "トピック名", “clientId”: “クライアントID", "principalId": “証明書ID", "sourceIp": " 123.45.67.89", "sourcePort": 12345, "reason": "AUTHORIZATION_FAILURE", "details": "Authorization Failure"}
例
: 成功時 (デバイスからIoT Core)
例
: 失敗時
fields @timestamp, @message
| sort @timestamp desc
| filter eventType = ”Publish-In"
ロググループ
: AWSIotLogsV2 へのクエリ例
デバイス
AWS IoT Core
クラウドからのメッセージを確認する
(
デバイス側
)
AWS IoT Device SDK のログ
を確認する
例
: AWS IoT Device SDK Python v2
(awsiotsdk==1.5.6)
実装例
…
connect_future = mqtt_connection.connect()
connect_future.result()
…
subscribe_future, _ =
mqtt_connection.subscribe(
topic
=”my/topic",
qos
=mqtt.QoS.AT_LEAST_ONCE,
callback
=my_callback,
)
subscribe_future.result(
timeout
=
5
)
Traceback (most recent call last):
File ”subscribe.py", line 60, in <module>
main()
…
File ”subscribe.py", line 47, in run
subscribe_future.result(timeout=5)
File
"/…/lib/python3.X/concurrent/futures/_base.py
", line 441, in result
raise TimeoutError()
concurrent.futures._base.TimeoutError
失敗時
(例外が発生)
デバイス
AWS IoT Core
デバイスへのメッセージを確認する
(
クラウド側
)
CloudWatch ログ
fields @timestamp, @message
| sort @timestamp desc
| filter eventType = ”Subscribe"
ロググループ
: AWSIotLogsV2 へのクエリ例
{ "timestamp": "2021-02-22 09:07:15.137", "logLevel": "INFO", "traceId": "33b7fe1a-ae31-1869-44a6-0ca9c143f549", "accountId": ”123456789012", "status": "Success", "eventType": ”Subscribe", "protocol": "MQTT", “topicName”: "トピック名", “clientId”: “クライアントID", “principalId”: “証明書ID", "sourceIp": ”123.45.67.89", "sourcePort": 12345 } { "timestamp": "2021-02-22 09:07:34.987", "logLevel": "ERROR", "traceId": "59625791-fc22-3e20-010e-c05f96f71121", "accountId": " 123456789012", "status": "Failure", "eventType": ”Subscribe", "protocol": "MQTT", “topicName”: "トピック名", “clientId”: “クライアントID", "principalId": “証明書ID", "sourceIp": " 123.45.67.89", "sourcePort": 12345, "reason": "AUTHORIZATION_FAILURE", "details": "Authorization Failure"}
例
: 成功時
例
: 失敗時
デバイス
AWS IoT Core
デバイスへのメッセージを確認する
(
クラウド側
)
CloudWatch ログ
fields @timestamp, @message
| sort @timestamp desc
| filter eventType = ”Publish-Out"
ロググループ
: AWSIotLogsV2 へのクエリ例
{ "timestamp": "2021-02-22 09:07:15.137", "logLevel": "INFO", "traceId": "33b7fe1a-ae31-1869-44a6-0ca9c143f549", "accountId": ”123456789012", "status": "Success", "eventType": ”Publish-Out", "protocol": "MQTT", “topicName”: "トピック名", “clientId”: “クライアントID", “principalId”: “証明書ID", "sourceIp": ”123.45.67.89", "sourcePort": 12345 } { "timestamp": "2021-02-22 09:07:34.987", "logLevel": "ERROR", "traceId": "59625791-fc22-3e20-010e-c05f96f71121", "accountId": " 123456789012", "status": "Failure", "eventType": ”Publish-Out", "protocol": "MQTT", “topicName”: "トピック名", “clientId”: “クライアントID", "principalId": “証明書ID", "sourceIp": " 123.45.67.89", "sourcePort": 12345, "reason": "AUTHORIZATION_FAILURE", "details": "Authorization Failure"}
例
: 成功時
例
: 失敗時
デバイス
AWS IoT Core
Publish / Subscribe
できない
問題の切り分け箇所
• クラウド側
•
AWS IoT のテスト画面
•
AWS IoT のモニタリング
•
CloudWatch ログ
• デバイス側
•
AWS IoT Device SDK の
ログ
確認するポイント
• クラウド側
• ポリシーは適切か
• デバイス側
•
Device SDK の実装は適切か
• 番外編
•
Basic Ingest を利用する場合
•
Boto3 を利用する場合
Publish
失敗時の確認ポイント
(
クラウド側
)
ポリシー
は適切か?
(デバイスから Publish する場合)
※
iot:Connect は省略しています
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/pub-sub-policy.html{
"Version"
:
"2012-10-17"
,
"Statement"
: [
…
{
"Effect"
:
"Allow"
,
"Action"
: [
"iot:Publish"
],
"Resource"
: [
"arn:aws:iot:us-east-1:123456789012:topic/data/my-device”,
"arn:aws:iot:us-east-1:123456789012:topic/data/${iot:Connection.Thing.ThingName}”,
]
},
…
]
}
iot:Publish を確認
トピック名が正しいか
${iot:Connection.Thing.ThingName}
のようなポリシー変数を使う場合は、モノと
証明書が紐付けられていることを確認する
デバイス
AWS IoT Core
Subscribe
失敗時の確認ポイント
(
クラウド側
)
ポリシー
は適切か?
(デバイスから Subscribe する場合)
※
iot:Connect は省略しています
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/pub-sub-policy.html{
"Version"
:
"2012-10-17"
,
"Statement"
: [
…
{
"Effect"
:
"Allow"
,
"Action"
: [
"iot:Subscribe"
],
"Resource"
: [
"arn:aws:iot:us-east-1:123456789012:topicfilter/cmd/my-device"
]
},
{
"Effect"
:
"Allow"
,
"Action"
: [
"iot:Receive"
],
"Resource"
: [
"arn:aws:iot:us-east-1:123456789012:topic/cmd/my-device"
]
},
…
]
}
iot:Subscribe を確認
Subscribe は topicfilter になる点に注意
Receive の場合は topic
iot:Receive も必要
デバイス
AWS IoT Core
Publish/Subscribe
失敗時の確認ポイント
(
デバイス側
)
Device SDKの実装
は適切か?
例
: AWS IoT Device SDK Python v2
(awsiotsdk==1.5.6)
実装例
(QoS1)
デバイス
AWS IoT Core
…
connect_future = mqtt_connection.connect()
connect_future.result()
…
mqtt_connection.publish(
topic
=”my/topic",
payload
=’{“hello”: “world”}’,
qos
=mqtt.QoS.AT_LEAST_ONCE,
)
…
connect_future = mqtt_connection.connect()
connect_future.result()
…
publish_future, _ = mqtt_connection.publish(
topic
=”my/topic",
payload
=’{“hello”: “world”}’,
qos
=mqtt.QoS.AT_LEAST_ONCE,
)
publish_future.result(
timeout
=
5
)
QoS=1 を指定しているが、
ACK を待たない
QoS=1 を指定して、ACK を待つ
ペイロードのサイズは
128KBまで
参考
: Basic Ingest
を利用する場合
メリット
• メッセージブローカーを経由しないために、メッセージ
ングのコストが不要となる
想定ユースケース
• センサーからデータをクラウドへ上げるなど、送信した
メッセージをsubscriberに送る必要がなく、ルール
エンジンを発⽕できればよい使い⽅
すでにご利⽤いただいているお客様向け
• デバイス側の設定が可能であれば、IoT Coreの設
定はそのままで、デバイス側のpublish topic
に ”$aws/rules/rule名”を追加するだけで利⽤
可能
• ポリシーでも ”$aws/rules/rule名” をつけた
トピックに対する Publish を許可する
デバイス側からPublishするトピック $aws/rules/{ルール名}/使いたいtopic e.g.) $aws/rules/act-lambda/data/{device_name} 追加する$aws/rules/ルール名の3階層は、トピックの8階層の 制限または256⽂字合計制限の⽅にカウントされません。 ルール側のSQL句のtopic指定は、以下でよい data/{device_name} https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-basic-ingest.htmlデバイス
AWS IoT Core
参考
: AWS Lambda
などから
Boto3
を利用する場合の注意点
Boto3 から AWS IoT データプレーン(publish, update_thing_shadow など)を利用す
る場合は、
endpoint_url
として
ATS
エンドポイントの
URL
を指定
する
import
boto3
iot_data = boto3.client(
"iot-data"
,
endpoint_url=
"https://xxxxx-ats.iot.<region>.amazonaws.com"
)
iot_data.update_thing_shadow(
thingName=
"test-device"
,
payload=
'{"state": {}}'
)
endpoint_url で ATS エンドポイントを指定
https:// を付ける
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iot-data.htmlaws iot describe-endpoint --endpoint-type iot:Data-ATS
エンドポイントの確認方法
(AWS CLI)
問題の切り分けフロー
デバイス
AWS IoT Core
AWS サービス
AWS IoT Core に
接続できない
デバイスからの
(への)
メッセージが届かない
•
ネットワークの確認
•
証明書・ポリシーの確認
•
Device SDK の設定の確認
Yes
No
•
トピック・ポリシーの確認
•
Device SDK の設定の確認
Yes
ルールがうまく動かない
No
•
ルール・
IAMロールの確認
•
AWS SDK の設定の確認
Yes
OK
No
ルールのログ・メトリクス
呼び出し先サービスのログ・メトリクス
切り分け時の確認箇所
問題修正時の確認箇所
ルールがうまく動かない
問題の切り分け箇所
•
AWS IoT Core
•
AWS IoT のモニタリング
•
CloudWatch ログ
• 呼び出し先サービス
•
CloudWatch メトリクス
•
CloudWatch ログ
確認するポイント
•
AWS IoT Core
• ルールのクエリ
• アクションの設定
• ルールのIAMロール
• エラーアクション
ルールの実行を確認する
(AWS IoT Core
側
)
AWS IoT
のモニタリング
(
CloudWatch
メトリクス
)
CloudWatch
ログ
例
: RuleMatch
ルールが実行された回数
fields @timestamp, @message
| sort @timestamp desc
| filter eventType = ”RuleMatch"
{ "timestamp": "2021-02-25 09:56:05.744", "logLevel": "INFO", "traceId": "574e579f-2b16-0625-20d1-fc65f9506aea", "accountId": ”123456789012", "status": "Success", "eventType": "RuleMatch", “clientId”: “クライアントID", “topicName”: “トピック名", “ruleName”: “ルール名", “principalId”: “証明書ID" }
ロググループ
: AWSIotLogsV2 へのクエリ例
ログが出ていない場合は、ルールのクエリを確認
ルールアクションの実行を確認する
(AWS IoT Core
側
)
CloudWatch ログ
例
: RuleExecution
fields @timestamp, @message
| sort @timestamp desc
| filter eventType = ”RuleExecution"
{ "timestamp": "2021-02-25 09:57:49.101", "logLevel": "INFO", "traceId": "82af95b8-6831-d609-5c2e-f07344a406ff", "accountId": "123456789012", "status": "Success", "eventType": "RuleExecution", “clientId”: “クライアントID", “topicName”: “トピック名", “ruleName”: “ルール名", “ruleAction”: “実行するアクション", “resources”: { アクションの対象リソースの情報 }, “principalId”: “証明書ID" } { "timestamp": "2021-02-25 10:08:06.792", "logLevel": "ERROR", "traceId": "d74418c4-7386-855e-1c14-b89b6055dfbd", "accountId": "123456789012", "status": "Failure", "eventType": "RuleExecution", (中略)
"details": "User: arn:aws:sts::123456789012:assumed-role/xxx-iot-rule-role/wVsRP81A is not authorized to perform: service:Action on resource: arn:aws:service: 123456789012 :type/name (Service: XXX; Status Code: 400; Error Code: AccessDeniedException; Request ID: f2d458a4-81ff-f3d7-aa65-21e2945e18ef; Proxy: null)"
}
例
: 成功時
例
: 失敗時
ロググループ
: AWSIotLogsV2 へのクエリ例
ルールアクションの実行を確認する
(
呼び出し先サービス側
)
CloudWatch メトリクス
(例: AWS Lambda)
関数の呼び出し回数
関数内でのエラー率
関数の実行時間
スロットルの発生数
関数の同時実行数
例えば、
AWS Lambdaであれば関数の同時
実行数や最大実行時間に上限がある
ルールの実行を確認する
(
呼び出し先サービス側
)
CloudWatch ログ
(例: AWS Lambda)
START RequestId: f02fb15c-2e21-4942-b777-7ac816efb042 Version: $LATEST
…
関数内で print や logging で出力したログ …
END RequestId: f02fb15c-2e21-4942-b777-7ac816efb042 REPORT RequestId: f02fb15c-2e21-4942-b777-7ac816efb042 Duration: 272.18 ms Billed Duration: 273 ms Memory Size: 128 MB Max Memory Used: 54 MB
START RequestId: ecfc9219-6caa-454f-9be3-a9f5de033fbf Version: $LATEST
[ERROR] RuntimeError: my runtime error Traceback (most recent call last):
File "/var/task/lambda_function.py", line 9, in lambda_handler raise RuntimeError("my runtime error")
END RequestId: ecfc9219-6caa-454f-9be3-a9f5de033fbf REPORT RequestId: ecfc9219-6caa-454f-9be3-a9f5de033fbf
Duration: 432.48 ms Billed Duration: 433 ms Memory Size: 128 MB Max Memory Used: 51 MB Init Duration: 121.19 ms
例
: 成功時
例
: エラー発生時
fields @timestamp, @message
| sort @timestamp desc
| limit 20
ロググループ
: /aws/lambda/関数名 へのクエリ例
ルールがうまく動かない
問題の切り分け箇所
•
AWS IoT Core
•
AWS IoT のモニタリング
•
CloudWatch ログ
• 呼び出し先サービス
•
CloudWatch メトリクス
•
CloudWatch ログ
確認するポイント
•
AWS IoT Core
• ルールのクエリ
• アクションの設定
• ルールのIAMロール
• エラーアクション
ルールの確認ポイント
クエリ
は適切か?
トピックの絞り込み・条件
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-sql-reference.html
SELECT
*
FROM
'data/thermometer/+'
WHERE
temperature > 50
ルール実行対象のトピックは正しいか?
ワイルドカードは適切か?
ルール実行条件は正しいか?
ペイロードの
JSON構造と合って
いるか?
呼び出し先サービスに渡すペイロード
SELECT
device_id, temperature, timestamp() as server_timestamp
FROM
'data/device-id'
後段処理に渡すペイロードは必要十分か?
{ ”device_id": ”my-device-0001", ”temperature": 47.3, ”humidity": 32.0 }デバイスからのペイロード例
ルールの確認ポイント
ルールアクション
の設定は適切か?
アクション・エラーアク
ションは間違っていないか
送信先のリソースは正しいか?
送信するペイロードの
設定は適切か?
ルールの確認ポイント
ルールの
IAMロール
は適切か?
権限が不足している場合は、
ロールの更新をクリック
ルールの確認ポイント
ルールアクション実行時に問題が発生した
場合に、エラーアクションをトリガーする
問題の例
• ルールのIAMロールに必要な権限が不足
している
• 呼び出し先サービスのスループットを超
える入力がある
エラーアクションの例
•
DynamoDB への書き込みアクションに
失敗した時に、
SQS へ一時的にメッ
セージを退避する
エラーアクションに記録されるメッセージ例
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/rule-error-handling.html { “ruleName”: “ルール名", “topic”: “トピック", "cloudwatchTraceId": "a16bca98-e92e-a1eb-6685-bc00b96a3b40", “clientId”: “クライアントID", “base64OriginalPayload”: “元のメッセージのペイロード(Base64)", "failures": [ { "failedAction": "DynamoDBv2Action", "failedResource": ”MyTable","errorMessage": "DynamoDBv2 Put record failed. The error received was User:
arn:aws:sts::123456789012:assumed-role/MyRuleRole/r77DPsEZ is not authorized to perform: dynamodb:PutItem on resource:
arn:aws:dynamodb:123456789012:table/MyTable (Service: AmazonDynamoDBv2; Status Code: 400; Error Code:
AccessDeniedException; Request ID: …; Proxy: null). Message arrived on: my/topic, Action: dynamoDBv2, Table: MyTable"
} ] }