이클립스나 안드로이드 스튜디오로 진행되는 안드로이드 개발에서 실제 로그 메시지를 어떻게 뿌리고 있는 지에 대한 내부 메커니즘도 알겸 IDE 툴 없이 진행해보기로 합니다.
Log는 LogCat을 사용해서 출력메시지를 표출 할 수 있는 로깅 클래스로 알고 있습니다.
일반적으로 로깅메시지를 사용하기 위해서 다음과 같은 API가 필요합니다.
메서드 이름이 직관적이라, 그냥 보면 이게 뭐다 정도 알 수 있도록 구성 되어 있는 API 메서드로 보입니다.
v(String, String) (verbose)
d(String, String) (debug)
i(String, String) (information)
w(String, String) (warning)
e(String, String) (error)
다음 처럼 TAG 명을 "MyActivity" 로 주었을 경우에
Log.i("MyActivity", "MyClass.getView() — get item number " + position);
위의 코드에 대한 LogCat의 출력으로 찍히는 내용은 다음과 같을 것입니다.
I/MyActivity( 1557): MyClass.getView() — get item number 1
LogCat 사용하기
DDMS 내, ADB 쉘 그리고 안드로이드 스튜디오의 디거깅 창에서 LogCat 메시지를 확인 할 수 있을 것입니다.
DDMS 상에서 LogCat을 사용하기 위한 더 많은 정보는
다음 Using DDMS 문서를 참고하시면 됩니다.
- 쉘을 통한 구동 방법
ADB 쉘을 통해서 LogCat을 구동하기 위해서는 다음 같이 사용 하면 됩니다.
[adb] logcat [<option>] ... [<filter-spec>] ...
굳이 예를 든다면, 위의 MyClass 는 다음과 같이 logcat 메시지를 구성 할 수 있습니다.
adb logcat MyClass:* *:S
다음 테이블은 logcat의 커맨드라인 옵션들입니다.
-c Clears (flushes) the entire log and exits.
-d Dumps the log to the screen and exits.
-f <filename> Writes log message output to <filename>. The default is stdout.
-g Prints the size of the specified log buffer and exits.
-n <count> Sets the maximum number of rotated logs to <count>.
The default value is 4. Requires the -r option.
-r <kbytes> Rotates the log file every <kbytes> of output.
The default value is 16. Requires the -f option.
-s Sets the default filter spec to silent.
-v <format> Sets the output format for log messages.
The default is brief format. For a list of supported formats,
see Controlling Log Output Format.
로그 출력 필터링하기
모든 안드로이드 로그 메시지는 tag를 가지고 있으며 그에 해당하는 우선권을 가지게 됩니다.
로그 메시지의 tag는 메시지가 온 시스템 컴포넌트를 가리키는 짧은 문자열이다.
(예를 들어 "View"는 뷰 시스템)
우선권은 하위 우선권 부터 상위 우선권 까지 다음 문자 값 중 하나가 될 수 있습니다.
V — Verbose (가장 낮은 우선권)
D — Debug
I — Info
W — Warning
E — Error
F — Fatal
S — Silent (아무것도 출력되지 않는 가장 상위 우선권)
예를 들면, 이런 느낌?
adb logcat MyClass:V *:S
adb logcat MyClass:I *:S
adb logcat MyClass:W *:S
adb logcat MyClass:E *:S
adb logcat MyClass:F *:S
LogCat을 사용해서 다음과 같은 조합으로 사용이 가능 합니다.
<priority>/<tag>
▶다음 예제는 우선순위가 "I"이고 tag가 "ActivityManager"를 출력하는 예제입니다.
I/ActivityManager( 585): Starting activity: Intent { action=android.intent.action...}
로그 출력 값을 읽을 수 있는 수준으로 만들기 위해서는 필터표현식을 사용해야만 합니다.
(filter expression)
필터표현식은 다른 특정 tag에 대한 로그를 표출하지 않고 실제로 필요한 부분만 로그를 출력 할 수 있도록 시스템과 tag 우선권을 사용하게 해 주도록 구성 되어 있습니다.
필터표현식의 형식:
tag:priority....
tag를 출력하기 위한 최소한의 레벨이 우선 순위가 됩니다.
단일 필터 표현식을 사용 할 수도 있으며 스페이스로 분리해서 여러개의 필터 표현식을 사용 할 수도 있습니다.
▶다음 예제는 "info" 우선순위 이상을 가진 tag "ActivityManager"와 "Debug" 우선순위 이상을 가진 tag "MyApp" 이외의 모든 로그메시지를 출력하지 않도록 하는 필터 표현식을 구성 할 수도 있습니다.
adb logcat ActivityManager:I MyApp:D *:S
위 표현식에서 마지막 부분인 *:S 는 모든 tag의 우선순위를 "silent"로 만들어서 "View"와 "MyApp" 의 로그 메시지만 출력되도록 만들어 줍니다.
▶다음 필터표현식은 모든 tag에 대한 우선 순위 "warning" 이상의 메시지를 출력하는 예제이다.
adb logcat *:W
개발 장비에서(원격 adb shell을 구동을 통해) LogCat을 구동하려 한다면
기본 필터 표현식을 다음 환경 변수 ANDROID_LOG_TAGS 에 값을 설정하여 줄 수도 있습니다.
export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S"
★ adb shell logcat으로 구동하였다면 위의 환경 변수가 설정 되지 않는다는 것을 명심하자.
Log 출력 형식 조절하기
로그 메시지는 tag와 우선순위 외의 몇몇의 메타 필드를 포함합니다.
특정 메타 필드를 표출하기 위해서 메시지의 출력형식을 조절할 수 있습니다.
이렇게 하기 위해서는 -v 옵션을 사용하며 다음 중 하나의 출력 형식을 사용하여야 하여야 합니다.
brief — 메시지를 출력하기위한 해당 프로세스의 priority/tag와 PID를 표출한다. (디폴트 형식).
process — PID 만 표출한다.
tag — priority/tag 만 표출한다.
raw — 다른 메타 필드 없이 raw 로그 메시지를 표출한다.
time — 메시지를 출력하려는 프로세스의 날짜와 호출 날짜, priority/tag, 그리고 PID를 출력한다.
threadtime — 메시지를 출력하려는 프로세스의 날짜와 호출 날짜, priority/tag, PID
그리고 TID를 출력한다.
long — 빈 라인과 함께 따로따로 메시지를 모든 메타 필드와 함께 출력한다.
형식:
adb] logcat [-v <format>]
예) thread 출력 형식으로 로그 메시지를 생성하기 위한 예는 다음과 같습니다.
adb logcat -v thread
대안: Log Buffer들을 사용해서 보기
로그 메시지를 위해서 안드로이드 로깅 시스템은 다중 원형 버퍼를 가지고 있다. 그리고 모든 로그 메시지들이 이 디폴트 원버퍼에 표출 되지 않습니다. 대신, 추가 로그 메시지를 보기 위해서는 logcat 명령어를 -b 옵션을 사용해서 구동하여 모든 대안 원형버퍼에서 요청 뷰를 볼 수가 있다.
다음이 이런 대안 버퍼들에 대한 view입니다.
radio — View the buffer that contains radio/telephony related messages.
events — View the buffer containing events-related messages.
main — View the main log buffer (default)
사용법:
[adb] logcat [-b <buffer>]
라디오와 전화 메시지를 가진 로그버퍼를 보는 법에 대한 예제는 다음과 같습니다.
adb logcat -b radio
stdout와 stderr 보기
기본적으로 안드로이드 시스템은 stdout와 stderr (System.out와 System.err) 출력을 /dev/null로 보내게 됩니다.
Dalvik VM이 프로세싱 되는 동안 이 출력의 복사본을 로그파일에다 쓰기를 할 수 있다.
이 경우에는 시스템은 I 우선권을 가진 stdout와 stderr tag를 사용해서 메시지를 로그에다 쓸 수 있는데,
이런 로그를 보기 위해서는 구동 에뮬레이터/기기 인스턴스를 정지하고 setprop 쉘 커맨드를 사용해서 출력의 리다이렉션을 enable 해야만 합니다.
그렇게 하기 위한 방법은 아래 처럼 하게 됩니다:
▶ $ adb shell stop
▶ $ adb shell setprop log.redirect-stdio true
▶ $ adb shell start
에뮬레이터/기기 인스턴스를 죽이기 전까지 시스템은 계속적으로 이런 방식으로 동작하게 되기 때문에. 이런 방식으로 디버깅을 사용하기 위해서는 기기 상에 /data/local.prop 파일에 해당 엔트리를 추가해야 하는 부담이 있습니다.
웹 앱 디버깅하기
console JavaScript API들을 사용해서 자바스크립트를 LogCat으로 출력하여 디버깅 할 수 있도록 안드로이드는 개발 중인 웹애플리케이션에 제공 합니다.
해당 정보는 다음 문서를 참고 하십시오.
실제 소스코드 상에서 다음과 같이 코딩해서 추가하게 되면,
private final static String TAG = "LocationClass";
혹은 다음과 같이 코드를 구성해도 됩니다.
private final static String TAG = LocationClass.class.getSimpleName()
그런 다음 해당 메시지에 대한 디버깅은 다음과 같이 되겠죠?
......
etc.extension.util.LogUtil.debug(TAG,"");
위의 메서드는 내부적으로 log.d를 호출 하게 됩니다.
우리는 위에서 이미 TAG를 만들어 놓았으므로 LogCat에서는 그 이름으로 디버깅하도록 다음과 같이 명령을 전달하면 되는 것입니다.
adb logcat GisMainActivity:D LocationClass:D Http:D GisUtil:D *:S
위의 내용은 다음과 같이 간단히 요약 정리 할 수 있습니다.
'GisMainActivity' , 'LocationClass' 및 'Http' 라는 TAG 이름으로 되어 있는 클래스들이 모두 Debug 이상의 메시지를 출력해라
물론 여기서는 패키지를 명시하시 않아도 됩니다. 왜냐구요? Tag 를 달았으니까...
이상.
'모바일프로그래밍 > 안드로이드' 카테고리의 다른 글
안드로이드 이해하기 - 첫 걸음 떼기 (0) | 2023.01.02 |
---|---|
Android Notification 이란 (0) | 2022.12.17 |
안드로이드 기기 디버깅을 위한 크롬브라우저 설정 (0) | 2022.09.18 |
안드로이드 APK 분석 참고 문서 (0) | 2022.09.15 |
내 멋대로 안드로이드 - 8 (0) | 2022.07.22 |