1. 程式人生 > >android logd 原理及實現

android logd 原理及實現

一、logd介紹

logd 是Android L版本提出來的概念,其作用是儲存Android執行期間的log(日誌)。在Android L之前,log由kernel的ring buffer 儲存,在Android L之後,log儲存在使用者空間。

1)  logd程序啟動

系統啟動到init函式時會解析init.rc檔案,啟動logd程序和logd-reinit(重新初始化logd) 程序,init.rc檔案中的相關內容如下:

onload_persist_props_action

     load_persist_props

     start logd             

     start logd-reinit

在system/core/logd中的logd.rc檔案中,啟動logdservice和logd-reinit service,具體內容如下:

service logd /system/bin/logd                  

    socket logd stream 0666logd logd

    socket logdr seqpacket0666 logd logd

    socket logdw dgram 0222logd logd

    group root system readproc

    writepid/dev/cpuset/system-background/tasks

service logd-reinit /system/bin/logd --reinit

    oneshot

    disabled

    writepid/dev/cpuset/system-background/tasks

注:logd-reinit只會執行一次,logd和logd-reinit都會呼叫system/core/logd/main.cpp中的main函式,但logd-reinit通過netlink給logd程序傳送reinit命令後就會退出。

2)  logd 實現log管理

主要原理是:上層應用(Android層)通過呼叫Log/Slog/Rlog中的v/d方法列印log,最終log會通過netlink傳遞給logd,logd會將log儲存在記憶體中(由C++中的list容器管理,後續會介紹),logcat等log獲取工具同樣通過netlink方式從logd獲取log。

二、logd實現流程

本文主要介紹load側的實現,對於Androidlog如何傳遞給logd,只做簡要介紹。

1.      Android層往logd寫log

Android層呼叫Log/Slog/Rlog中的v/d方法列印log,最終會呼叫到

system/core/liblog/logger_write.c 中的__android_log_buf_write函式,呼叫流程如下:

__android_log_buf_write

->write_to_log

           ->__write_to_log_init

                    ->__write_to_log_initialize

                             ->logdOpen

                    ->__write_to_log_daemon

                             ->logdWrite

檔案最終寫到 “/dev/socket/logdw”中,此時logd中的LogListener會監測到有log需寫入,待log儲存後,會通知LogReader將新儲存的log傳遞給logcat等。

2.      Logd log儲存機制

在system/core/lodgd/main.cpp檔案的main函式中,建立了LogBuffer,LogReader,LogListener和CommandListener四個物件,

LogBuffer用於管理log;

LogReader用於將log傳遞給logcat;

LogListener用於監聽是否有log寫入logd;

CommandListener用於監聽是否有命令傳送給logd。

接下來介紹log的儲存流程:

1)  建立LogBuffer物件,在classLogBuffer類中,定義了一個list容器,儲存了指向LogBufferElement物件的指標,建立LogBuffer物件時在其建構函式中會呼叫LogBuffer::init()函式初始化各log域(如main/system/kernel/crash等)的大小。

2)  建立LogListener物件並開始監聽

    LogListener *swl = newLogListener(logBuf, reader);

   // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value

    if(swl->startListener(600)) {

        exit(1);

          }

3)  在startListener函式中建立執行緒,執行緒註冊函式為SocketListener::threadStart;

4)  執行runListener函式,如果socket監聽到資料,則執行onDataAvailable函式進行處理;

5)  呼叫logbuf->log(LogBuffer::log),這個函式很重要,新建一個LogBufferElement物件(用於儲存log),呼叫mLogElements.insert將LogBufferElement加入list容器,實現log的儲存。

3.       

三、Logd-reinit 程序

Logd-reinit 程序在啟動時,會給logd程序傳送reinit命令,logd在收到命令後,會重新初始化LogBuffer。

在system/core/lodgd/main.cpp檔案的main函式中會建立一個執行緒用於監測是否有reinit請求

if (pthread_create(&thread, &attr,reinit_thread_start, NULL))

在reinit_thread_start函式中,會重新初始化各個log區的大小,以及其他引數的初始化,但不會重新生成LogBuffer物件。相關程式碼如下:

//Anything that reads persist.<property>

if(logBuf) {

    logBuf->init();                     

    logBuf->initPrune(NULL);

}

四、Logd log 獲取

可通過logcat工具獲取logd log,logcat 相關程式碼所在路徑:system/core/logcat

執行adb logcat 即可檢視log

注:通過logcat獲取的log,並不完全是按照log分類來列印的,如在KERNEL log中可能存在MAIN log。

logcat實現的大部分函式都在logcat/logcat.cpp檔案中,其中__logcat函式是最重要的函式,其負責logcat 輸入引數的解析以及log的處理。

logcat 最終讀取log通過liblog/logd_reader.c 中的logdRead函式實現。此函式負責開啟/dev/logdr,並通過socket獲取log。

最近在使用logcat 獲取log時,存在log丟失的情況,不知大家是否有遇到過。

調查發現,當同時啟動6個執行緒分別獲取main/kernel/system/crash/events等log時,由於啟動的執行緒太多(即多個socket 與server 連線),導致有log丟失。

相關推薦

android logd 原理實現

一、logd介紹 logd 是Android L版本提出來的概念,其作用是儲存Android執行期間的log(日誌)。在Android L之前,log由kernel的ring buffer 儲存,在Android L之後,log儲存在使用者空間。 1)  logd程序啟動

Android AOP介紹實現原理

深入理解Android之AOP 一、閒談AOP 大家都知道OOP,即ObjectOriented Programming,面向物件程式設計。而本文要介紹的是AOP。AOP是Aspect Oriented Programming的縮寫,中譯文為面向切向程式

Android影象處理-畫素化的原理實現

