2.2.3 Android日志與logd交互過程
2.2.3.1 Android日志傳遞給logd
Android app層或framework層,通過調用Log/Slog/Rlog中d方法打印日志,通過JNI會調用到native層android_util_Log_println_native接口,具體見下圖內容。
接下來具體調用流程如下:
/XXX/system/logging/liblog/logger_write.cpp
__android_log_buf_write
-->__android_log_write_log_message
-- >get_logger_function()
-- >__android_log_logd_logger
-- >write_to_log
-- >LogdWrite
最終寫到 “/dev/socket/logdw”中,此時logd中的LogListener會監測到存在log信息需要寫入,待log保存到buffer中后,再通知LogReader將新保存的log傳遞給logcat等
socket信息如下
// Note that it is safe to call connect() multiple times on DGRAM Unix domain sockets, so this
// function is used to reconnect to logd without requiring a new socket.
static void LogdConnect(int sock) {
sockaddr_un un = {};
un.sun_family = AF_UNIX;
strcpy(un.sun_path, "/dev/socket/logdw");
TEMP_FAILURE_RETRY(connect(sock, reinterpret_cast(&un), sizeof(sockaddr_un)));
}
2.2.3.2 logd中的log保存過程
具體代碼路徑如/XXX/system/logging/logd/main.cpp,從文件的main函數中可以看到,logd執行過程中創建了LogBuffer,LogReader,LogListener和CommandListener四個對象,上文有詳細介紹,本節暫且不予解釋,詳情見2.3.1.2節內容。
接下來創建LogListener的對象,開啟一個線程“logd.writer”監聽數據,具體過程見下圖。
HandleData()
-->logbuf_->Log
新建一個LogBufferElement對象,實現log的保存.
2.2.3.3 logcat獲取logd日志
/XXX/system/logging/logcat/logcat.cpp
int main(int argc, char** argv) {
Logcat logcat;
return logcat.Run(argc, argv);
}
具體的logcat命令參數解析在Run函數中執行。
android_logger_list_read接下來的調用過程如下:
android_logger_list_read
-->LogdRead //打開logdr,并通過socket獲取log
-->logdOpen
logd的main函數中有開啟LogReader監聽
// LogReader listens on /dev/socket/logdr. When a client
// connects, log entries in the LogBuffer are written to the client.
LogReader* reader = new LogReader(log_buffer, &reader_list);
if (reader->startListener()) {
return EXIT_FAILURE;
}
LogReader繼承自SocketListener,如果socket監聽到數據,則執行onDataAvailable函數進行處理。
最后加入read_list_中:
最終通過ProcessBuffer輸出日志內容,打印log_msg日志到界面或者fd文件中。具體內容包括:處理日志buffer內容、回滾打印日志內容等。
-
Android
+關注
關注
12文章
3923瀏覽量
127130 -
代碼
+關注
關注
30文章
4744瀏覽量
68345 -
日志
+關注
關注
0文章
138瀏覽量
10632
發布評論請先 登錄
相關推薦
評論