Android 日志系統(tǒng)分析(三):logcat

一属韧、前言

logcat 作為讀取日志的工具楼镐,相當(dāng)于client 的角色忿族;在前兩篇文章中,關(guān)于 logcat 如何與其他部分溝通獲取日志信息的流程已經(jīng)介紹的比較清晰驻啤,本文不在贅述菲驴,轉(zhuǎn)而歸納一下 logcat 的一些常用指令,并對(duì)其中一些做詳細(xì)分析

二骑冗、命令簡(jiǎn)介

選項(xiàng) 描述 eg
-s 輸出指定 tag 的日志赊瞬,相當(dāng)于過濾器表達(dá)式 '*:S' logcat -s tag
-f <file> 設(shè)置logcat 內(nèi)容保存的位置先煎,默認(rèn)是stdout logcat -f sdcard/log.txt
-r <kbytes> 每輸出 <kbytes> 時(shí)輪替日志文件,默認(rèn)是16 必須配合 -f (暫不明白) logcat -f sdcard/log.txt -r 1
-n <count> 設(shè)置日志輸出的最大數(shù)目, 需要 -r 參數(shù) 暫不明白
-v <format> 設(shè)置日志消息的輸出格式巧涧。詳見下文 格式化輸出 logcat -v thread
-D 輸出各個(gè)日志緩沖區(qū)之間的分隔線 logcat -D ...
-c 清除(清空)所選的緩沖區(qū)并退出榨婆,默認(rèn)清除 main、system 和 crash logcat -c / -b all -c
-d 將日志轉(zhuǎn)儲(chǔ)到屏幕并退出 logcat -d > log.txt
-e <expr> 輸出正則匹配的日志消息 logcat -e 匹配數(shù)據(jù) -m 5
-m <count> 輸出 <count> 行后退出 ......
-t <count> 僅輸出最新的行數(shù)褒侧,此選項(xiàng)包括 -d 功能 logcat -t 5
-t '<time>' 輸出自指定時(shí)間以來的最新行良风,此選項(xiàng)包括 -d 功能 logcat -t '01-26 20:52:41.820'
-g 獲取指定日志緩沖區(qū)的大小并退出 logcat -g
-G 設(shè)置日志環(huán)形緩沖區(qū)的大小,可以在結(jié)尾處添加 K 或 M logcat -G 2M
-b 加載可供查看的日志緩沖區(qū)闷供,更多可見下文 日志緩沖區(qū) logcat -b system
-B 以二進(jìn)制文件形式輸出日志 ......
-S 在輸出中包含統(tǒng)計(jì)信息烟央,以識(shí)別和定位日志垃圾信息發(fā)送者 ......
--pid=<pid> 僅輸出來自給定 PID 的日志 logcat --pid=4355

三、日志緩沖區(qū)

Android 日志系統(tǒng)為日志消息保留了多個(gè)環(huán)形緩沖區(qū)歪脏,但并非多有的日志消息都會(huì)發(fā)送到默認(rèn)的環(huán)形緩沖區(qū)疑俭。這里可以采用 logcat -b 命令查看設(shè)備的其他緩沖區(qū):

緩沖區(qū) 描述 eg
radio 輸出通信系統(tǒng)的日志,包含無線裝置/電話相關(guān)消息 logcat -b radio
events 輸出event模塊的日志 logcat -b events
main 主日志緩沖區(qū)(默認(rèn))婿失,不包含系統(tǒng)和崩潰日志消息 logcat -b main
system 輸出系統(tǒng)日志 logcat -b system
crash 輸出崩潰日志 logcat -b crash
all 輸出所有緩沖區(qū)日志 logcat -b all
default 輸出main钞艇、system、crash緩沖區(qū)日志 logcat -b default

如果需要查看內(nèi)核空間日志信息豪硅,可采用如下幾種方式查看:

1哩照、讀取 /proc/kmsg ,命令如下

adb shell cat /proc/kmsg

