2016년 10월 24일 월요일

[안드로이드] 커스텀 Logger 클래스 만들기

배경

개발을 하다보면 여러가지 이유로 로그를 남기게 되는데, 여기저기 남길 로그들을 real 버전에서 다 지우기란 여간 버거운 일이 아니다. 그리고, 추후에 유지보수할 때 다시 로그를 찍는 것도 매우 비효율적이다. 그래서, 디버그 상태일때만 로그를 남길 수 있도록 메서드를 추가했다.
public class MyActivity extends Activity {
private static final String LOG_TAG = "MyActivity";

...
public static void logVerbose(String msg) {
// isDebuggable() 이라는 메서드로 디버그 모드인지 확인(이부분은 앱마다 알아서...)
if (!AppConfig.isDebuggable()) return;
Log.v(LOG_TAG, msg);
}
...
}
안드로이드 공식문서의 컨벤션대로 상수를 이용해 클래스 이름을 TAG로 이용했는데, 문제는... 저 형식에 맞추기 위해서 로그가 필요한 모든 클래스에 TAG와 메서드를 만드는 사태가 벌어졌다.

커스텀 Logger 클래스

모든 클래스의 로그메서드를 걷어내기 위해, Logger 클래스를 하나 선언하고 다음과 같이 static 메서드로 로그 메서드를 추가했다.
public class Logger {
private static final String LOG_TAG = "앱 이름";
private static final String FORMAT = "[%s]: %s";

public static void logVerbose(String msg) {
if (!AppConfig.isDebuggable()) return;
Log.v(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

public static void logDebug(String msg) {
if (!AppConfig.isDebuggable()) return;
Log.d(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

public static void logInfo(String msg) {
if (!AppConfig.isDebuggable()) return;
Log.i(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

public static void logWarn(String msg) {
if (!AppConfig.isDebuggable()) return;
Log.d(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

public static void logError(String msg) {
if (!AppConfig.isDebuggable()) return;
Log.e(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

private static String getCallerInfo() {
StackTraceElement[] elements = new Exception().getStackTrace();
String className = elements[2].getClassName();
return className.substring(className.lastIndexOf(".") + 1, className.length()) + "_" + elements[2].getLineNumber();
}
}
이렇게 추출한 로그 메서드에, 로그를 남기는 클래스이름과 실행라인을 얻어오기 위하여 StackTraceElement 배열을 얻어오는 방법을 이용했다. 이 배열은 다음의 2가지 방법으로 얻어올 수 있다.
  • Thread.currentThread().getStackTrace()
  • new Exception().getStackTrace();
첫번째 방법은 현재 스레드에서의 CallStack을 얻는 것이고, 두번째 방법은 익셉션을 생성해서 익셉션의 CallStack을 얻는 것이다. (2개의 CallStack 순서가 미묘하게 다르니 필요한 경우 테스트해보면 좋다.)
StackTraceElement 객체는 스택에 있는 클래스, 메서드 이름을 불러올 수 있으며, 호출된 라인도 가지고 있다. 필요한 정보를 다 로그에 출력해준다.
Tip : 안드로이드 스튜디오는 클래스 바로가기, 라인 바로가기가 존재한다.(맥 기준으로 설명)
클래스 바로가기 : Editor에서 Shift 두번 입력 후, 팝업이 뜨면 원하는 클래스 이름을 입력한다.
라인 바로가기 : Editor에서 찾고자 하는 클래스를 들어간 후에, cmd + l 입력 후, 팝업이 뜨면 원하는 라인을 입력한다.

댓글 없음:

댓글 쓰기