logcat 레벨과 태그, 자주 보는 오류 패턴 읽는 법
수만 줄의 로그에서 오류를 찾는 첫 단계는 "어떤 줄이 무슨 뜻인지"를 알아보는 눈입니다. logcat 한 줄은 레벨과 태그, 메시지로 이루어져 있고, 대표적인 문제 유형은 저마다 알아볼 수 있는 "지문"을 남깁니다. 이 글은 그 지문들을 정리한 것입니다. 한 가지 미리 알려 드리면, 레벨이 F라서 더 심각하고 E라서 덜 심각한 것이 아닙니다. 앱이 죽는 크래시가 E 레벨로 기록되는 경우가 오히려 흔합니다.
1. 레벨: 여섯 단계
| 문자 | 이름 | 의미와 쓰임 |
|---|---|---|
V | Verbose | 가장 상세한 개발용 정보. 배포 빌드에서는 대개 꺼져 있음 |
D | Debug | 디버깅용 메시지 |
I | Info | 정상적인 동작 안내(서비스 시작, 연결 성공 등) |
W | Warning | 지금은 넘어가지만 주의가 필요한 상황(재시도, 느린 응답 등) |
E | Error | 동작 실패. 앱 크래시와 ANR 보고도 대부분 여기에 기록됨 |
F | Fatal | 복구 불가능한 치명적 상황. 주로 네이티브 코드(C/C++)의 libc가 기록 |
S(Silent)는 필터에서 "아무것도 보이지 않게"(*:S)할 때만 쓰는 값이라 로그 줄에는 나타나지 않습니다.
이 대시보드는 E와 F를 "결함"으로, W를 "경고"로 집계하고 나머지는 세지 않습니다.
E와 F는 "무언가 실패했다"는 신호일 뿐 사용자에게 영향이 있었다는 보장이 아닙니다. 네트워크 재시도 실패처럼 곧바로 복구되는 E도 수천 줄 쌓일 수 있습니다. 개수보다 종류와 반복 여부를 보세요.
2. 대표 패턴 여섯 가지
2-1. 자바/코틀린 앱 크래시 — FATAL EXCEPTION
E AndroidRuntime: FATAL EXCEPTION: main
E AndroidRuntime: Process: com.example.app, PID: 1234
E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method ...
E AndroidRuntime: at com.example.app.MainActivity.onCreate(MainActivity.java:52)
태그 AndroidRuntime, 메시지 FATAL EXCEPTION이 정석입니다. 바로 아래 줄의 Process:가 죽은 앱이고,
스택트레이스 가장 위쪽의 앱 코드 줄(at com.example...)이 원인 위치입니다. 이 대시보드는 여러 줄에 걸친
스택트레이스를 하나의 결함으로 묶어 "원문 보기"에서 통째로 보여 줍니다.
2-2. 응답 없음 — ANR in
E ActivityManager: ANR in com.example.app (com.example.app/.MainActivity)
E ActivityManager: PID: 1234
E ActivityManager: Reason: Input dispatching timed out ...
앱의 메인 스레드가 일정 시간 넘게 응답하지 못하면 시스템이 남기는 기록입니다. Reason:이 핵심입니다.
입력 처리 시간 초과인지, 브로드캐스트·서비스 시간 초과인지에 따라 조사 방향이 달라집니다.
메인 스레드에서 디스크·네트워크·무거운 연산을 하고 있지 않은지 먼저 의심합니다.
2-3. 네이티브 크래시 — Fatal signal
F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 1256 (RenderThread), pid 1234
F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
F DEBUG : backtrace:
C/C++ 코드나 코덱·드라이버 같은 네이티브 계층에서 잘못된 메모리에 접근하면 libc가 F 레벨로 Fatal signal을 남깁니다.
이어지는 DEBUG(기기·버전에 따라 crash_dump) 태그의 backtrace가 원인 추적의 단서입니다.
자바 예외보다 재현·분석이 어렵기 때문에, 이 패턴이 한 번이라도 있으면 우선순위를 올려 확인하는 편이 좋습니다.
2-4. 메모리 부족과 프로세스 종료
java.lang.OutOfMemoryError— 앱의 힙 메모리 초과. 이미지·버퍼를 과하게 붙들고 있는지 확인합니다.lowmemorykiller또는lmkd태그의Kill '...' (pid ...)— 시스템이 메모리를 확보하려고 프로세스를 강제 종료했다는 기록입니다(버전마다 태그가 다름). 앱이 스스로 죽은 것이 아니므로, 크래시 로그가 없는데 프로세스가 사라졌다면 이 기록을 찾아보세요.
2-5. 시스템 워치독 — Watchdog
시스템 서버의 핵심 스레드가 오래 멈추면 Watchdog 태그로 "WATCHDOG KILLING SYSTEM PROCESS" 같은 기록을 남기고 시스템 프로세스를 재시작합니다.
셋톱박스가 갑자기 재부팅·화면 초기화되는 증상과 겹친다면 앞뒤 수십 초를 확인하세요.
2-6. 로그 자체가 만든 착시 — chatty
I chatty : uid=1000(system) Binder:1234_5 identical 37 lines
같은 내용이 너무 자주 반복되면 logcat이 중복을 압축하고 identical N lines라는 한 줄만 남깁니다.
즉 집계된 E·F 건수는 실제 발생 횟수보다 적을 수 있습니다. 특정 태그의 건수가 이상하게 규칙적이거나 적다면 압축 여부를 확인하세요.
3. 태그로 범인의 위치를 짐작하기
태그는 "누가 말하는가"입니다. 아래는 예시이며, 제조사·OS 버전·앱 구성에 따라 실제 태그는 다릅니다.
| 태그 예시 | 보통 의미하는 영역 |
|---|---|
AndroidRuntime, System.err | 앱의 자바 예외와 스택트레이스 |
ActivityManager, WindowManager | 앱 실행·화면 전환·ANR 등 시스템 서버 |
MediaCodec, ExoPlayerImplInternal | 영상·음성 디코딩과 재생(재생 문제 조사의 출발점) |
ConnectivityService, wpa_supplicant | 네트워크 연결 상태·Wi-Fi |
| 앱 패키지명·자체 태그 | 서비스 사업자가 직접 남기는 로그(가장 유용하지만 형식이 제각각) |
대시보드의 오류 태그별 건수 막대가 길다고 곧바로 가장 위험한 것은 아닙니다. 다만 평소에 보이지 않던 태그가 갑자기 상위에 올라왔거나,
AndroidRuntime·libc처럼 프로세스가 죽는 태그가 나타났다면 그것이 첫 번째 조사 대상입니다.
4. 한 줄을 읽는 순서
- 레벨 — E·F인가, 아니면 W가 반복되는가?
- 태그 — 어느 영역의 말인가(앱? 시스템? 네이티브?)
- PID·TID — 같은 PID의 앞뒤 줄을 따라가면 그 프로세스의 이야기가 이어집니다. 프로세스가 재시작되면 PID가 바뀝니다.
- 메시지의 앞부분 —
FATAL EXCEPTION,ANR in,Fatal signal같은 키워드가 있는가? - 앞뒤 시간 — 오류 직전 5~10초에 무슨 일이 있었는가? (다음 글 로그 분석 순서 참고)
로그를 수집하는 방법은 adb logcat 수집 가이드에서, 파일을 올려 표와 그래프로 확인하는 것은 로그 분석 대시보드에서 할 수 있습니다.