讀取/proc/kmsg屬于消費(fèi)型讀取懒浮,讀取之后再次讀取不會(huì)顯示已經(jīng)讀取過的日志信息

2飘弧、讀取 /dev/kmsg,命令如下

adb shell cat /dev/kmsg

讀取/dev/kmsg會(huì)顯示緩存區(qū)里面的所有日志信息砚著。新寫入的日志信息會(huì)不斷累加到日志緩沖器中

3次伶、使用 dmesg 命令讀取

adb shell dmesg

dmesg命令讀取一次只顯示一部分日志,非阻塞執(zhí)行

四、格式化輸出

使用 -v 命令來修改 log 的輸出格式稽穆,以顯示特定的元數(shù)據(jù)字段:

格式 描述 eg
brief 顯示優(yōu)先級(jí)冠王、標(biāo)記以及發(fā)出消息的進(jìn)程的 PID ......
long 顯示所有元數(shù)據(jù)字段,并使用空白行分隔消息 ......
process 僅顯示 PID ......
raw 顯示不包含其他元數(shù)據(jù)字段的原始日志消息 ......
tag 僅顯示優(yōu)先級(jí)和標(biāo)記 ......
thread 舊版格式舌镶,顯示優(yōu)先級(jí)柱彻、PID 以及發(fā)出消息的線程的 TID ......
threadtime (默認(rèn)值)顯示日期、調(diào)用時(shí)間乎折、優(yōu)先級(jí)绒疗、標(biāo)記侵歇、PID 以及發(fā)出消息的線程的 TID ......
time 顯示日期骂澄、調(diào)用時(shí)間、優(yōu)先級(jí)惕虑、標(biāo)記以及發(fā)出消息的進(jìn)程的 PID ......
color 使用不同的顏色來顯示每個(gè)優(yōu)先級(jí) ......
descriptive 顯示日志緩沖區(qū)事件說明坟冲。此修飾符僅影響事件日志緩沖區(qū)消息磨镶,不會(huì)對(duì)其他非二進(jìn)制文件緩沖區(qū)產(chǎn)生任何影響 ......
epoch 顯示自 1970 年 1 月 1 日以來的時(shí)間(以秒為單位) ......
monotonic 顯示自上次啟動(dòng)以來的時(shí)間(以 CPU 秒為單位) ......
printable 確保所有二進(jìn)制日志記錄內(nèi)容都進(jìn)行了轉(zhuǎn)義 ......
uid 如果訪問控制允許,則顯示 UID 或記錄的進(jìn)程的 Android ID ......
usec 顯示精確到微秒的時(shí)間 ......
UTC 顯示 UTC 時(shí)間 ......
year 將年份添加到顯示的時(shí)間 ......
zone 將本地時(shí)區(qū)添加到顯示的時(shí)間 ......

優(yōu)先級(jí):

選項(xiàng) 描述 eg
V –Verbose(最低優(yōu)先級(jí)) adb logcat *:v
D – Debug adb logcat *:d
I – Info adb logcat *:i
W – Warning adb logcat *:w
E – Error adb logcat *:e
F – Fatal adb logcat *:f
S – Silent adb logcat *:s

五健提、logcat -f 命令詳解

logcat -f 命令可以將日志消息輸出到指定的文件中琳猫。這里我們需要確定的一件事是 logcat 作為客戶端的角色,會(huì)將通過 liblog 獲得的日志信息進(jìn)行格式解析私痹、格式化處理脐嫂,而 liblog 庫(kù)本身并不存在保存、解析的功能紊遵。這里來對(duì) -f 指令做一下解析:

