Android 日志系統(tǒng)分析(二):logd

一羡宙、前言

logd 守護(hù)進(jìn)程是日志系統(tǒng)的管家凌盯,內(nèi)部維持三個(gè)日志 Socket : logd付枫、logdr、logdw 來與客戶端進(jìn)行通信驰怎。同時(shí)負(fù)責(zé)維護(hù)幾個(gè)環(huán)形緩沖區(qū)阐滩,用于存放系統(tǒng)中的各種日志,緩沖區(qū)包含 main砸西、system叶眉、events址儒、radio芹枷、crash、kernel 莲趣;但是在 Android 5.0 之前鸳慈,logd 進(jìn)程并不存在,日志是保留在 /dev/log/main喧伞、/dev/log/system走芋、/dev/log/radio、/dev/log/event 等節(jié)點(diǎn)中潘鲫,但是這樣面臨的一個(gè)問題就是當(dāng) Android 系統(tǒng)大版本升級(jí)時(shí)翁逞,linux kernel 需要升級(jí)對(duì)應(yīng)的日志驅(qū)動(dòng),因此在后續(xù)的版本中就有了 logd 進(jìn)程溉仑。

二挖函、logd 進(jìn)程詳解

2.1 logd 進(jìn)程框架

Android 日志系統(tǒng)分析(一):概述 一文中,總結(jié)了整個(gè)日志讀寫的主要流程浊竟,因此對(duì)于 logd 進(jìn)程是如何同外界溝通進(jìn)而讀寫日志的過程不再贅述怨喘,而著重于 logd 本身的一些知識(shí)點(diǎn)津畸,這里先看一下 logd 的系統(tǒng)框圖:

圖片來源于參考 [1]

知識(shí)點(diǎn):

logd 是日志系統(tǒng)的核心進(jìn)程,由 init 啟動(dòng)必怜,是屬于守護(hù)進(jìn)程常駐后臺(tái)
logd 維護(hù)各個(gè)日志節(jié)點(diǎn)緩存隊(duì)列肉拓,提供 socket 接口進(jìn)行讀、寫梳庆、控制功能
logd 進(jìn)程啟動(dòng)后暖途,分別啟動(dòng) LogReader、LogListener膏执、CommandListener 三個(gè)線程丧肴,監(jiān)聽并處理來自三個(gè) socket 的消息。在收到消息后胧后,會(huì)通過 LogBuffer 類保存日志到對(duì)應(yīng)的 RAM buffer
LogAudit 模塊用于接收 Kernel selinux 信息芋浮,即可以在用戶空間打印 selinux 日志信息
LogKlog 用于接收 kernel 日志信息,通過設(shè)置 property 壳快,可以通過 logcat 命令讀取內(nèi)核日志
LogStatistics 是日志統(tǒng)計(jì)模塊纸巷,默認(rèn)開啟統(tǒng)計(jì)數(shù)據(jù)較少,僅能以 pid/uid 緯度統(tǒng)計(jì)打印日志的數(shù)量眶痰。如果設(shè)置了 logd.statistic = true 瘤旨。會(huì)打印更多緯度的統(tǒng)計(jì)信息,包括哪些 pid/uid/tid/TAG 日志量比較大竖伯,可用于日志裁剪相關(guān)

2.2 logd 啟動(dòng)流程

圖片來源于參考 [1]

main 函數(shù)中存哲,會(huì)打開 /dev/kmsg 來讀取內(nèi)核日志,通過 LogKlog 來進(jìn)行存儲(chǔ)七婴;若是配置了 ro.logd.kernel 屬性祟偷,則打開 /proc/kmsg 讀取內(nèi)核日志;

2.3 logd.rc 解析

logd 作為 Native Service 打厘,系統(tǒng)啟動(dòng)時(shí)會(huì)讀取 init.rc 腳本去啟動(dòng)修肠,它的相關(guān)屬性被定義在 logd.rc 文件中:

service logd /system/bin/logd                                                         
    socket logd stream 0666 logd logd
    socket logdr seqpacket 0666 logd logd
    socket logdw dgram+passcred 0222 logd logd
    file /proc/kmsg r
    file /dev/kmsg w
    user logd
    group logd system package_info readproc
    writepid /dev/cpuset/system-background/tasks

service logd-reinit /system/bin/logd --reinit
    oneshot
    disabled
    user logd
    group logd
    writepid /dev/cpuset/system-background/tasks

......

這里主要分為兩部分:啟動(dòng) logd 服務(wù)啟動(dòng) logd-reinit 服務(wù) (在Android 10 上添加了 logd-auditctl 服務(wù),目的是為了限制 selinux denia打印日志為5秒一次)户盯;先來看一下 啟動(dòng) logd 服務(wù) 的同時(shí)做了些什么:

