Logcat 命令列工具

Logcat 是一種命令列工具,可叫出系統訊息的記錄檔,包括裝置在跳出錯誤提醒時留下的堆疊追蹤,及您使用 Log 類別在應用程式寫入的訊息。

本頁面主要說明命令列 Logcat 工具,但您其實也可以在 Android Studio 的「Logcat」視窗中檢視訊息記錄。想瞭解如何透過 Android Studio 查看及篩選記錄檔,請參考用 Logcat 編寫及檢視記錄檔

記錄系統總覽

Android 記錄系統是一組由系統程序 logd 維護的環形緩衝區結構。這組緩衝區結構受到系統規範,十分穩定。最相關的記錄有:main,儲存大部分的應用程式記錄;system,儲存來自 Android OS 的訊息;以及 crash,儲存系統崩潰記錄。每次記錄都有優先順序 (VERBOSEDEBUGINFOWARNINGERROR,或 FATAL 其中之一),作為標記來辨別記錄來源和詳細的記錄訊息。

記錄系統的主要介面是共用資料庫 liblog 和其標頭 <android/log.h>。所有語言專用的記錄設備最終都會呼叫 __android_log_write 函式。根據預設會呼叫 __android_log_logd_logger 函式,並利用通訊端將記錄傳送至 logd。從 API 層級 30 開始,可以透過呼叫 __android_set_log_writer 來變更記錄函式。詳情請參閱NDK 說明文件

adb logcat 顯示的記錄會經過四次不同等級的篩選:

  1. 以編譯時間篩選:視編譯設定而定,部分記錄檔可能會從二進位檔完全移除。例如,您可以設定 Proguard 來移除 Java 程式碼中對 Log.d 的呼叫記錄。
  2. 系統屬性篩選:liblog 會查詢一組系統屬性,來決定需要傳送到 logd 的最小嚴重性等級。如果您的記錄中包含 MyApp 標記,則系統會檢查以下屬性,並會包含最小嚴重性的第一個字母 (從VDIWE,若程度嚴重到 S 將停用所有記錄):
    • log.tag.MyApp
    • persist.log.tag.MyApp
    • log.tag
    • persist.log.tag
  3. 應用程式篩選:如未設定任何屬性,liblog 會使用 __android_log_set_minimum_priority 設定的最小優先順序。預設為 INFO
  4. 畫面顯示篩選:adb logcat 會支援額外的篩選器,可減少 logd 顯示的記錄量。細節如下

命令列語法

如要透過 ADB 殼層來執行 logcat,常見寫法為:

[adb] logcat [<option>] ... [<filter-spec>] ...

您可以將 logcat 當做 ADB 指令執行,也可以直接在模擬器或連線裝置中的殼層提示中運作。想用 adb 檢視記錄檔輸出內容,請前往 SDK platform-tools/ 目錄並執行下列指令:

adb logcat

如想取得 logcat 線上說明,請啟動裝置並執行下列指令:

adb logcat --help

您可以透過殼層為裝置建立連線,並執行下列指令:

$ adb shell
# logcat

選項

下表將說明 logcat 的命令列選項。

選項 說明
-b <buffer> 載入備用記錄緩衝區來檢視,例如 eventsradio。根據預設,系統會使用 mainsystemcrash 緩衝區組合。請參考檢視備用記錄緩衝區一文。
-c, --clear 清除所選緩衝區後退出。預設緩衝集區為 mainsystemcrash。如要清除所有緩衝區,請使用 -b all -c
-e <expr>, --regex=<expr> 僅顯示當 <expr> 為一規則運算式,且記錄訊息與 <expr> 相符的記錄。
-m <count>, --max-count=<count> 在顯示 <count> 行後結束。本設計為與--regex配對,但也會自行運作。
--print --regex--max-count 配對使用,讓內容略過規則運算式篩選器,但仍能到正確的比對數量時停止。
-d 讓記錄檔顯示在畫面上後退出。
-f <filename> 將記錄訊息輸出寫入 <filename>。預設為 stdout
-g, --buffer-size 顯示指定記錄緩衝區的大小後退出。
-n <count> 將輪替的記錄檔數量上限寫入 <count>。預設值為 4。需要有 -r 選項。
-r <kbytes> 每輸出 <kbytes> 一次,輪替一次記錄檔。預設值為 16。需要有 -f 選項。
-s 等同於篩選器運算式 '*:S',能讓所有標記先靜音,用來優先篩選出新增內容的運算式清單。詳情請參閱篩選記錄檔輸出一節。
-v <format> 設定記錄訊息的輸出格式。預設值為 threadtime 格式。如需支援格式的清單,請參閱控制記錄檔輸出格式一節的說明。
-D, --dividers 顯示每個記錄緩衝區之間的分隔符號。
-c 清除全部記錄並退出。
-t <count> 僅顯示距離最近的數行。這個選項包含 -d 功能。
-t '<time>' 顯示指定時間之後的所有部分。這個選項包含 -d 功能性。如要瞭解含有內嵌空格的參數引用,請參閱-P 選項部分。

