LoginSignup
4
2

More than 1 year has passed since last update.

Timber×Crashlytics でログをクラッシュレポート送信(Crashlytics編)

Posted at

はじめに

タイトルスライド.png

日が空いてしまいましたが、後編です。

前編は「Timber×Crashlytics でログをクラッシュレポート送信(Timber編)」です。

前編では Timber を用いて、デバッグビルドとリリースビルドで、ログ出力を切り替える基盤を作成しました。
後編では、前編で作成した ReleaseTree クラスを用います。
そして、リリースビルド時は、「コンソールへログ出力しない」かつ「クラッシュ時にレポートを送信する」機能を組み込んでいきます。

Firebase Crashlytics

Firebase Crashlytics は、モバイルアプリで発生したクラッシュを検知して、クラッシュが発生するまでのログを送信するクラッシュレポートツールです。
クラッシュレポートはFirebaseコンソールに集約され、クラッシュの分析や調査に役立ちます。

導入方法

前提

  • Googleアカウントの作成

Firebase Crashlytics のセットアップ

セットアップに関しては、公式ドキュメントがかなり丁寧でわかりやすいので、本稿では省略します。
※ Firebaseの導入と、Firebase Crashlyticsの導入に分かれている点に注意してください。

Firebase

公式 - Android プロジェクトに Firebase を追加する

Firebase Crashlytics

公式 - Firebase Crashlytics を使ってみる

プログラム変更

上記の公式手順をもとに、前編のTimber編 からの変更点を記載します。

build.gradle(:project)

※ プロジェクト直下

build.gradle
buildscript {
    ....
+    dependencies {
+        classpath 'com.google.gms:google-services:4.3.10'
+        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
+    }
}
....

build.gradle(:app)

※ app直下

build.gradle
....
apply plugin: 'com.android.application'
+ apply plugin: 'com.google.gms.google-services'
....
dependencies {
    implementation 'com.jakewharton.timber:timber:4.7.1'
+    implementation platform('com.google.firebase:firebase-bom:29.2.0')
+    implementation 'com.google.firebase:firebase-analytics'
+    implementation 'com.google.firebase:firebase-crashlytics'
}

MainActivity.java

MainActivity.java
public class MainActivity extends AppCompatActivity {

-   private final String TAG = MainActivity.class.getName() + "_TAG";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

     // 後編では不要なので消しておきます
-       Log.v(TAG, "Log VERBOSE");
-       Log.d(TAG, "Log DEBUG");
-       Log.i(TAG, "Log INFO");
-       Log.w(TAG, "Log WARN");
-       Log.e(TAG, "Log ERROR");
-       Log.println(Log.ASSERT, TAG, "Log ASSERT");
-       Timber.v("Timber VERBOSE");
-       Timber.d("Timber DEBUG");
-       Timber.i("Timber INFO");
-       Timber.w("Timber WARN");
-       Timber.e("Timber ERROR");
-       Timber.wtf("Timber ASSERT");

+       Button crashButton = new Button(this);
+       crashButton.setText("Test Crash");
+       crashButton.setOnClickListener(new View.OnClickListener() {
+           public void onClick(View view) {
+               throw new RuntimeException("Test Crash"); // Force a crash
+           }
+       });

+       addContentView(crashButton, new ViewGroup.LayoutParams(
+               ViewGroup.LayoutParams.MATCH_PARENT,
+               ViewGroup.LayoutParams.WRAP_CONTENT));

    }
}

クラッシュレポート

まずは公式ドキュメントに従って、クラッシュを強制的に起こし、クラッシュレポートを確認します。
※ Test Crash ボタンをタップすると、アプリが落ち、クラッシュレポートが送信されます。

Timber × Firebase Crashlytics

導入が完了したところで、前編のTimber編 で作成した ReleaseTree へ、Firebase Crashlytics を組み込んでいきます!

プログラム変更

MyApplication.java

MyApplication.java

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if (BuildConfig.DEBUG) {
            Timber.plant(new Timber.DebugTree());
+           // デバッグビルドの場合はクラッシュレポートを送信しないように設定
+           FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(false);
        } else {
            Timber.plant(new ReleaseTree());
        }
    }
}

ポイント

  • ビルド方法によって、Timberの設定を切り替えます
  • FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(false) の一文を書いておくことで、クラッシュレポートを送信しないように設定できます
    (この設定をしないと、開発中に実行時例外が出るたびにクラッシュレポートが送信されてしまいます)

ReleaseTree.java

ReleaseTree.java
public class ReleaseTree extends Timber.Tree {

    @Override
    protected void log(int priority, @Nullable String tag, @NotNull String message, @Nullable Throwable t) {
        switch (priority) {
-           case Log.INFO:
-           case Log.WARN:
-           case Log.ERROR:
-           case Log.ASSERT:
-               // Crashlytics ログ出力処理を記述(Crashlytics編で記載)
-               break;
+           case Log.INFO  : recordLog("I", message); break;
+           case Log.WARN  : recordLog("W", message); break;
+           case Log.ERROR : recordLog("E", message); break;
+           case Log.ASSERT: recordLog("A", message); break;
            default:
                /*
                下記の優先度は出力なし
                ・Log.VERBOSE
                ・Log.DEBUG
                 */
                break;
        }
    }

+    private void recordLog(String prefix, String message) {
+        FirebaseCrashlytics.getInstance().log(String.format("%s: %s", prefix, message));
+    }
}

ポイント

  • どの優先度かを識別したいので、プレフィックスをつける関数を呼び出します
  • recordLog 関数内の FirebaseCrashlytics.getInstance().log() を呼び出すことで、クラッシュレポートのログとして記録されます

MainActivity.java

MainActivity.java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
+       Timber.i("メイン画面初期処理開始");
+       Timber.d("デバッグログはコンソール出力のみ!");

        Button crashButton = new Button(this);
        crashButton.setText("Test Crash");
        crashButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
+               Timber.e("Test Crash ボタンが押されました!");
                throw new RuntimeException("Test Crash"); // Force a crash
            }
        });

        addContentView(crashButton, new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));

+       Timber.i("メイン画面初期処理終了");
    }
}

ポイント

  • 初期処理の開始~終了のタイミングでINFOログ、 DEBUGログを出力します
  • ボタンを押されたときにERRORログを出力します

動作確認

それぞれのビルド方法でクラッシュを発生させます。

デバッグビルド

コンソール出力

AndroidStudio のコンソールには下記のように出力されます。

I: メイン画面初期処理開始
D: デバッグログはコンソール出力のみ!
I: メイン画面初期処理終了
E: Test Crash ボタンが押されました!

クラッシュレポート

クラッシュレポートは送信されません。

リリースビルド

コンソール出力

実装したログはコンソールに出力されません。

クラッシュレポート

クラッシュレポートが送信されます。
また、「ログ」タブには実装したログが出力されています!
そして ReleaseTree で実装した通り、デバッグログはクラッシュレポートには出力されていません😎

image.png

※ #2 はデフォルトで出力

おわりに

いかがだったでしょうか。
これで、開発中のコンソール上だけで確認したい内容は DEBUG 、開発中とクラッシュレポートどちらでも確認したい内容は INFO 以上という使い分けができますね!

また、Firebase Crashlytics には、より分析しやすくするために下記のような機能もあります。

  • ユーザーIDを設定
  • 任意のKeyValueをログの項目として保持
  • 任意のタイミングでクラッシュレポートを送信

これらを扱うような Util クラスを作成してもよさそうですね。

以上、より良いログ基盤の構築の一助になりましたら幸いです!

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2