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を想定しています。
{
"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で確認出来ます。
{
"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プログラムの動作に関しても保障いたしませんので、参考程度にしてください。