Sunday, May 17, 2015

CrashlyticsTree for Timber

Timber is an outstanding, yet minimalistic library for logging. By default, you can use its DebugTree for logging to standard output, as you would with android.util.Log. It’s easy, just use if (BuildConfig.DEBUG) { Timber.plant(new Timber.DebugTree()); }. This comes in handy, when your source code is full of debug logs, which you don’t want to use in production builds. In this case, when running a release build, nothing will be logged. On the other hand, if you want to use Acra, or in this case Crashlytics for crash reporting in production builds, just plant a different Tree. It’s fairly easy. You just need to define your reporting Tree. Since I haven’t found any up-to-date Tree definition for Crashlytics logging, I wrote this one (inspired by Jake Wharton’s example). It logs only those logs with priority higher, than debug (because you don’t want to spam your Crashlytics account with irrelevant logs). And why do you need to bother using Crashlytics, when Android provides crash reporting right into developer console? Well, because from my experience, users report just around 1 % of all crashes, so don't rely on their good will to press the report button.

Edited 2015/06/04 - new Crashlytics API calls

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        if (BuildConfig.DEBUG) {
            Timber.plant(new Timber.DebugTree());
        } else {
            Fabric.with(this, new Crashlytics());
            Timber.plant(new CrashlyticsTree());
        }

    }

    private static class CrashlyticsTree extends Timber.Tree {

        @Override
        protected void log(int priority, String tag, String message, Throwable t) {
            if (priority == Log.VERBOSE || priority == Log.DEBUG) {
                return;
            }

            Crashlytics.getInstance().core.log(priority, tag, message);

            if (t != null) {
                Crashlytics.getInstance().core.logException(t);
            }
        }

    }
}

2 comments:

  1. Hmm, I guess tag will be always null in this aproach.

    ReplyDelete
    Replies
    1. You are right. It seems getTag() method should be correctly overriden to get it working.

      Delete