로깅 이해

이 문서에서는 로그 표준, 수준 가이드라인, 클래스, 목적, 다중 스택 근사를 포함하여 로깅 프로세스를 설명합니다.

로그 표준

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;

… If (DEBUG) { Log.v("FOO_TAG", "Extra debug logging."); }

로깅은 컴파일 시간에 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.Logandroid.util.Slog는 동일한 로그 수준 표준을 사용하지만 Slog는 플랫폼에만 사용할 수 있는 @hide 클래스입니다. EventLog 수준은 /system/etc/event-log-tagsevent.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)를 로깅하지 마세요. 다음과 같은 세부정보가 여기에 포함됩니다.

  • 이메일 주소
  • 전화번호
  • 이름

마찬가지로, 명시적으로 개인 식별이 가능하지 않더라도 민감한 정보로 간주되는 특정 세부정보가 있습니다.

예를 들어 시간대 정보는 개인 식별 정보로 간주되지 않지만 사용자의 대략적 위치를 알려 줍니다.

로그 정책 및 허용 가능한 세부정보는 출시 전에 보안 및 개인 정보 보호 검토의 일부로 처리해야 합니다.