이 문서에서는 로그 표준, 수준 가이드라인, 클래스, 목적, 다중 스택 근사를 포함하여 로깅 프로세스를 설명합니다.
로그 표준
Android에서 로깅은 logcat
에 결합된 표준이 혼합되어 사용되기 때문에 복잡합니다. 아래에는 사용되는 기본 표준이 자세히 설명되어 있습니다.
소스 | 예 | 스택 수준 안내 |
---|---|---|
RFC 5424 (syslog 표준) |
Linux 커널, 다양한 Unix 애플리케이션 | 커널, 시스템 데몬 |
android.util.Log |
Android 프레임워크 + 애플리케이션 로깅 | Android 프레임워크 및 시스템 애플리케이션 |
java.util.logging.Level |
자바에서의 일반 로깅 | 비 시스템 애플리케이션 |
그림 1: 로그 수준 표준.
이러한 각 표준은 비슷한 수준의 구성을 갖지만, 세분성에서는 다릅니다. 표준 전반에 걸쳐 대략적으로 상응하는 항목은 다음과 같습니다.
RFC 5424 수준 | RFC 5424 심각도 | RFC 5424 설명 | android.util.Log | java.util.logging.Level |
---|---|---|---|---|
0 | 긴급 | 시스템을 사용할 수 없음 | Log.e / Log.wtf |
SEVERE |
1 | 주의 | 즉시 조치를 취해야 함 | Log.e / Log.wtf |
SEVERE |
2 | 심각 | 위험한 상태 | Log.e / Log.wtf |
SEVERE |
3 | 오류 | 오류 상태 | Log.e |
SEVERE |
4 | 경고 | 경고 상태 | Log.w |
WARNING |
5 | 알림 | 정상이지만 중요함 | Log.w |
WARNING |
6 | 정보 | 정보 메시지 | Log.i |
INFO |
7 | 디버그 | 디버그 수준 메시지 | Log.d |
CONFIG , FINE |
- | - | 상세 메시지 | Log.v |
FINER /FINEST |
그림 2: syslog
, Android 및 자바 로깅 수준
로그 수준 가이드라인
로그 표준마다 기존 가이드라인이 있습니다. 선택된 로그 수준은 사용 중인 관련 표준을 따릅니다(예: 커널 개발에는 syslog
표준 사용).
아래 세 가지 그림에는 로그 수준이 낮은 순에서 높은 순으로 표시되어 있습니다.
ERROR |
이러한 로그는 항상 보관됩니다. |
WARN |
이러한 로그는 항상 보관됩니다. |
INFO |
이러한 로그는 항상 보관됩니다. |
DEBUG |
이러한 로그는 컴파일되지만 런타임 시 삭제됩니다. |
VERBOSE |
이러한 로그는 개발 단계 외에는 애플리케이션에 컴파일되지 않습니다. |
그림 3: android.util.Log
CONFIG |
정적 구성 메시지의 메시지 수준 |
FINE |
추적 정보를 제공하는 메시지 수준 |
FINER |
상당히 자세한 추적 메시지를 나타냄 |
FINEST |
매우 상세한 추적 메시지를 나타냄 |
INFO |
정보 메시지의 메시지 수준 |
SEVERE |
심각한 오류를 나타내는 메시지 수준 |
WARNING |
잠재적 문제를 나타내는 메시지 수준 |
그림 4: java.util.Logging.Level
.
0 | 긴급 | 시스템을 사용할 수 없음 |
1 | 주의 | 즉시 조치를 취해야 함 |
2 | 심각 | 위험한 상태 |
3 | 오류 | 오류 상태 |
4 | 경고 | 경고 상태 |
5 | 알림 | 정상이지만 중요한 상태 |
6 | 정보 | 정보 메시지 |
7 | 디버그 | 디버그 수준 메시지 |
그림 5: RFC 5424
- 섹션 6.2.1.
애플리케이션 로깅
아래와 같이 선택적 로깅은 Log#isLoggable
을 사용하는 android.util.Log
클래스에 TAG
를 사용하여 수행됩니다.
if (Log.isLoggable("FOO_TAG", Log.VERBOSE)) { Log.v("FOO_TAG", "Message for logging."); } |
---|
아래와 같이 선택한 수준의 로깅을 제공하도록 런타임 시 로그를 조정할 수 있습니다.
adb shell setprop log.tag.FOO_TAG VERBOSE |
---|
log.tag.*
속성은 재부팅 시 재설정됩니다. 재부팅에서 유지되는 영구 변형도 있습니다. 아래를 참고하세요.
adb shell setprop persist.log.tag.FOO_TAG VERBOSE |
---|
Log#isLoggable
검사는 애플리케이션 코드에 로그 추적을 남겨 둡니다. 아래와 같이 부울 DEBUG
플래그는 false
로 설정된 컴파일러 최적화를 사용하여 로그 추적을 우회합니다.
private final static boolean DEBUG = false; |
---|
로깅은 컴파일 시간에 R8
에 의한 ProGuard 규칙 세트를 통해 APK별로 삭제할 수 있습니다. 다음 예에서는 android.util.Log
에 관해 로깅된 내용 중에서 INFO
수준 아래의 모든 내용을 삭제합니다.
# This allows proguard to strip isLoggable() blocks containing only <=INFO log # code from release builds. -assumenosideeffects class android.util.Log { static *** i(...); static *** d(...); static *** v(...); static *** isLoggable(...); } -maximumremovedandroidloglevel 4 |
---|
이 작업은 기본 코드가 동일해야 하지만 허용되는 로그 수준이 서로 다른 여러 개의 애플리케이션 빌드 유형(예: 개발 빌드와 출시 빌드)을 처리할 때 도움이 됩니다. 빌드 유형과 예상되는 출시 정보가 로그 출력에 어떠한 영향을 미치게 할지 정하려면 애플리케이션(특히 시스템 애플리케이션)에 관한 명시적 정책을 설정하고 준수해야 합니다.
Android 런타임(ART)의 시스템 로깅
시스템 애플리케이션과 서비스에 사용할 수 있는 몇 가지 클래스가 있습니다.
클래스 | 목적 |
---|---|
android.telephony.Rlog |
라디오 로깅 |
android.util.Log |
일반 애플리케이션 로깅 |
android.util.EventLog |
시스템 통합자 진단 이벤트 로깅 |
android.util.Slog |
플랫폼 프레임워크 로깅 |
그림 6: 사용 가능한 시스템 로그 클래스 및 목적
android.util.Log
와 android.util.Slog
는 동일한 로그 수준 표준을 사용하지만 Slog
는 플랫폼에만 사용할 수 있는 @hide
클래스입니다. EventLog
수준은 /system/etc/event-log-tags
의 event.logtags
파일에 있는 항목에 매핑됩니다.
기본 로깅
C/C++를 이용한 로깅은 printk
버퍼를 제어하는 Linux 커널 syslog
에 대응하는 syslog
(2)와 일반 시스템 로거에 대응하는 syslog
(3)을 사용하는 syslog
표준을 따릅니다. Android는 일반 시스템 로깅에 liblog
라이브러리를 사용합니다.
liblog
는 다음 매크로 양식을 사용하여 하위 로그 그룹을 위한 래퍼를 제공합니다.
[Sublog Buffer ID] LOG [Log Level ID] |
예를 들어 RLOGD
는 [Radio log buffer ID] LOG [Debug Level]
에 상응합니다.
주요 liblog
래퍼는 다음과 같습니다.
래퍼 클래스 | 예제 함수 |
---|---|
log_main.h |
ALOGV , ALOGW |
log_radio.h |
RLOGD , RLOGE |
log_system.h |
SLOGI , SLOGW |
그림 7: liblog
래퍼
다음과 같이 Android에는 로깅에 직접 liblog
를 사용하는 것보다 선호되는 더 높은 수준의 인터페이스가 있습니다.
라이브러리 | 사용 |
---|---|
async_safe |
async-signal-safe 환경에서 로깅하기 위한 전용 라이브러리 |
libbase |
Google 스타일(glog) 로깅과 유사한 로깅에 C++ 스트림 인터페이스를 제공하는 로깅 라이브러리. libbase 는 외부 프로젝트 모두에서 사용할 수 있으며 libbase_ndk 를 사용하는 애플리케이션에서 사용할 수 있습니다. |
그림 8: 더 높은 수준의 로그 라이브러리
다중 스택 근사
세분성과 수준 인텐트의 차이로 인해 서로 다른 로깅 표준이 명확하게 또는 정확하게 일치되지 않습니다. 예를 들어 오류 로그의 java.util.logging.Level
수준과 android.util.Log
수준은 1:1로 일치되지 않습니다.
java.util.Logging.Level | android.util.Log |
---|---|
SEVERE | Log.wtf |
SEVERE | Log.e |
그림 9: 표준 자바 로깅과 Android 로깅의 오류 수준 비교
이 같은 경우에는 개별 표준을 사용하여 적용할 수준을 결정합니다.
다중 스택 수준 구성요소가 포함된 시스템 개발 중에는 그림 1에 따라 구성요소별로 사용할 표준을 정합니다. 계층 메시징에 관한 대략적인 가이드는 그림 2를 참고하세요.
보안 및 개인 정보 보호
개인 식별 정보(PII)를 로깅하지 마세요. 다음과 같은 세부정보가 여기에 포함됩니다.
- 이메일 주소
- 전화번호
- 이름
마찬가지로, 명시적으로 개인 식별이 가능하지 않더라도 민감한 정보로 간주되는 특정 세부정보가 있습니다.
예를 들어 시간대 정보는 개인 식별 정보로 간주되지 않지만 사용자의 대략적 위치를 알려 줍니다.
로그 정책 및 허용 가능한 세부정보는 출시 전에 보안 및 개인 정보 보호 검토의 일부로 처리해야 합니다.