ログ管理でウキウキandroid life (log management in android)

Post on 10-Jul-2015

2.104 Views

Category:

Software

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

ログ管理でウキウキAndroid Life

2014/11/20 Mercari Inc. 今井智章

自己紹介• 株式会社メルカリ Android エンジニア(2014.3~)

!

!

!

!

!

!

• 以前はSIerでインフラ系DBエンジニア(たまにjava開発)2

twitter: tomoaki_imai github: tomoima525 qiita: tomoima525

フリマアプリの機能開発、USアプリ開発

Agenda

• ウキウキするエラー系ログ管理のお話

• ウキウキする分析系ログ管理のお話

3

エラーログとは

ユーザーの声にならない 叫び

ユーザーの声として上がるのはほんの一部です

エラーログ、見ましょう バグ、駆逐しましょう

メルカリでのエラー監視

• Google Developer Console

• Crashlytics

• 自前でのリアルタイムエラーレポート

8

Google Developer Console• apkをGoogle playに上げる時に時のアレ

• アプリがクラッシュし、ユーザーがエラーレポート送付してくれた内容が見られる

- なので大体氷山の一角

• Crashlyticsで拾えないネイティブクラッシュが確認できる

9

Crashlytics

• 言わずと知れた有名エラーレポートサービス

• 導入が超簡単。レポートも詳細。

• テスト配信機能も有り

• 最近はアカウント作成待ちの行列ができてる10

使い方• 一番最初に起動するActivityで呼ぶだけ

!

!

• クラッシュ時の情報を添付することもできる

11

@Override public void onCreate(Bundle savedInstanceState) { com.crashlytics.android.Crashlytics.start(this); }

com.crashlytics.android.Crashlytics.setString( "last_activity", this.getClass().getName());

使い方

!

• メルカリではdev,stg,productでパッケージ名を分け、それぞれでログ監視

• テスト、QAレベルでエラーログを拾う12

自前エラーレポート• エラー用Apiでクラッシュ時に送信

• より詳細に状況を把握し、バグ解消に活かす

• 以下の3点が実装のポイント

13

①予期せずエラーが起きてもレポートを飛ばす仕組み

②既知のバグの発生条件を調査できる仕組み

③レポートを貯めて送る仕組み

仕組み①予期せずエラーが起きてもレポートを飛ばす仕組み

14

