MyTetra Share
Делитесь знаниями!
Логирование в Android приложениях с автоматическим формированием имени места вызова логирующей функции
15.01.2019
18:55
Текстовые метки: android, андроид, разработка, отладка, логирование, лог
Раздел: Компьютер - Программирование - Java - Java в Android

Уверен, что всем разработчикам приложений на платформе Android знаком класс Log, позволяющий логировать различные события. По различным причинам, формат записи логов для каждого проекта может отличаться достаточно сильно — начиная от «AAA», «111111» и «I was here» до более-менее внятных — «Opening HTTP connection to habrahabr.ru». Под катом вы найдете пример функции, которая поможет навести порядок в логах.

Данный топик не претендует на оригинальность и универсальность. И поэтому, если в вашем проекте уже существует некий стандарт логирования событий, то смело проходите мимо — топик скорее ориентирован на начинающих разработчиков.

Как правило, ценность логов начинаешь понимать только когда заказчик матерясь отсылает лог на почту и просит засабмитить фикс через 5 минут. И если лог состоит из сообщений невнятного характера, то как минимум, разбр данного лога займет куда больше времени, чем хотелось бы.


Пытаемся навести порядок

Логи существуют для того, чтобы разработчик мог понять что, где и когда произошло. Найти ответ на вопрос «когда произошло» достаточно просто — в логах Андройд записывает время события. Нахождение ответа на вопрос «что произошло» так же не вызывает больших трудностей, если сообщение в лог было написано со смыслом, например: «Opening file...». Вопрос «где произошло» оказывается наиболее сложным. Если проект большой, то придеться потратить время на нахождение нужного места кода, даже, если лог был написан со смыслом.

Если событие логируется с указанием Throwable (чаще Exception), например, метод public static int d (String tag, String msg, Throwable tr), то в консоле сообщений будет выведен стек, который поможет быстро идентифицировать место логирования. Но использование данного метода без особой необходимости до безобразия перегрузит лог ненужной информацией.

Если же логируется просто текст, то при логировании можно явно указывать место вызова. Например:


Log.v("My Project", "[ImageLoader:loadFile]: Opening file...");


Однако, писать такое каждый раз — дело утомительное и неблагодарное.

Ниже приведен пример класса Log, который делает это автоматически.


public final class Log {


...


public static void v(String msg) {

android.util.Log.v(TAG, getLocation() + msg);

}

private static String getLocation() {

final String className = Log.class.getName();

final StackTraceElement[] traces = Thread.currentThread().getStackTrace();

boolean found = false;


for (int i = 0; i < traces.length; i++) {

StackTraceElement trace = traces[i];


try {

if (found) {

if (!trace.getClassName().startsWith(className)) {

Class<?> clazz = Class.forName(trace.getClassName());

return "[" + getClassName(clazz) + ":" + trace.getMethodName() + ":" + trace.getLineNumber() + "]: ";

}

}

else if (trace.getClassName().startsWith(className)) {

found = true;

continue;

}

}

catch (ClassNotFoundException e) {

}

}


return "[]: ";

}


private static String getClassName(Class<?> clazz) {

if (clazz != null) {

if (!TextUtils.isEmpty(clazz.getSimpleName())) {

return clazz.getSimpleName();

}


return getClassName(clazz.getEnclosingClass());

}


return "";

}

}


Использование класса очень простое:


Log.v("Opening file...");


Результатом логирования данным способом будут примерно следующие строки:


03-28 22:51:23.239: VERBOSE/TestApp(16390): [MainActivity:onResume:124]: Opening file...

03-28 22:51:23.341: VERBOSE/TestApp(16390): [MainActivity:run:198]: Closing file...



Примечание: По понятным причинам, данный способ мало пригоден для приложений «пропущенных» через обфускатор.


Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования