目录

0. 前言

1. Native的Log写过程解析

2. Socket的另一端Logd


0. 前言

Android中 logd 详解_私房菜的博客-CSDN博客_logd

里面讲了Java层Logd的框架和代码和Native的一些代码

1. Native的Log写过程解析

普通LogI会调用到ALOG  -->位于logger_write.cpp

__android_log_print  --> __android_log_logd_logger --> write_to_log

调用__android_log_logd_logger:

void __android_log_logd_logger(const struct __android_log_message* log_message) {int buffer_id = log_message->buffer_id == LOG_ID_DEFAULT ? LOG_ID_MAIN : log_message->buffer_id;struct iovec vec[3];vec[0].iov_base =const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(&log_message->priority));vec[0].iov_len = 1;vec[1].iov_base = const_cast<void*>(static_cast<const void*>(log_message->tag));vec[1].iov_len = strlen(log_message->tag) + 1;vec[2].iov_base = const_cast<void*>(static_cast<const void*>(log_message->message));vec[2].iov_len = strlen(log_message->message) + 1;write_to_log(static_cast<log_id_t>(buffer_id), vec, 3);
}

调用write_to_log做了一些参数检查,最终又调到了LogdWrite

static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) {int ret;struct timespec ts;
...clock_gettime(CLOCK_REALTIME, &ts);if (log_id == LOG_ID_SECURITY)if (vec[0].iov_len < 4) ret = check_log_uid_permissions();if (!__android_log_security()) if (logger_ratelimit(log_id, ts) == LOGGER_RATELIMIT_SHIELD)
...ret = LogdWrite(log_id, &ts, vec, nr);PmsgWrite(log_id, &ts, vec, nr);return ret;
}

LogdWrite是往logd的socket中/dev/socket/logdw 这节点中写

int LogdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr) {LogdSocket& logd_socket = logId == LOG_ID_SECURITY ? LogdSocket::BlockingSocket() : LogdSocket::NonBlockingSocket();if (__android_log_is_loggable_len(ANDROID_LOG_INFO, "liblog", strlen("liblog"))) {ret = TEMP_FAILURE_RETRY(writev(logd_socket.sock(), newVec, 2));if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {if (WriteDropLog(newVec, 2) != static_cast<int>(iov_length(newVec, 2)))atomic_fetch_add_explicit(&dropped, snapshot, memory_order_relaxed);}}if (RedirectLogWrite(logId)) {ret = WriteAppLog(logId, newVec, i);}ret = TEMP_FAILURE_RETRY(writev(logd_socket.sock(), newVec, i));if (ret < 0 && errno != EAGAIN) {logd_socket.Reconnect();ret = TEMP_FAILURE_RETRY(writev(logd_socket.sock(), newVec, i));}
}

PmsgWrite

是往/dev/pmsg0节点中写, 这个节点是pstore 内核日志的通路

2. Socket的另一端Logd

system\logging\logd\main.cpp中规定了logd初始化的组件

SerializedLogBuffer TODO后面看看 socket on Android

LogListener->StartListener

