本文將說明記錄程序,包括記錄標準、層級指南、類別、用途和多層架構近似值。
記錄標準
由於 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; |
---|
您可以在編譯時透過 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) 中的系統記錄
系統應用程式和服務可使用多個類別:
Class | 目的 |
---|---|
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
會使用下列巨集形式為 sublogs 群組提供包裝函式:
[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 |
記錄程式庫,可提供 C++ 串流介面進行記錄,類似於 Google 風格 (glog) 記錄。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
。 - 僅存取事件記錄緩衝區。
- 使用
EventLog
API。 - 使用檢測設備測試。
- 如果前景中的應用程式使用
READ_LOGS
要求存取裝置記錄,系統會提示使用者核准或拒絕這類存取要求。