При использовании 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])
перед каждым звонком.
Есть взлом, если вы хотите показать / добавить тег в релизе 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. Для получения полезной информации вы можете посмотреть здесь.