int LogListener::GetLogSocket() {static const char socketName[] = "logdw";int sock = android_get_control_socket(socketName);if (sock < 0) {  // logd started up in init.shsock = socket_local_server(socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM);int on = 1;if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {return -1;}}return sock;
}

LogListener开始监听

void LogListener::HandleData() {// + 1 to ensure null terminator if MAX_PAYLOAD buffer is received__attribute__((uninitialized)) charbuffer[sizeof(android_log_header_t) + LOGGER_ENTRY_MAX_PAYLOAD + 1];struct iovec iov = {buffer, sizeof(buffer) - 1};alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))];struct msghdr hdr = {nullptr, 0, &iov, 1, control, sizeof(control), 0,};// To clear the entire buffer is secure/safe, but this contributes to 1.68%// overhead under logging load. We are safe because we check counts, but// still need to clear null terminator// memset(buffer, 0, sizeof(buffer));ssize_t n = recvmsg(socket_, &hdr, 0);
...logbuf_->Log(logId, header->realtime, cred->uid, cred->pid, header->tid, msg,((size_t)n <= UINT16_MAX) ? (uint16_t)n : UINT16_MAX, secontext, secontext_len);
}

logbuf->log是刷写log的函数。

LogBuffer这个类可以研究一下,log的循环使用是怎么实现的?

3、Logcat

#system/core/logcat/logcat.cpp

main函数中直接调用logcat run,最终调用到函数

android_logger_list_read(logger_list.get(), &log_msg)

也是通过socket(logdr)来传递信息的

Android Log日志系统相关推荐

  1. 客户端log日志系统

    背景 我们在开发过程中出现了个别bug,而我们往往很难定位到问题所在,这个不仅仅局限于移动端,只是移动端不容易定位问题.我们常见的实现方式可能是, 1. 创建一个带队列的线程. 2. 把要上报的数据抛 ...

  2. FFmpeg源码分析:log日志系统

    FFmpeg的封装专有的log日志系统,支持设置日志等级log level,也支持日志回调log callback,方便开发者调试与排查问题. 1.日志等级 log日志位于libavutil模块,lo ...

  3. ANDROID L日志系统——JAVAAPI与LIBLOG

    在 Android L(包含Android L)之后,Andoird使用了全新的日志系统,也非之前结合Kernel Ring Buffer的方式来存储,读写Log.替而代之是使用新的日志机制Logd. ...

  4. Android L日志系统1——logd

    在介绍完Android M之前的日志系统的实现之后,我们现在来看看现在最新的Android L的日志机制.Android L与之前版本最大的变化,就是日志保存的位置由Kernel的Ringer Buf ...

  5. Android动态日志系统Holmes

    背景 美团点评公司是全球领先的一站式生活服务平台,为6亿多消费者和超过450万优质商户提供连接线上线下的电子商务网络.美团点评的业务覆盖了超过200个丰富品类和2800个城区县网络,在餐饮.外卖.酒店 ...

  6. DPDK 18 log日志系统使用

    概述: DPDK 日志系统分为1-8个等级,在lib/librte_eal/common/include/rte_log.h文件中定义,每个DPDK模块都可以定义一个预设日志输出等级,只有日志输出语句 ...

  7. C++ 实现简易 log 日志系统

    1.log日志的作用 在软件开发周期中,不管是前台还是后台,系统一般会采用一个持久化的日志系统来记录运行情况. 在代码中嵌入log代码信息,主要记录下列信息: (1)记录系统运行异常信息. (2)记录 ...

  8. LVGL misc log日志系统(lv_log.h)

    更多源码分析请访问:LVGL 源码分析大全 LVGL misc log日志系统目录 1.概述 2.API 2.1.日志级别 2.2.日志输出宏 3.使用方法 1.概述 LVGL的日志系统实现比较简单, ...

  9. C++实现log日志系统

    1.log日志的作用 在软件开发周期中,不管是前台还是后台,系统一般会采用一个持久化的日志系统来记录运行情况. 在代码中嵌入log代码信息,主要记录下列信息: (1)记录系统运行异常信息. (2)记录 ...

最新文章

  1. REST API安全认证研究!
  2. 用python画动态樱花_利用python画一棵漂亮的樱花树,turtle画图代码大全,此处感谢知乎大佬小白...
  3. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
  4. linux minicom usb串口
  5. Azure pipeline 配置根据条件执行脚本
  6. 经典排序算法-MFC实现之2:问题
  7. c语言 程序统计注释比例,C语言统计单词数量程序 超详解
  8. 以向量和矩阵的视角抽象万物
  9. NodeJS连接MySQL
  10. 机械设计课程设计含设计说明书
  11. 解决hive报错FAILED: SemanticException Cartesian products are disabled for safety的问题
  12. 微信小程序学习2022.11.22
  13. 宋宝华:slab在内核内存管理和用户态Memcached的双重存在
  14. Linux 下使用Trickle限制下载/上传带宽
  15. 电容笔和触控笔哪个好?平板电脑好用电容笔推荐
  16. 海信电视linux安装软件,海信电视无法安装软件怎么办,两种最新方法完美解决!...
  17. python实现面部特效_用Python获取摄像头并实时控制人脸的实现示例
  18. linux sctp 模块,Linux Kernel SCTP模块多个安全漏洞
  19. Python根据IP查找所在地理位置与运营商
  20. 电脑msvcp140.dll丢失的解决方法

热门文章

  1. 构造函数可以是虚函数吗?不看看你就亏大了
  2. Fluent案例1- 空气流经障碍物-3D模拟
  3. 常用IDE快捷键整理
  4. Unity学习笔记 使用DMM(Distance-Independent Millimeter)思想设计VRAR中的UI
  5. 《图解HTTP》第七章个人学习
  6. 如何利用PS将照片的灰色背景变为白色
  7. 开学返校学生党耳机推荐,连接稳定的无线蓝牙耳机分享
  8. 如何转行游戏行业及我眼中的理想游戏开发团队
  9. 前端不止:Web内容的无障碍性
  10. 怎么在微信接收邮箱信息