投稿日

デバイスの通信量を監視しよう! ~オペレーターやグループ単位で通信量が取れるようになりました~

こんにちは!ソリューションアーキテクトの今井です。ニックネームはfactoryと申します。早速ですが、今年の2月にオペレーター(SORACOMアカウントのこと)やグループ単位でデータ通信量を取得できるAPIがリリースされました。

IoT SIM のデータ通信量をオペレーターまたはグループごとに取得できる API をリリースしました

このAPIを使うと「利用しているすべてのSIMの日次通信量合計をトラックする」だったり「SIMグループごともしくは特定のSIMグループの日次通信量のトラックして、一定量以上の通信が発生したらアラートを受け取る」ということが可能になります。また、逆に「想定される通信量が発生していない」ことをフックにシステムの異常の予兆を得ることもできるようになります。

この記事では、APIについてご紹介をした上で、SORACOMのイベントハンドラーやAmazon CloudWatchなどを使って実際の監視業務を実装するアイデアについて論じたいと思います。

まずはAPIのご紹介

今回新たにリリースされたAPIは以下の2つです。どちらのAPIも対象と集計単位(日または月)、そして取得範囲を指定して通信量データの実績を取得するイメージです。

Stats:getAirStatsOfGroup: 指定したグループに所属するすべての IoT SIM のデータ通信量履歴を取得する API、引数は以下の通りです。なお、SIMがグループに所属している間に行われた通信がグループに対して計上されます。SIMの所属グループを変更するとそのタイミングから新しいグループに対して通信量が計上されます。

  • group_id
    • 対象のSIMグループのID
  • period
    • データの集計単位。month(月単位)またはday(日単位)のいずれかを選択
  • from
    • データ取得範囲の開始日時(Unixtime秒)
    • periodがmonthの場合、現在時刻の 3 か月前 〜 現在時刻の UNIX 時間 (秒) が指定可能。
    • periodがdayの場合、現在時刻の 6 日前 〜 現在時刻の UNIX 時間 (秒) を指定可能。
  • to
    • データ取得範囲の終了日時(Unixtime秒)
    • periodがmonthの場合、現在時刻の 3 か月前 〜 現在時刻の UNIX 時間 (秒) が指定可能。
    • periodがdayの場合、現在時刻の 6 日前 〜 現在時刻の UNIX 時間 (秒) を指定可能。

Stats:getAirStatsOfOperator: 指定したオペレーターが保有するすべての IoT SIM のデータ通信量履歴を取得する API、引数は以下のとおりです。

  • operator_id
    • 対象のオペレーターのID
  • period
    • データの集計単位。month(月単位)またはday(日単位)のいずれかを選択
  • from
    • データ取得範囲の開始日時(Unixtime秒)
    • periodがmonthの場合、現在時刻の 3 か月前 〜 現在時刻の UNIX 時間 (秒) が指定可能。
    • periodがdayの場合、現在時刻の 6 日前 〜 現在時刻の UNIX 時間 (秒) を指定可能。
  • to
    • データ取得範囲の終了日時(Unixtime秒)
    • periodがmonthの場合、現在時刻の 3 か月前 〜 現在時刻の UNIX 時間 (秒) が指定可能。
    • periodがdayの場合、現在時刻の 6 日前 〜 現在時刻の UNIX 時間 (秒) を指定可能。

fromについての注意点:指定したタイムスタンプを含む日の00:00:00または月の初日の00:00:00が実際の集計対象の起点となります。
toについての注意点:指定したタイムスタンプを含む日の24:00:00または月の最終日の24:00:00が実際の集計対象の終点となります。

やってみよう!

ではまずはSORACOM CLIを使ってオペレーター全体の通信量を取得してみます。fromとtoは実際に手元で動かした現在時刻とそこから6日前のUnixtime(秒)を指定していますので、(このコマンドの実際の発行時点における)今日を含んだ過去7日間のデータを取得するコマンド、ということになります。また、SORACOM CLIを利用する場合、operator_id は自動的に補完してくれます。

$ soracom stats air operators get --period day --from 1681521336 --to 1682039734

[
       {
                "downloadByteSizeTotal": 16586277,
                "unixtime": 1681516800,
                "uploadByteSizeTotal": 8808383
        },
        {
                "downloadByteSizeTotal": 19287895,
                "unixtime": 1681603200,
                "uploadByteSizeTotal": 11388108
        },
        {
                "downloadByteSizeTotal": 57397259,
                "unixtime": 1681689600,
                "uploadByteSizeTotal": 12814069
        },
        {
                "downloadByteSizeTotal": 65319315,
                "unixtime": 1681776000,
                "uploadByteSizeTotal": 13625627
        },
        {
                "downloadByteSizeTotal": 15195253,
                "unixtime": 1681862400,
                "uploadByteSizeTotal": 13046057
        },
        {
                "downloadByteSizeTotal": 13092135,
                "unixtime": 1681948800,
                "uploadByteSizeTotal": 11063020
        },
        {
                "downloadByteSizeTotal": 672124,
                "unixtime": 1682035200,
                "uploadByteSizeTotal": 573677
        }
]

