안드로이드 개발 시 커스텀 로그 남기기

주의

이 문건은 과거 Hexo 블로그 (2017-11-25) 에서 이동된 문서입니다.

시간이 지남에 따라 최신 기술과 다를 수 있으니 주의 바랍니다.


안드로이드 로그

안드로이드 개발자라면 개발에서 결과 또는 테스트를 위해 로그 기능을 사용할 것입니다.

하지만 이 로그는 배포버전이 아닌 개발버전에서만 나오게끔 하는 것이 제일 베스트한 선택일 것입니다.

또한 기본적으로 사용하는 로그의 경우 아래와 같이 사용하게 됩니다.

Log.d("Log tag", "Log message...");

Log 클래스 뒤에 메서드는 로그 레벨로써 아래와 같이 분류됩니다.


로그 레벨 설명 우선순위
e(Error) 오류가 났을 때 사용 매우 높음
w(Warn) 오류는 아니지만 문제가 발생할 가능성이 있을 때 사용 높음
i(Info) 일반적으로 사용 중간
d(Debug) 개발 중 확인이 필요할 경우 사용 낮음
v(Verbose) 자세한 정보 등을 표시할 때 사용 매우 낮음

로그에 대해 좀 더 상세한 설명은 공식문서를 참고하시길


이제 기본적인 내용은 여기까지하고, 포스트에서 원하는 목표는 다음과 같습니다.

1. 개발버전에서만 동작하는 기능 만들기
2. 나만의 로그 만들기

그럼 하나씩 풀어나가보도록 하겠습니다.


1. 개발버전에서만 동작하는 기능 만들기

먼저 현재 어플리케이션이 구동되는 상태가 개발버전인지 아니면 배포버전인지 알아야 합니다.

저의 경우 아래와 같이 전역 메서드를 하나 생성하고, 호출하는 방식으로 구현하였습니다.

public class SomeCls {

	/**
     * 현재 디버그 상태(개발모드) 체크를 하는 메서드
     * @param context
     * @return true-개발모드 / false-릴리즈 모드
     */
    public static boolean isDebuggable(Context context) {
        boolean debuggable = false;
        PackageManager pm = context.getPackageManager();
        try{
            ApplicationInfo appinfo = pm.getApplicationInfo(context.getPackageName(), 0);
            debuggable = (0 != (appinfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
        }catch (PackageManager.NameNotFoundException e) {
            Log.d("MyLog", makeClazzAndMethodName(context.getClass(), "isDebuggable") + " error msg = " + e.getMessage());
        }
        return debuggable;
    }

}

위 메서드를 호출할 경우 boolean을 반환하는데 true일 경우 개발모드(Debug), false일 경우 배포모드입니다.

일단 개발버전을 체크하는 메서드는 준비되었습니다.

그럼 다음과 같이 로그를 개발버전에서만 보이게끔 처리할 수 있을 것입니다.

	if(SomeCls.isDebuggable(context)) {
		Log.d("DEV-LOG", "Hello~ World Log");
	}

그런데 매번 이렇게 로그를 작성하려면 뭔가 번거롭습니다.

특히 저 if(SomeCls.isDebuggable(context)) 이 부분이 몹시 거슬립니다.

또한 Context 객체를 계속 전달을 받아야 하는 부분도 번거롭네요.

이것을 해결하기 위해선 다양한 방법이 있습니다.

  1. 어플리케이션에서 제일 먼저 진입하는 Activity에서 전역(정적) 변수를 선언하고, 이 전역(정적) 변수를 통해서 체크하는 방법.
  2. 전역에서 사용할 클래스를 하나 생성 후, 전역 변수를 하나 만들고, 어플리케이션에서 제일 먼저 진입하는 Activity에서 앞서 설명한 전역 변수에 값을 저장 후 체크하는 방법.

말로 쓰면 어려우니 간단한 코드로 설명을 대신합니다.

///제일 처음 진입하는 Activity == MainActivity
///전역 클래스 == CommUtil   전역 변수 == boolean ISDEBUG

///Type 1 (MainActivity 안)

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	ISDEBUG = isDebuggable(getApplicationContext());
}


///Type 2 (MainActivity 안)

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	CommUtil.ISDEBUG = isDebuggable(getApplicationContext());
}

이제 개발버전에서만 동작하는 기능을 구현하였습니다.

하지만 로그를 작성할 때마다 if문을 계속 같이 쓰면 번거롭습니다.

또한 항상 로그 태그와 함께 메세지를 넣는 부분도 거슬립니다. (물론 경우에 따라서 로그 태그를 통해 분기하기도 하지만…)

그렇다면 나만의 로그 클래스를 만들고 그 안에서 위 작업을 한꺼번에 처리한다면?


2. 나만의 로그 만들기

이제 나만의 로그 클래스를 만들어 보도록 하겠습니다.

프로젝트에서 적당한 로그 클래스를 만들어봅니다.

먼저 코드를 참고하기길..

public class MyLog {
	private static final String TAG = "MyAppLog";

	public static final void i(String msg) { if (ISDEBUG) { Log.i(TAG, makeLogBody(msg)); } }
	public static final void v(String msg) { if (ISDEBUG) { Log.v(TAG, makeLogBody(msg)); } }
	public static final void w(String msg) { if (ISDEBUG) { Log.w(TAG, makeLogBody(msg)); } }
	public static final void d(String msg) { if (ISDEBUG) { Log.d(TAG, makeLogBody(msg)); } }
	public static final void e(String msg) { if (ISDEBUG) { Log.e(TAG, makeLogBody(msg)); } }

	/**
     * 로그에 띄울 메세지를 만들어주는 메서드
     * @param logMsg
     * @return
     */
    private static String makeLogBody(String logMsg) {
        StackTraceElement ste = Thread.currentThread().getStackTrace()[4];
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        sb.append(ste.getFileName().replace(".java", ""));
        sb.append("::");
        sb.append(ste.getMethodName());
        sb.append("] ");
        sb.append(logMsg);
        return sb.toString();
    }
}

일단 사용방법은 MyLog. 으로 사용하면 됩니다.

내부에서 사용된 ISDEBUG의 경우 위에서 설명한 방법을 참고합니다.

makeLogBody 메서드의 경우 로그의 보여줄 메세지를 만들어주는 메서드로써 보여주고 싶은 내용은 개발자의 입맛에 맞게끔 바꾸면 됩니다.


결론

자신의 입맛에 맞는 커스텀 로그를 만드는 방법을 간단히 알아보았습니다.

오픈소스에서도 다양한 안드로이드용 로그 라이브러리가 있습니다.

전에 찾아본 것으론 Logger 라는 것도 있었습니다.


Written by@MHLab
로또는 흑우집합소 🎲
와인관리, 시음노트, 셀러관리는 마와셀 🥂

🫥 My Service|  📜 Contact|  💻 GitHub