logcat_main.cpp # main()
    ---> logcat.cpp # android_logcat_run_command()
        ---> __logcat()
            {
                ......

                case 'f':
                    if ((tail_time == log_time::EPOCH) && !tail_lines) {
                        tail_time = lastLogTime(optctx.optarg);
                    }
                    // redirect output to a file
                    context->outputFileName = optctx.optarg;   //注釋 ①
                    break;

                ......


                setupOutputAndSchedulingPolicy()   //注釋 ②

 
                 while (...) {   //注釋 ③

                    int ret = android_logger_list_read(logger_list, &log_msg);
                    
                    if (context->printBinary) {
                        printBinary(context, &log_msg);
                    } else {
                        processBuffer(context, dev, &log_msg);
                    }

                ......

            }

5.1 注釋① :解析 -f 指令

          case 'f':
                  if ((tail_time == log_time::EPOCH) && !tail_lines) {
                        tail_time = lastLogTime(optctx.optarg);
                    }
                    // redirect output to a file
                    context->outputFileName = optctx.optarg;   //注釋 ①
                    break;

_logcat() 函數(shù)中解析 -f 指令账千,設(shè)置日志輸出文件。例如 logcat -f sdcard/log.txt 暗膜,則 context->outputFileName 賦值為 sdcard/log.txt匀奏;

5.2 注釋② :設(shè)置輸出路徑

static void setupOutputAndSchedulingPolicy(
    android_logcat_context_internal* context, bool blocking) {
    
    if (!context->outputFileName) return;

    ......
  
    // 打開文件獲得 fd 
    context->output_fd = openLogFile(context->outputFileName);

    if (context->output_fd < 0) {
        logcat_panic(context, HELP_FALSE, "couldn't open output file");
        return;
    }

    ......
}

5.3 注釋③ :寫入日志


               while (...) {   
                                // 調(diào)用 liblog 庫(kù)中的 android_logger_list_read 函數(shù)獲取日志 
                    int ret = android_logger_list_read(logger_list, &log_msg);
                    
                    if (context->printBinary) {       
                                    // 根據(jù)上面獲取的文件 fd ,將日志消息寫入文件
                        printBinary(context, &log_msg);
                    } else {
                        processBuffer(context, dev, &log_msg);
                    }

printBinary() 函數(shù)為例:

logcat.cpp # printBinary() :

void printBinary(android_logcat_context_internal* context, struct log_msg* buf) {
    size_t size = buf->len();

    TEMP_FAILURE_RETRY(write(context->output_fd, buf, size));
}

參考

[ 1 ] Android物語(yǔ):logcat
[ 2 ] android調(diào)試——logcat詳解
[ 3 ] 玩轉(zhuǎn)Android10源碼開發(fā)定制(12)內(nèi)核篇之logcat輸出內(nèi)核日志

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市学搜,隨后出現(xiàn)的幾起案子娃善,更是在濱河造成了極大的恐慌,老刑警劉巖瑞佩,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聚磺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡炬丸,警方通過查閱死者的電腦和手機(jī)咧最,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來御雕,“玉大人矢沿,你說我怎么就攤上這事∷岣伲” “怎么了捣鲸?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)闽坡。 經(jīng)常有香客問我栽惶,道長(zhǎng),這世上最難降的妖魔是什么疾嗅? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任外厂,我火速辦了婚禮,結(jié)果婚禮上代承,老公的妹妹穿的比我還像新娘汁蝶。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布掖棉。 她就那樣靜靜地躺著墓律,像睡著了一般。 火紅的嫁衣襯著肌膚如雪幔亥。 梳的紋絲不亂的頭發(fā)上耻讽,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音帕棉,去河邊找鬼针肥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛香伴,可吹牛的內(nèi)容都是我干的祖驱。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼瞒窒,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼捺僻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起崇裁,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤匕坯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后拔稳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葛峻,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年巴比,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了术奖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轻绞,死狀恐怖采记,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情政勃,我是刑警寧澤唧龄,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站奸远,受9級(jí)特大地震影響既棺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜懒叛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一丸冕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薛窥,春花似錦胖烛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)妥凳。三九已至竟贯,卻和暖如春答捕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屑那。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工拱镐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人持际。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓沃琅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蜘欲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子益眉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容