① 創(chuàng)建 logd嵌施、logdr、logdw 這三個(gè) socket 為后面的通信做準(zhǔn)備
logdw 定義為 dgram 類型的 socket 莽鸭,類似與 UDP類型的 Socket 吗伤,這么做的原因是考慮到性能問題,在多個(gè)進(jìn)程同時(shí)寫日志的情況下硫眨,write 函數(shù)寫入到 socketbuffer 中即可返回足淆,這樣不會(huì) block 業(yè)務(wù)邏輯太長時(shí)間。如果是 TCP 類型的 Socket ,客戶端需要等到 TCP 收到 ACK 響應(yīng)才能返回缸浦,這樣就會(huì)過多的消耗性能和資源夕冲;

啟動(dòng) logd-reinit 服務(wù):

這個(gè)服務(wù)的主要作用是重新初始化 logd 的 LogBuffer,在配置中 oneshot 表示開機(jī)只啟動(dòng)一次裂逐。在上面的 main.cpp 中的 main 函數(shù)內(nèi)歹鱼,logd 在啟動(dòng)后,會(huì)創(chuàng)建一個(gè)線程 reinit_thread_start () 卜高,當(dāng) logd-reinit 傳入?yún)?shù) reinit 后弥姻,進(jìn)行功能執(zhí)行:

① 如果 reinit 啟動(dòng)后,并且 /deg/kmsg 打開成功掺涛,把 logd.daemon: renit 寫入 kmsg
② 重新初始化各個(gè) log buffer 的大小庭敦,以及其他參數(shù)的初始化,但不會(huì)重新生成 LogBuffer 對(duì)象

main.cpp##main

int main(int argc, char* argv[]) {

    ......

    // 啟動(dòng) Reinit線程薪缆,當(dāng)logd-reinit傳入?yún)?shù)reinit時(shí)秧廉,進(jìn)行調(diào)用,reinit開機(jī)只啟動(dòng)一次

    sem_init(&reinit, 0, 0);
    sem_init(&uidName, 0, 0);
    sem_init(&sem_name, 0, 1);
    pthread_attr_t attr;
    if (!pthread_attr_init(&attr)) {
        struct sched_param param;

        memset(&param, 0, sizeof(param));
        pthread_attr_setschedparam(&attr, &param);
        pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
        if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
            pthread_t thread;
            reinit_running = true;
            if (pthread_create(&thread, &attr, reinit_thread_start, nullptr)) {
                reinit_running = false;
            }
        }
        pthread_attr_destroy(&attr);
    }

    ......

    exit(0);
}

main.cpp#reinit_thread_start()

 
static void* reinit_thread_start(void* /*obj*/) {
    prctl(PR_SET_NAME, "logd.daemon");
 
    while (reinit_running && !sem_wait(&reinit) && reinit_running) {
 
        if (fdDmesg >= 0) {
            static const char reinit_message[] = { KMSG_PRIORITY(LOG_INFO),
                     'l','o','g','d','.','d','a','e','m','o','n',':',' ','r','e','i','n','i','t','\n' };
            write(fdDmesg, reinit_message, sizeof(reinit_message));
        }
 
    
        //重新初始化各個(gè)log buffer的大小拣帽,以及其他參數(shù)的初始化疼电,但不會(huì)重新生成LogBuffer對(duì)象
        if (logBuf) {
            logBuf->init();
            logBuf->initPrune(nullptr);
        }
        android::ReReadEventLogTags();
    }
 
    return nullptr;
}

參考

[ 1 ] 深入理解安卓日志系統(tǒng)(logcat / liblog / logd)
[ 2 ] Android10.0 日志系統(tǒng)分析(二)-logd、logcat架構(gòu)分析及日志系統(tǒng)初始化

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末减拭,一起剝皮案震驚了整個(gè)濱河市蔽豺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拧粪,老刑警劉巖修陡,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異可霎,居然都是意外死亡魄鸦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門啥纸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來号杏,“玉大人婴氮,你說我怎么就攤上這事斯棒。” “怎么了主经?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵荣暮,是天一觀的道長。 經(jīng)常有香客問我罩驻,道長穗酥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮砾跃,結(jié)果婚禮上骏啰,老公的妹妹穿的比我還像新娘。我一直安慰自己抽高,他們只是感情好判耕,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翘骂,像睡著了一般壁熄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碳竟,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天草丧,我揣著相機(jī)與錄音,去河邊找鬼莹桅。 笑死昌执,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诈泼。 我是一名探鬼主播仙蚜,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼厂汗!你這毒婦竟也來了委粉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤娶桦,失蹤者是張志新(化名)和其女友劉穎贾节,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衷畦,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡栗涂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了祈争。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斤程。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖菩混,靈堂內(nèi)的尸體忽然破棺而出忿墅,到底是詐尸還是另有隱情,我是刑警寧澤沮峡,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布疚脐,位于F島的核電站,受9級(jí)特大地震影響邢疙,放射性物質(zhì)發(fā)生泄漏棍弄。R本人自食惡果不足惜望薄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呼畸。 院中可真熱鬧痕支,春花似錦、人聲如沸蛮原。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞬痘。三九已至故慈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間框全,已是汗流浹背察绷。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留津辩,地道東北人拆撼。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像喘沿,于是被迫代替她去往敵國和親闸度。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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