Edited at

AWS IoTの利用状況を可視化するCloudwatchカスタムメトリクスを作る

More than 1 year has passed since last update.


AWS IoTのカスタムメトリクス

AWS IoTのコンソール画面が変更され、dashボードが表示されるようになりました。が、thing単位での通信状況はわからないので、rule engineからLambdaへ送り、通信状況をcloudwatchのカスタムメトリクスで表示できるようにしてみました。

マルチテナント型で使う、や、想定外にメッセージが多いときにどのthingがどの位使っているかがわかれば解析が楽になるかなと思います。

現状のdashbordで見れる情報は、アカウント全体の利用状況で以下のように見えます。

では、カスタムメトリクス対応を作ってみましょう。


AWS操作


IAM

Lambdaから、cloudwatch からput_metric_dataを使うので、以下2つの権限を持った role を作成してください

AWSLambdaBasicExecutionRole

CloudWatchFullAccess


AWS Lambda

イベントトリガはAWS IoTから作成するので関数だけ作っておいてください。

Lambda から "create a lambda function" -> "configure function"

Name:任意 (ここでは IoT-payload-cal)

Description:任意

Runtime: Python2.7

として以下のコードを利用してください。

前提として dataは jsonで thingNameとしてthingの情報が上がってくるものとします。

例えば以下のようなjsonを想定しています。


example_event.json

{

"thingName": "xxxx",
<任意>
}

Lambdaの説明

AWS IoTの課金は、512byteを1-messageとしているのでmessage部分を 512byteで割って小数点を繰り上げしています。これで大まかには詳細利用状況が可視化できるかと思います。floatでcastしているのは、intのままだと小数点が切り捨てられるためです。

コードにはつけてないですが、通信量を見たい場合は、取得したbyte数を同様にカスタムメトリクスにputしてもらえれば、byte数で見ることができると思います。こちらは例えばSIMなどを使ってSIMのコストの概算をみるのによいかと思います。

import json

import math
import datetime
import boto3

CLW = boto3.client('cloudwatch')

def put_cloudwatch(thingName, value):
try:
now = datetime.datetime.now()
CLW.put_metric_data(
Namespace = "IoT_count",
MetricData = [{
"MetricName" : thingName,
"Timestamp" : now,
"Value" : value,
"Unit" : "Count"
}]
)
except Exception as e:
print e.message
raise

def lambda_handler(event, context):

thingName = event['thingName']
#JSON to String, and count string bytes
str_event = json.dumps(event)
byte_len = len(str_event)
#count message, AWS IoT 1-message = 512byte
msg_cnt = float(byte_len)/512

try:
put_cloudwatch(thingName, math.ceil(msg_cnt))
except Exception as e:
raise

return

roleはここで作った role を選択してください。


AWS IoT

AWS IoTから Rules => create

Name:任意 (ここでは、aws_iot_cal)

Description:任意

Using SQL version:beta

すべてのメッセージを通すので、

Attribute:*

Topic filter:#

とします。

Add Actionから、Invoke a Lambda function passing the message data

を選択configure actionから、先ほど作成したLambdaを指定します。


テスト

Lambdaからtest用jsonを作成して実行、もしくはAWS IoTへデータを送ります。

Lambdaのプログラムでも説明したましたが、jsonの中に thingName の情報を必ず入れてください。

lambdaのみで実行確認するには、例えば以下のようなjsonで確認出来ます。


test.json

{

"thingName": "testThing-1",
"key3": "value3",
"key2": "value2",
"key1": "value1"
}

testThing-1でメトリクスが作成されます。時間単位の積算データはcloudwatchのsumで見てください。

1つのNamespaceに複数のthingからputすると以下のようになります。


最後に

マルチテナント型や工場/設置場所別で分けたい場合はAWS IoTでtopicとrule enginによる打ち分けで、lambdaを分けて、namespaceを分けるなどすると、良いかもしれません。

大規模なthing登録の場合、全イベントでlambdaが発火されるので、lambdaの同時起動数などは注意が必要です。

lambdaの同時起動数が気になる場合にはlambdaの前段にkinesisを挟むつまり、AWS IoT -> kinesis streams -> Lambda とするとよいかと思います。

同じくcloudwatchのlimitも意識しておいたほうが良いでしょう。

また、カスタムメトリクスもメトリクス単位で少額ですが、課金が発生します。


免責

本投稿は、個人の意見で、所属する企業や団体は関係ありません。

また掲載しているsampleプログラムの動作に関しても保障いたしませんので、参考程度にしてください。