adb logcat -t '01-26 20:52:41.820'
-T <count> 顯示指定時間之後的最新數行。這個選項不包含 -d 功能性
-T '<time>' 顯示指定時間之後的所有部分。這個選項不包括 -d 功能。如要瞭解含有內嵌空格的參數引用,請參閱-P 選項部分。

adb logcat -t '01-26 20:52:41.820'
-L, --last 叫出上次重新啟動之前的記錄檔。
-B, --binary 以二進位檔案輸出記錄。
-S, --statistics 在輸出結果中加入統計資料,以便您辨識並鎖定垃圾記錄發布者。
-G <size> 設定記錄環形緩衝區的大小。在結尾加上 KM 來表示 KB 或 MB。
-p, --prune 列印 (讀取) 許可清單和拒絕清單,且不需要引數,如下所示:

adb logcat -p
-P '<list> ...'
--prune '<list> ...' -P '<allowlist_and_denylist>'
寫入 (設定) 許可清單和拒絕清單,以針對特定用途調整記錄內容。您提供許可清單和拒絕清單資料的複合型內容,且 <allowlist><denylist> 可為 UID、UID/PID 或 PID。參考 Logcat 統計資料 (logcat -S) 的指南,就可以考慮針對不同目的調整許可清單和拒絕清單,例如:
  • 透過特定 UID 選項,提供給特定記錄內容最長效期。
  • 防止其他人 (UID) 或某些資訊 (PID) 來消耗這些資源,以便增加記錄範圍,並藉此取得可深入診斷問題的更高權限。

根據預設,記錄系統會經常性、自動避開記錄數據中最嚴重的累犯,以騰出空間存放新的記錄訊息。耗盡了所有的計算法則後,系統會裁掉最舊的項目以騰出空間處理新訊息。

加入許可清單,可保護 Android 識別編號 (AID),然後此識別編號會成為處理程序的 AID 和 GID,而不會被誤判為錯誤,而加入拒絕清單可以在日後發生最壞錯誤之前,預先清出一些空間。您可以自行設定裁舊的運作頻率。也可以適時關閉裁舊功能,讓系統僅移除每個記錄緩衝區中最老舊的內容。

引用

adb logcat 不會保留引號,因此用於指定許可清單和拒絕清單的語法如下:


$ adb logcat -P '"<allowlist_and_denylist>"'

or

adb shell
$ logcat -P '<allowlist_and_denylist>'

以下範例指定有 PID 32676 和 UID 675 的許可清單,以及列有 PID 32677 和 UID 897 的拒絕清單。拒絕清單上的 PID 32677 將被賦予權重,以加快裁舊作業。


adb logcat -P '"/32676 675 ~/32677 897"'

其他可用的許可清單和拒絕指令變化如下:


~! worst uid denylist
~1000/! worst pid in system (1000)
--pid=<pid> ... 僅顯示指定 PID 的記錄。
--wrap 休眠 2 小時後,或緩衝即將結束時 (兩者取其先)。採用緩衝結束前的自動喚醒機制,來提升輪詢效率。

篩選記錄檔輸出內容

  • 記錄訊息的標記是一簡短字串,指出訊息的來源系統元件 (例如檢視系統的「View」)。
  • 優先順序是下列字元代表的其中一層意義,由低至高排序:
    • V:詳細 (優先度最低)
    • D:偵錯
    • I:資訊
    • W:警示
    • E:錯誤
    • F:嚴重
    • S:靜音 (優先度最高,不顯示任何記錄)

如要獲得系統內使用、一併附上優先度的標記清單,請執行 logcat 並觀察每則訊息的前兩欄,顯示如 <priority>/<tag>

以下是使用 logcat -v brief output 指令取得的 logcat 輸出內容簡短範例。範例顯示,該訊息與優先度等級「I」及「ActivityManager」標記有關:

I/ActivityManager(  585): Starting activity: Intent { action=android.intent.action...}

想將記錄檔輸出量縮減至可管理的程度,您可以透過篩選運算式來限制。您可以透過篩選運算式,向系統指出想關注的標記/優先度組合;系統將會專注於選定的標記而隱藏其他訊息。

篩選運算式符合以下格式:tag:priority ...。其中 tag 代表重點標記;priority,則是針對該標記需要呈報的最低優先度。系統會將屬於該標記、且優先度在設定值以上的訊息寫入記錄檔。您可以在單一篩選運算式中,提供不限數量的 tag:priority 設定值。這些設定值之間設有空格來分隔。

這個範例呈現的是,篩選運算式隱藏了絕大多數的訊息記錄,除了以下兩個情況。附有「ActivityManager」標記、且優先度為「Info」以上;或附有「MyApp」標記、且優先度為「Debug」以上。

adb logcat ActivityManager:I MyApp:D *:S

上述運算式中的最後一個元素 *:S 會將所有標記的優先度設為「靜音」,來確保系統只會顯示含有「ActivityManager」和「MyApp」標記的訊息記錄。使用 *:S 可以確保記錄檔輸出內容侷限於您指定過的篩選標準,也讓這些篩選條件可以做為記錄檔輸出時的許可清單。

