При использовании Timber тег пуст

Когда DebugTree логи, я вижу имя класса, однако, когда я создаю пользовательское дерево, тег null, Вот как выглядит мое пользовательское дерево:

public class CrashlyticsTree extends Timber.Tree {
private static final String CRASHLYTICS_KEY_PRIORITY = "priority";
private static final String CRASHLYTICS_KEY_TAG = "tag";
private static final String CRASHLYTICS_KEY_MESSAGE = "message";

@Override
protected boolean isLoggable(int priority) {
    if (priority == Log.VERBOSE || priority == Log.DEBUG || priority == Log.INFO) {
        return false;
    }

    // only log WARN(Timber.w), ERROR(Timber.e), or WTF(Timber.wtf)
    return true;
}

@Override
protected void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable t) {
    if(User.CurrentUser.isLoggedIn()){
        Crashlytics.setUserIdentifier(Long.toString(User.CurrentUser.getUserId()));
    }

    Crashlytics.setInt(CRASHLYTICS_KEY_PRIORITY, priority);
    Crashlytics.setString(CRASHLYTICS_KEY_TAG, tag);
    Crashlytics.setString(CRASHLYTICS_KEY_MESSAGE, message);

    if (t == null) {
        Crashlytics.logException(new Exception(message));
    } else {
        if(!TextUtils.isEmpty(message)){
            Crashlytics.log(priority, tag, message);
        }
        Crashlytics.logException(t);
    }
}
}

Однако даже из DebugTree генерируемый тег BaseActivity потому что это исходит от BaseActivity Однако мне было интересно, если бы я мог получить имя класса, который расширяет BaseActivity

3 ответа

По словам Джейка Уортона:

tag является нулевым, если вы не позвоните tag(String) на сайте журнала или расширить с DebugTree (что вы не должны делать для ведения журнала производства).

Поэтому вам нужно добавить Timber.tag([class name]) перед каждым звонком.

См. https://github.com/JakeWharton/timber/issues/122

Есть взлом, если вы хотите показать / добавить тег в релизе apk. Вместо того, чтобы использовать Timber.Tree() использование Timber.DebugTree() что позволит вам показывать тег в каждом журнале, как показано ниже:

class ReleaseTree : Timber.DebugTree() {

    override fun log(priority: Int, tag: String?, message: String, throwable: Throwable?) {
        // Don't log VERBOSE and DEBUG
        if (priority == Log.VERBOSE || priority == Log.DEBUG) {
            return
        }

        Log.println(priority, "Test->$tag", message)

    }
}

Таким образом, вы также можете добавить свой пользовательский тег в качестве префикса для каждого журнала.

Я сделал что-то вроде этого, чтобы избавиться от проблемы:

          public static class ReleaseTree extends Timber.Tree {

    private static final int MAX_LOG_LENGTH = 4000;
    private static final int MAX_TAG_LENGTH = 23;
    private static final int CALL_STACK_INDEX = 6;
    private static final Pattern ANONYMOUS_CLASS = Pattern.compile("(\\$\\d+)+$");

    @SuppressLint("LogNotTimber")
    @Override
    protected void log(int priority, @Nullable String tag, @NotNull String message, @Nullable Throwable t) {
        if (priority != Log.ERROR) {
            return;
        }

        String newTag = getTag(tag);
        if (message.length() < MAX_LOG_LENGTH) {
            Log.println(priority, newTag, message);
            return;
        }

        // Split by line, then ensure each line can fit into Log's maximum length.
        for (int i = 0, length = message.length(); i < length; i++) {
            int newline = message.indexOf('\n', i);
            newline = newline != -1 ? newline : length;
            do {
                int end = Math.min(newline, i + MAX_LOG_LENGTH);
                String part = message.substring(i, end);
                Log.println(priority, newTag, part);
                i = end;
            } while (i < newline);
        }
    }

    private String getTag(String tag) {
        if (tag != null) {
            return tag;
        }

        // DO NOT switch this to Thread.getCurrentThread().getStackTrace(). The test will pass
        // because Robolectric runs them on the JVM but on Android the elements are different.
        StackTraceElement[] stackTrace = new Throwable().getStackTrace();
        if (stackTrace.length <= CALL_STACK_INDEX) {
            throw new IllegalStateException(
                    "Synthetic stacktrace didn't have enough elements: are you using proguard?");
        }
        return createStackElementTag(stackTrace[CALL_STACK_INDEX]);
    }

    @Nullable
    protected String createStackElementTag(@NotNull StackTraceElement element) {
        String tag = element.getClassName();
        Matcher m = ANONYMOUS_CLASS.matcher(tag);
        if (m.find()) {
            tag = m.replaceAll("");
        }
        tag = tag.substring(tag.lastIndexOf('.') + 1);
        // Tag length limit was removed in API 24.
        if (tag.length() <= MAX_TAG_LENGTH || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return tag;
        }
        return tag.substring(0, MAX_TAG_LENGTH);
    }
}

Это почти похоже на реализацию DebugTree , за исключением того, что он регистрирует только ошибки, и, поскольку частота ошибок должна быть низкой, у нас не слишком много накладных расходов; P

В этом случае мы не использовали отражение, чтобы найти имя тега, а умело использовали экземпляр Throwable. Для получения полезной информации вы можете посмотреть здесь.

Другие вопросы по тегам