public class ThisApplication extends Application implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, final Throwable ex) { new Thread() { public void run() { ByteArrayOutputStream b = new ByteArrayOutputStream(); ex.printStackTrace(new PrintStream(b)); String errMessage = b.toString(); gotoErrorActivityAndReport(errMessage); //エラーレポートをAPIに送る System.exit(1); }; }.start(); }

Applicationクラス内でThread.UncaughtExceptionHandlerを実装

仕組み②既知のバグの発生条件を調査できる仕組み

15

try { return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); } catch (OutOfMemoryError ooe) { postErrorReport(getCurrentActivity().getClass().getName() , options.inSampleSize , options.outWidth , reqWidth);     //画像処理系で画像サイズ情報を送信 }

すでにErrorが発生すると判明している部分で、try/catchし、 catch内で調査に必要な情報を送る

public void sendErrorReportInternal(final JSONObject errReport) { String errMessage = JSONUtil.getString(errReport, S.message); if (errMessage != null) { Api.process(errReport, new responseListener<JSONObject>() { @Override public void onResponse(JSONObject response) {} @Override public void onErrorResponse(JSONObject response) { ErrorStore.addErrReport(errReport); //プリファレンスに保存 } //以下略

仕組み③レポートを貯めて送る仕組み

16

レポートをプリファレンスに保存し、レポート送信前にクラッシュ したり通信できなくても、次回起動時に送付できるようにする

public void onResume() { sendOldErrorReports(); //以前のレポートがあった場合は送信 }

まとめ• Crashlyticsで届かないかゆいところに自前エラーレポートを組み合わせるとバグ駆逐が捗る

17

Google Analytics Crashlytics 自前

ログのわかりやすさ △ ◯ ◎

カスタマイズ性 ☓ △ ◎

導入容易性 default ◯ △

ウキウキしましたか?

続いて、分析ログの話

What is 分析ログ?• インストール率, DAU, 売上, A/B testing etc. を分析するためのログ

• 用途によって様々なサービスがある

20

分析ログ(サービス)の問題点

• それぞれの分析サービスのApiに標準性がない

- 似たようなトラッキングコードをひたすら書かされる

- その割にApiごとに癖があって実装に困る

- 新しいライブラリを追加する度に導入の調査が必要になる

21

そうだ、Segment 使おう

Segment• 複数の分析サービスを統合できる

• シンプルなAPIで導入が簡単

• けどかなり詳細に分析データを送信できる!

23

Segment• SegmentのApiで多くの分析サービスをカバー

• ユーザーはコンソールから分析サービスを選ぶだけ

24

実装例• 事前準備

- アカウントの用意

- https://segment.com/

- プロジェクトの作成

- 組織単位でproject作成が可能

- API keyを確認

25

こちらにまとめました↓http://qiita.com/tomoima525/items/bab086d341b686b9f8a1

実装例• gradleのdependencies追加(Android Studio)

!

!

!

!

• AndroidManifest.xmlへの設定

26

dependencies { compile('com.segment.analytics.android:core:+@aar') { transitive = true } //必要なライブラリのみ追加 compile 'com.google.android.gms:play-services:+' compile ‘com.mixpanel.android:mixpanel-android:+@aar' }

<uses-permission android:name=“android.permission.INTERNET”/>   //必須 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.READ_LOGS"/> <uses-permission android:name="android.permission.GET_TASKS"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Eclipse向けにjarファイルもある(ただしバージョンは古い)

実装例• res/values/analytics.xmlにAPI keyを設定

27

<resources> <string name="analytics_write_key">YOUR_WRITE_KEY</string> <string name="analytics_logging">true</string> <integer name="analytics_queue_size">20</integer> </resources>

analytics_write_key:    コンソールで確認したApi key analytics_logging:    logに送信データが出力    うまく確認できなかった。iOSでは見られる? analytics_queue_size:    一度のキューで送信するイベントの数    キューがたまらなくても一定時間で送信されている様子

代表的なトラッキングメソッド• identify

Analytics.with(context).identify(new Traits().putName(“Moge Hoge")); Analytics.with(context).identify( new Traits().putEmail(moge@hoge.com"));

Analytics.with(context).identify(user_id);

アプリユーザーのIDを設定する

複数のTraits(特徴)を設定することも可能

Traitsはage, gender等多数あり、分析サービスに応じて設定可能

https://segment.com/docs/api/tracking/identify/#special-traits

代表的なトラッキングメソッド• Alias

会員登録前後のIDを紐つけ、会員登録前のイベントを関連付けする

※Segmentのエンジニア曰く統合がまだ十分でないらしく、 今後も変わる可能性あり

Analytics.with(context).alias(uuid, new_id); //会員登録前のIDがない場合はSegment内のanonymousIDが紐付けられる

Mixpanel、Flurryといった分析サービスで利用

代表的なトラッキングメソッド• Track

あらゆるイベントにプロパティ、トラック名をつけてトラックする

プロパティは任意のキーを設定できる

Properties properties = new Properties() .putValue("price", price) .putValue("category", CategoryId); //オブジェクト型を設定できる Analytics.with(context).track(trackName, properties);

デバッガー• コンソールデバッガーで値を確認できる

{ "messageId": "09361829-c11c-451d-83d0-d1e2e9fc9063", "type": "track", "anonymousId": "d6c327e4-76c3-418c-907e-4b0eba89ec40", // 中略 "timestamp": "2014-11-19T11:34:54.000Z", "event": "Eat Curry", "properties": { "price": 1200, "category": "Indian", "condition": "good", }, }

値はjsonでも取得可能

分析• コンソールから分析サービスを選ぶ

それぞれの分析サービスに必要なIDやkeyを設定するだけ

分析ツールの追加があってもライブラリ、ソースコードの追加は(ほとんど)不要

スッキリ

ちょっと注意

• 成長中のサービスなので、開発がさかん

• Documentの記述が食い違っている所もある

• ソースコードが食い違っている所がある(!)

• オープンソースなのでおかしかったら迷わずPR

35

まとめ

• エラーログ管理はカスタマイズするとバグ駆逐が捗ってウキウキ

• 分析ログはSegment使うと楽ちん、スッキリでウキウキ

36

メルカリではAndroid/iOSエンジニア募集中!

top related