以下篩選運算式會顯示所有標記內,優先度為「warning」以上的記錄訊息:

adb logcat *:W

如果您是用開發電腦執行 logcat (而非在遠端 ADB 殼層中執行),則可以考慮匯出環境變數 ANDROID_LOG_TAGS 的值,並將其設為預設的篩選運算式:

export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S"

請注意,如果您是透過遠端殼層或使用 adb shell logcat 來執行 logcat,篩選條件 ANDROID_LOG_TAGS 就不會匯出至模擬器或裝置實體。

控制記錄檔輸出格式

訊息記錄除了標記和優先度之外,還有多個中繼資料欄。您可以修改訊息的輸出格式,讓訊息顯示特定的中繼資料欄。方法是利用 -v 選項,並指定下列其中一種有支援的輸出格式。

  • brief:顯示優先度、標記,和發布該訊息的程序 ID(PID)。
  • long:顯示所有中繼資料欄,並以空白行隔開不同訊息。
  • process:僅顯示 PID。
  • raw:顯示不含其他中繼資料欄的原始訊息記錄。
  • tag:僅顯示優先度和標記。
  • thread: 為一舊版格式。會顯示優先度、PID,以及發布該訊息的緒 ID(TID)。
  • threadtime(預設):顯示訊息的發送日期、叫用時間、優先度、標記、PID,和 TID。
  • time:顯示訊息的發送日期、叫用時間、優先度、標記,和 PID。

啟動 logcat 時,您可以利用 -v 選項來指定需要的輸出格式:

[adb] logcat [-v <format>]

以下範例將呈現如何產生 thread 輸出格式的訊息:

adb logcat -v thread

請注意,選用 -v 後將只能指定一種輸出格式,但您仍可以指定合理範圍內任意數量的修飾符。Logcat 會忽略不合邏輯的修飾符。

格式修飾符

格式修飾符一般會在組合下列的一至多個後,來變更 Logcat 輸出內容。如要指定格式修飾符,請選用 -v,如下所示:

adb logcat -b all -v color -d

每個 Android 訊息記錄都有一個相關的標記和優先順序。任何格式修飾符皆可與下列任一格式選項搭配使用:brieflongprocessrawtagthreadthreadtime,和 time

想取得格式修飾符的詳細資料,請在命令列中輸入 logcat -v --help

  • color:以不同顏色表示不同優先度。
  • descriptive:顯示記錄緩衝區的事件說明。這項修飾符只會影響記錄緩衝區事件的訊息,並不影響其他非二進位緩衝區。事件說明取自事件、記錄檔和標記的集合資料庫。
  • epoch:顯示從 1970 年 1 月 1 日開始至今的時間 (以秒為單位)。
  • monotonic:顯示從上次啟動以來,CPU 的總運作時間 (以秒為單位)。
  • printable:確保所有二進位檔記錄內容均成功逸出。
  • uid:如果存取控制允許,顯示已記錄程序的 UID 或 Android ID。
  • usec:顯示時間,單位精確至微秒。
  • UTC:顯示世界協調時間。
  • year:於顯示時間中加入年份。
  • zone:在顯示時間中加註當地時區。

查看替代記錄緩衝區

Android 記錄系統會保留多個環形緩衝區來存放記錄訊息,但也並非所有記錄訊息都會傳送至預設的環形緩衝區。想查看其他記錄訊息,您可以選用 -b 來執行 logcat 指令,請求檢視替代的環形緩衝區。您可以檢視下列任一替代緩衝區:

  • radio:檢視內含無線電 / 電話服務相關訊息的緩衝區。
  • events:檢視已解譯的二進位系統緩衝區訊息。
  • main:檢視主要記錄緩衝區 (預設),不含系統或系統崩潰記錄訊息。
  • system:檢視系統記錄緩衝區 (預設)。
  • crash:檢視系統崩潰記錄緩衝區 (預設)。
  • all:檢視所有緩衝區。
  • default:回報 mainsystem,和 crash 緩衝區。

-b 的使用方式為:

[adb] logcat [-b <buffer>]

以下範例說明如何檢視包含無線電和電話服務訊息的記錄緩衝區:

adb logcat -b radio

您也可以針對需要顯示的所有緩衝區指定多個 -b 標記,如下所示:

logcat -b main -b radio -b events

您可以指定一緩衝區清單列 (各緩衝區以逗號隔開) 及單一 -b 標記,例如:

logcat -b main,radio,events

程式碼記錄

透過 Log 類別,您可以在自己的程式碼中建立記錄,而後顯示在 Logcat 工具中。常見的記錄方式包括:

以下列呼叫模式為例:

Kotlin

Log.i("MyActivity", "MyClass.getView() — get item number $position")

Java

Log.i("MyActivity", "MyClass.getView() — get item number " + position);

logcat 輸出的內容如:

I/MyActivity( 1557): MyClass.getView() — get item number 1