はじめに
以前、Kinesis Firehoseを動かして見るでもチラシの裏しましたが、Kinesis Firehoseは、Backend Serverを自分で構築/管理せずとも、Android Client AppやIOT機器のLogをS3やRedshiftに簡単に溜められる、というServiceです。
Google Analytics
, Amazon Mobile Analytics
と競合する領域ではありますが、Backend serverは構築管理したくないけど、生Logは欲しい、と言う場合に使えるServiceです (みんな大好きGoogle Analytics
は、無料版だと生LogのExportが出来ないのと、個人情報に該当する情報は送ってはいけないと言う制約があります)。
その他、詳細は紹介記事を参照して下さい。
- AWSが外部に一般供用するKinesis FirehoseはIoTなどのセンサデータをクラウドへ直接送る
- Amazon Kinesis StreamsとAmazon Kinesis Firehoseは何が違うのか
先日、やっとAndroid SDK v2.2.10でKinesis Firehoseをサポートしてくれました、FirehoseのClassも追加されています。動作確認用のAndroid Appを作ってFirehose経由でS3にLogをUploadするProtoを作ってみたので、その時の設定手順、Android AppのCodeをチラシの裏しておきます。
作業の全体の流れ
全体の流れは以下の様になっています。
- CognitoのIdendity Poolの作成
- Kinesis FirehoseのStreamの作成
- Android Appの作成、LogのUpload
- UploadされたLogの確認
注意
-
Firehose
はまだN. Virginia
,Oregon
,Ireland
の3 Regionのみサポートなので、Firehose
,Cognito
とも同じRegionで、この3つのどこかに作って下さい。
AWS CognitoのIdendity Poolの作成
CognitoのIdentity Poolを作成します。Cognitoは馴染みが無い方が多いと思いますが、最低限の設定でOKなので怖くないです、1分で終わります。RegionをN. Virginia
等に変更し、AWS Console→Cognitoに行き、Create new identity pool
を選択します
Step1
Identity pool name
は適当な名前を入れて、Enable access to unauthenticated identities
にCheckeを付けて、Create Pool
を選択し下さい。これでCognitoの設定は実質終わりです。
Step2
Your Cognito identities require access to your resources
と言うUIに移り、IAM roleの設定画面が出ますが、何も変えずにAllow
を選択して下さい。
Sample Code
すると、Sample codeのUIに移ります。"us-east-1:3030cfcf-4210-4980-99ab-34f941f4b16e"
などのIdentity Pool IDをコピペしておきます。
Kinesis FirehoseのStreamの作成
続いて、Kinesis FirehoseのDelivery Streamを作成します。
AWS Console→Kinesis firehoseに行き、Create Delivery Stream
を選択します
Step1
-
Destination
はS3を選択 -
Delivery stream name
は適当な名前を付ける (ここではtest_kinesis
とします) -
S3 bucket
は既存のS3 bucketを選択するか、新規作成する
上記設定をすれば、指定したS3 bucketにFirehoseのLogが溜まる様になります。
Step2
-
Buffer Size
は5
(MB) -
Buffer interval
は60
(秒) -
IAM role
はFirehose delivery IAM role
を選択
選択すると、IAM role
の設定画面になりますが、DefaultのままでAllow
を選択
上記設定で、60秒経過する or 5MB以上FirehoseにDataが溜まるとS3に書き出す設定になります。
Step3
このStepは只の最終確認なので、Create Delivery Stream
を選択して完了です。
Androidのcode
最後に、Cognito, Firehoseの設定内容をAndroid Appへの組み込みます。
Sample Appの仕様
以下Sample codeの仕様概要です。Amazonの公式FirehoseのAPI仕様書を参考に作りましたが、公式Documentに微妙に(Criticalな)Typoがあるので注意です。
- Buttonが3つある
- Button1/2をTapするとLogがたまり、Button3をTapするとServerにLogがPushされる
- Logは以下の様なjson形式
{"model":"SO-02H","andoid_ID":"434c3786437e39cf","date":"20160112T090920","message":"onCreate","app_name":"Firehose Test1"}
Customizeが必要な個所
以下のSample codeで個別にCustomizeが必要なのは、3箇所です
- CognitoのIdentity pool ID
us-east-1:3030cfcf-4210-4980-99ab-34f941f4b16e
- Kinesis FirehoseのStream名
test_kinesis
- AWSのRegion
US_EAST_1
Sample code
package com.your.package.name;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import android.provider.Settings;
import com.amazonaws.AmazonClientException;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.mobileconnectors.kinesis.kinesisrecorder.KinesisFirehoseRecorder;
import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.regions.Regions;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;
public class MainActivity extends ActionBarActivity{
KinesisFirehoseRecorder firehoseRecorder;
String android_id;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
saveFirehoseRecord("onCreate");
setContentView(R.layout.activity_main);
}
public void saveFirehoseRecord(String put_string) {
File directory = this.getCacheDir();
Regions region = Regions.US_EAST_1;
AWSCredentialsProvider provider = new CognitoCachingCredentialsProvider(
this,
"us-east-1:3030cfcf-4210-4980-99ab-34f941f4b16e",
Regions.US_EAST_1);
android_id = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
firehoseRecorder = new KinesisFirehoseRecorder(directory, region, provider);
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'kkmmss");
JSONObject json = new JSONObject();
try {
json.accumulate("model", Build.MODEL);
json.accumulate("andoid_ID", android_id);
json.accumulate("date", sdf.format(date));
json.accumulate("message", put_string);
json.accumulate("app_name", "Firehose Test1");
Log.e("KinesisFirehoseTest1", json.toString());
} catch (JSONException e) {
e.printStackTrace();
}
firehoseRecorder.saveRecord(json.toString(), "test_kinesis");
}
public void onClick(View v) {
switch(v.getId()) {
case R.id.button1:
Toast.makeText(MainActivity.this, "Button1 pressed", Toast.LENGTH_LONG).show();
saveFirehoseRecord("onClick-1 event");
break;
case R.id.button2:
Toast.makeText(MainActivity.this, "Button2 pressed", Toast.LENGTH_LONG).show();
saveFirehoseRecord("onClick-2 event");
break;
case R.id.button3:
Toast.makeText(MainActivity.this, "Button3 pressed - submit events", Toast.LENGTH_LONG).show();
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... v) {
try {
saveFirehoseRecord("onClick3 - submit events");
firehoseRecorder.submitAllRecords();
} catch (AmazonClientException ace) {
Log.e("KinesisFirehoseTest1", "submitAll failed!");
}
return null;
}
}.execute();
break;
}
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
}
}
その他
釈迦に説法だと思いますが、build.gradeの設定と、manifest.xmlの設定もお忘れ無く。
(1) build.gradleでKinesisのSDKを設定する
compile 'com.amazonaws:aws-android-sdk-kinesis:2.2.10'
(2)AndroidManifest.xmlで以下のPermissionを設定する
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
UploadされたLogの確認
最後に、実際にLogがS3にUploadされているかの確認です。Android app上のボタンをポチポチ押して、Logを発生させてみて下さい。
暫くすると、Firehoseで指定したS3 bucket上に、test_kinesis-2-2016-01-17-12-23-01-4e3483ed-44ce-44ed-87d7-43b77347ce7b
みたいなファイルが出来ると思うので、中身を確認して見て下さい。
最後に
Firehoseは、Serverの構築/管理無し(Zero administration)で、各種logをCloudにあげる事が可能なServiceです。同様のServiceとしてGoogle Analytics
やAWS Mobile Analytics
との比較を書いておきますが、Needsに合致すれば、とてもよいんじゃないかな、と思います。
(おまけ) Serverの構築/管理無しでLog収集可能なService比較
Serverの構築/管理無しに、Client AppやIOT機器のLogをCloudに溜めて解析したい、と言うNeedsに対して、Google Analytics
, Amazon Mobile Analytics
, Kinesis Firehose
の3つをProtoして触って来ました、以下、簡単ですが3者の比較です。
Google Analytics
Pros
- みんな大好きGA、無料
- GAのQuery APIを使いこなすとかなり複雑なQueryも可能、Query Explorerさいこーです
- GAのDashboardがかなり秀逸、多くのNeedsはこのDashboardの中で完結
- GAのTag Managerがかなり秀逸
- Client側からのLog Uploadの細かい制御(Networkが繋がっていない場合の遅延Upload, 途中で切れた場合のRetry etc)をGoogle Play Serviceがほぼ自動でやってくれる
Cons
- 生ログにはアクセスできない(GA Premium Accountという有料契約だと生ログ貰えます)
- 個人情報に該当する情報は送ってはいけない
- Record件数が多いと、Query時に問答無用にSamplingされる
- Log Updateが1日1回とやや遅い
Amazon Mobile Analytics
自分の周りでも認知度が微妙に低い気がしますが、Amazon版のGoogle Analytics対抗Serviceです
Pros
- 生ログがS3に溜まる
- Log Updateが1時間毎
Cons
- 有料 (やや高く
$1/100万 events
、1万台で1台辺り100 event/dayだと、$1/day) - Dashboardの機能はやや簡易的、Query機能も無し
- Google Analyticsに比べるとSDK側で補完してくれる機能、Configurationの余地が少ない
Kinesis Firehose
微妙にAmazon Mobile Analyticsと被ってる気もしますが、IOT用のLog収集Serviceで、Logを低遅延でS3/Redshiftに溜められる所に特化したServiceです
Pros
- 生ログがS3に溜まる
- Log Updateが最短1分毎
Cons
- 有料 (
$0.035/1GB
とデータ量課金、1万台で1台辺り100 event/day、1KB/eventとすると、$0.035/day) - Dashboardの機能はほぼ無い, Query機能も無し
- Sessionの開始/終了の判定が無く、必要なら自前で実装する必要が有る
- Android SDK側の機能は余り期待するな