瞭解記錄

本文將介紹記錄程序,包括記錄標準、層級指南、類別、用途和多堆疊近似值。

記錄標準

Android 記錄檔使用的標準混雜,並在 logcat 中合併,因此記錄檔相當複雜。主要使用的標準如下:

Source 範例 堆疊層級指南
RFC 5424 (syslog 標準) Linux 核心、許多 Unix 應用程式 核心、系統 Daemon
android.util.Log Android 架構 + 應用程式記錄 Android 架構和系統應用程式
java.util.logging.Level Java 中的一般記錄 非系統應用程式

圖 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 CONFIGFINE
- - 詳細訊息 Log.v FINER/FINEST

圖 2: syslog、Android 和 Java 記錄層級。

記錄層級指南

每個記錄標準都有現行規範。所選記錄層級會遵循適用的標準,例如使用 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 節

應用程式記錄

選取性記錄是透過 android.util.Log 類別使用 Log#isLoggable 執行,如下所示: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."); }

您可以在編譯時透過 ProGuard 規則集,依據 APK 移除記錄。R8以下範例會移除 android.util.LogINFO 級別以下所有記錄:

# 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++ 中的記錄遵循 syslog 標準,其中 syslog(2) 對應於控制 printk 緩衝區的 Linux 核心 syslog,而 syslog(3) 則對應於一般系統記錄器。Android 會使用 liblog 程式庫進行一般系統記錄。

liblog 使用下列巨集形式,為子記錄群組提供包裝函式:

[Sublog Buffer ID] LOG [Log Level ID]

舉例來說,RLOGD 對應於 [Radio log buffer ID] LOG [Debug Level]。 主要的 liblog 包裝函式如下:

包裝函式類別 函式範例
log_main.h ALOGVALOGW
log_radio.h RLOGDRLOGE
log_system.h SLOGISLOGW

圖 7: liblog 包裝函式。

Android 提供較高層級的記錄介面,因此建議您使用這些介面,而非直接使用 liblog,如下所示:

程式庫 用量
async_safe 這個程式庫僅適用於從非同步訊號安全環境記錄
libbase 記錄程式庫,提供類似 Google 樣式 (glog) 記錄的 C++ 串流介面。libbase 可用於外部專案,並在採用 libbase_ndk 的應用程式中使用。

圖 8:較高層級的記錄檔程式庫。

多堆疊近似值

由於精細程度和意圖層級不同,不同記錄標準之間沒有明確或完全相符的對應關係。舉例來說,錯誤記錄的 java.util.logging.Levelandroid.util.Log 層級並非 1:1 對應:

java.util.Logging.Level android.util.Log
SEVERE Log.wtf
SEVERE Log.e

圖 9:標準 Java 記錄與 Android 記錄中的錯誤層級。

在這種情況下,請使用個別標準來判斷要套用哪個等級。

使用多個堆疊層級元件開發系統時,請按照圖 1 決定每個元件要使用的標準。如需各層級訊息的概略指南,請參閱圖 2。

安全性和隱私權

請勿記錄個人識別資訊 (PII)。包括:

  • 電子郵件地址
  • 電話號碼
  • 名稱

同樣地,即使某些詳細資料並非明確的個人識別資訊,仍屬於敏感資訊。

舉例來說,時區資訊雖然不屬於個人識別資訊, 但可指出使用者的概略位置。

發布前,必須先完成安全性與隱私權審查,才能處理記錄政策和可接受的詳細資料。

裝置記錄

存取所有裝置記錄 (包括使用 android.permission.READ_LOGS) 的權限受到限制:

  • 如果應用程式在背景中要求存取所有裝置記錄,系統會自動拒絕這類要求,除非應用程式符合下列條件:
    • 分享系統 UID。
    • 使用原生系統程序 (UID < APP_UID)。
    • 使用 DropBoxManager
    • 僅存取事件記錄緩衝區。
    • 使用 EventLog API。
    • 使用檢測設備測試。
  • 如果前景應用程式 (含 READ_LOGS) 要求存取裝置記錄,系統會提示使用者核准或拒絕這類要求。