ダウンロード(downloadByteSizeTotal)、アップロード(uploadByteSyzeTotal)それぞれの量が取得できました!すばらしい!

が、ちょっとこれだと使いづらいという方もいらっしゃいますよね。例えば「日毎の通信量をMB単位でCSV形式で出力したい。あと、毎回from/toを指定するのは面倒なので現在時刻から7日分のデータを取れるようにしたい」という場合、こういったイメージのワンライナーになります。なお、このコマンドにはnode.jsjqを利用していますのでご注意ください。

$ soracom stats air operators get --period day --from `node -e 'console.log(Math.floor(Date.now()/1000 - 86400 * 6))'`   --to `node -e 'console.log(Math.floor(Date.now()/1000))'` | jq -r '.[] | [(.unixtime|strftime("%Y-%m-%d")), (.uploadByteSizeTotal/1024/1024*100|floor/100), (.downloadByteSizeTotal/1024/1024*100|floor/100)] | @csv'

"2023-04-15",8.4,15.81
"2023-04-16",10.86,18.39
"2023-04-17",12.22,54.73
"2023-04-18",12.99,62.29
"2023-04-19",12.44,14.49
"2023-04-20",10.55,12.48
"2023-04-21",0.59,0.69

どうでしょう。これならスプレッドシートにぺたっと貼り付けることもできますね。使いみちのイメージがついてきたのではないでしょうか。

使い道を考える: イベントハンドラーを利用して通信量が一定量を超えたら通知を受ける

ここまではAPIを直接取り扱ってきましたが、SORACOMプラットフォームにはイベントハンドラーと呼ばれる便利な機能があり、GUIでしきい値監視の設定ができるようになっています。下記は特定のグループの日次通信量が100MBを超えたらメールでアラート通知をするという例ですが、もちろん前述のようにオペレータ全体の通信量監視もできますし、日次ではなく月次での監視も可能です。

これで本記事の冒頭で触れたような「オペレータ全体やSIMグループの日次通信量のトラックして、一定量以上の通信が発生したらアラートを受け取る」というようなユースケースは実現できました!

使い道を考える: Amazon CloudWatchで利用量の可視化としきい値監視を行う

イベントハンドラーがあれば多くのユースケースを満たすことができると思いますが、あえてもう一歩踏み込んでみるとすると「時系列に利用量を保存しておいてトラフィックのトレンドを把握したい」というケースもあると思います。方法論としてはどこかにデイリーで利用量を保存しておくのがよいでしょう。

ここではAmazon CloudWatch(以下、CloudWatch)を利用してみようと思います。CloudWatchはAWSの提供する統合的なモニタリングサービスで、様々なAWSのサービスがこれを利用してリソースの利用量などの情報をユーザーに提供してくれます。今回は「カスタムメトリクス」と呼ばれる独自のデータを取り扱う機能を使って、SORACOMの利用量をCloudWatchに格納してみたいと思います。

下記はSORACOMの社員が利用している検証用のオペレータの利用量(uploadByteSizeTotal、downloadByteSizeTotalそれぞれ)をCloudWatchに保存してグラフ化してみました。4月27日に明らかに他と違う利用トレンドがあったのがひと目で読み取れますね。

CloudWatchの「CloudWatch Alarm」という機能を使うと前述のようを使ってしきい値監視を設定することもできます。「しきい値を下回った場合にアラート」というようなこともできますので、想定される通信量が発生していないことをトラップすることもできますし、更にアドバンストな使い方としては下記の例のように機械学習ベースのAnomaly Detectionによる外れ値判定も可能です。

このCloudWatch Alarmをしかけたうえで、1日に1回SORACOMからgetAirStatsOfOperatorでデータを取得し、CloudWatchにカスタムメトリクスとして保存していくと、トラフィックに問題があった際、翌日にアラートを受け取ることができるようになります。非常に単純ですが、まとめとして構成を絵にすると以下のようになります。

この仕組みをざっとデプロイするためのAWS CDKのスタックを公開してますので、ご興味ある方はそちらもぜひご覧ください!

soracom-stats-monitor

まとめ

この記事では新たにリリースされたgetAirStatsOfOperatorやgetAirStatsOfGroupというAPIを利用してオペレーターやグループ単位でのSIMの利用量を抽出し、活用する方法をご紹介してきました。このように、SORACOMをコネクティビティとして利用するだけで、みなさまのIoTシステム全体の通信量が可視化できるようになります。

SORACOMプラットフォームはデバイスとクラウドを安全かつ簡単に接続するためにさまざまな機能やツールを提供しています。みなさまのIoTプロジェクトに役立てていただけるとうれしいです!

― ソラコム今井 (factory)