本文將介紹記錄程序,包括記錄標準、層級指南、類別、用途和多堆疊近似值。
記錄標準
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 |
CONFIG、FINE |
| - | - | 詳細訊息 | 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; |
|---|
您可以在編譯時透過 ProGuard 規則集,依據 APK 移除記錄。R8以下範例會移除 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++ 中的記錄遵循 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 |
ALOGV、ALOGW |
log_radio.h |
RLOGD、RLOGE |
log_system.h |
SLOGI、SLOGW |
圖 7: liblog 包裝函式。
Android 提供較高層級的記錄介面,因此建議您使用這些介面,而非直接使用 liblog,如下所示:
| 程式庫 | 用量 |
|---|---|
async_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:標準 Java 記錄與 Android 記錄中的錯誤層級。
在這種情況下,請使用個別標準來判斷要套用哪個等級。
使用多個堆疊層級元件開發系統時,請按照圖 1 決定每個元件要使用的標準。如需各層級訊息的概略指南,請參閱圖 2。
安全性和隱私權
請勿記錄個人識別資訊 (PII)。包括:
- 電子郵件地址
- 電話號碼
- 名稱
同樣地,即使某些詳細資料並非明確的個人識別資訊,仍屬於敏感資訊。
舉例來說,時區資訊雖然不屬於個人識別資訊,
但可指出使用者的概略位置。
發布前,必須先完成安全性與隱私權審查,才能處理記錄政策和可接受的詳細資料。
裝置記錄
存取所有裝置記錄 (包括使用 android.permission.READ_LOGS) 的權限受到限制:
- 如果應用程式在背景中要求存取所有裝置記錄,系統會自動拒絕這類要求,除非應用程式符合下列條件:
- 分享系統 UID。
- 使用原生系統程序 (
UID<APP_UID)。 - 使用
DropBoxManager。 - 僅存取事件記錄緩衝區。
- 使用
EventLogAPI。 - 使用檢測設備測試。
- 如果前景應用程式 (含
READ_LOGS) 要求存取裝置記錄,系統會提示使用者核准或拒絕這類要求。