Timber support
Jordi Giménez avatar
Written by Jordi Giménez
Updated over a week ago

A Bugfender tree can be planted on Timber. Here's an adapter class that you can add to your code:

import android.util.Log;

import com.bugfender.sdk.Bugfender;
import com.bugfender.sdk.LogLevel;

import timber.log.Timber;

public class BugfenderTree extends Timber.Tree {
    // note: some people prefer extending DebugTree to get the tag automatically filled in

    @Override protected void log(int priority, String tag, String message, Throwable t) {
        // determine log level
        LogLevel logLevel = LogLevel.Debug;
        switch (priority) {
            case Log.VERBOSE:
                logLevel = LogLevel.Trace;
            case Log.DEBUG:
                logLevel = LogLevel.Debug;
            case Log.INFO:
                logLevel = LogLevel.Info;
            case Log.WARN:
                logLevel = LogLevel.Warning;
            case Log.ERROR:
                logLevel = LogLevel.Error;
            case Log.ASSERT:
                logLevel = LogLevel.Fatal;
        // fill in caller info, skipping Timber's calls
        int lineNumber = -1;
        String method = "";
        String fileName = "";
        StackTraceElement callerInfo = findCaller(new Exception());
        if(callerInfo != null) {
            lineNumber = callerInfo.getLineNumber();
            method = callerInfo.getClassName() + "." + callerInfo.getMethodName();
            fileName = callerInfo.getFileName();
        Bugfender.log(lineNumber, method, fileName, logLevel, tag, message);

    private static StackTraceElement findCaller(Throwable t) {
        StackTraceElement[] stack = t.getStackTrace();
        for (int i = 2; i < stack.length; i++) { // 0th will be the caller of this method, inside this class, 1st will be Timber, 2nd might be Timber or the real caller
            final StackTraceElement stackTraceElement = stack[i];
            if (!stackTraceElement.getClassName().startsWith("timber.log.")) {
                return stackTraceElement;
        return null;

You plant it with:

Timber.plant(new BugfenderTree());

Thanks to @aldoborrero for his initial contribution!

Please note if you're also planting a Timber.DebugTree(), it will print logs to the console simultaneously. This is not a problem, but you may end up with logs written twice! If that happens, make sure:

  • Configure Bugfender to not print logs to the console, by setting the third parameter to false in Bugfender.init(this, "YOUR_APP_KEY_HERE", false). Since Timber is also sending the logs to logcat, you would see them twice.

  • Do not call Bugfender.enableLogcatLogging() when initializing Bugfender. If Bugfender were configured to read logs from logcat, it would read the logs printed by the DebugTree.

Did this answer your question?