部落格地址:xiazdong.github.io 馬賽克演算法首先需要確定馬賽克單元的大小,即小方塊的大小。馬賽克圖的每個馬賽克單元都是純色的塊,其取值一般為原圖中該塊區域的顏色的均值(這裡的實現為了簡化,取了原圖中該區域左上角的畫素)。馬賽克單元的大小決定了最後的馬賽克圖的樣子,當值為1時,就是原圖。

Android頭部伸縮元件的原理實現(上)

前言我們的App最近上了一個新Feature,名叫Speed Dial,類似於視訊中這樣,Header和ViewPager裡面的Page一起滾動,支援下拉重新整理,有的頁面還要支援上拉重新整理,有的頁面還有Bar固定在頁面底部。其實陌陌、大眾點評、馬蜂窩現在都有類似的功能,但可能我們的更復雜一些。ViewPa

關於base64編碼的原理實現

一個 replace 編碼範圍 func nco 都是 style bit 如果 我們的圖片大部分都是可以轉換成base64編碼的data:image。 這個在將canvas保存為img的時候尤其有用。雖然除ie外,大部分現代瀏覽器都已經支持原生的基於base64的enco

java設計模式singleton原理實現

最新 不必要 -- 不同 適合 所有 引用 ati cnblogs 題外話:我要變強,要變強,變強,強。 1、 Singleton的應用場景以及為什麽要使用singleSingleton是一生只能有一個實例的對象。只能由singleton自身創建一個實例。外人是無法創建實例

決策樹原理實現

方式 -1 變化 log nbsp 導致 結點 以及 重要 1、決策樹原理 1.1、定義 分類決策樹模型是一種描述對實例進行分類的樹形結構。決策樹由結點和有向邊組成。結點有兩種類型:內部節點和葉節點,內部節點表示一個特征或屬性,葉節點表示一個類。

RPC原理實現

.get 版本 pcs 連接方式 正常 zookeepe list 接口 分布式計算 1 簡介 RPC 的主要功能目標是讓構建分布式計算(應用)更容易,在提供強大的遠程調用能力時不損失本地調用的語義簡潔性。為實現該目標,RPC 框架需提供一種透明調用機制讓使用者不必顯式的

SSO單點登錄原理實現

response dem nbsp boolean 配置文件 實現 有效 ucc ons 1.SSO分類   根據實現的域不同,可以把SSO分為同域SSO、同父域SSO、跨域SSO三種類型。 2.SSO實現原理 a.打開統一的登錄界面 b.登錄,同時向服務器寫入Cookie

線程池的原理實現

execute inter void date() 超過 緩沖 線程池大小 exceptio 調整 1、線程池簡介: 多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。 假設一個服務器完成一項任務所需時間為:T1

線程池原理實現

任務隊列 批量 not alt con 成了 代碼 pla extends 1、線程池簡介: 多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。 假設一個服務器完成一項任務所需時間為:T1

四.HashSet原理實現學習總結

throw map 所有 cti con name 保持 nts equal 在上一篇博文(HashMap原理及實現學習總結)詳細總結了HashMap的實現過程,對於HashSet而言,它是基於HashMap來實現的,底層采用HashMap來保存元素。所以如果對HashMa

五.HashTable原理實現學習總結

容量 區別 存儲 們的 如果 isn cte ash ref 有兩個類都提供了一個多種用途的hashTable機制,他們都可以將可以key和value結合起來構成鍵值對通過put(key,value)方法保存起來,然後通過get(key)方法獲取相對應的value值。一個是

CGLib動態代理原理實現

aop object col 子類 doc pos 輸出 intercept pub JDK實現動態代理需要實現類通過接口定義業務方法,對於沒有接口的類,如何實現動態代理呢,這就需要CGLib了。CGLib采用了非常底層的字節碼技術,其原理是通過字節碼技術為一個類創建子類,

sso簡單原理實現

登錄用戶 會話 例子 www 哪些 java類 pad adb 應對 轉自:http://www.cnblogs.com/ywlaker/ 一、單系統登錄機制 1、http無狀態協議   web應用采用browser/server架構,http作為通信協議。http是無

網站統計中的數據收集原理實現

fun 美的 置配 客戶 etc 分析 獲取 固定 open 網站統計中的數據收集原理及實現 網站數據統計分析工具是網站站長和運營人員經常使用的一種工具,比較常用的有谷歌分析、百度統計和騰訊分析等等。所有這些統計分析工具的第一步都是網站訪問數據的收集。目前主流的數據收

智能指針原理實現(1)- shared_ptr

red ++ 直接 初始 targe -- div urn 記錄 C++沒有內存回收機制,每次程序員new出來的對象需要手動delete,流程復雜時可能會漏掉delete,導致內存泄漏。於是C++引入智能指針,可用於動態資源管理,資源即對象的管理策略。 一、智能指針類別 智

智能指針原理實現(2)- unique_ptr

unique clas 結束 基礎 無法 body 智能指針 周期 文件 只允許基礎指針的一個所有者。 可以移到新所有者(具有移動語義),但不會復制或共享(即我們無法得到指向同一個對象的兩個unique_ptr)。 替換已棄用的 auto_ptr。 相較於 boost::s

分布式鎖原理實現方式

ack 常用 ima 個數 tar 刪除 不能 cap lock 本文轉自:http://www.hollischuang.com/archives/1716 目前幾乎很多大型網站及應用都是分布式部署的,分布式場景中的數據一致性問題一直是一個比較重要的

【數據結構】ArrayList原理實現學習總結(2)

!= 需要 但是 object count def 原理 arrays 位置 ArrayList是一個基於數組實現的鏈表(List),這一點可以從源碼中看出: transient Object[] elementData; // non-private to si