Android Log日志系统
目录
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日志系统相关推荐
- 客户端log日志系统
背景 我们在开发过程中出现了个别bug,而我们往往很难定位到问题所在,这个不仅仅局限于移动端,只是移动端不容易定位问题.我们常见的实现方式可能是, 1. 创建一个带队列的线程. 2. 把要上报的数据抛 ...
- FFmpeg源码分析:log日志系统
FFmpeg的封装专有的log日志系统,支持设置日志等级log level,也支持日志回调log callback,方便开发者调试与排查问题. 1.日志等级 log日志位于libavutil模块,lo ...
- ANDROID L日志系统——JAVAAPI与LIBLOG
在 Android L(包含Android L)之后,Andoird使用了全新的日志系统,也非之前结合Kernel Ring Buffer的方式来存储,读写Log.替而代之是使用新的日志机制Logd. ...
- Android L日志系统1——logd
在介绍完Android M之前的日志系统的实现之后,我们现在来看看现在最新的Android L的日志机制.Android L与之前版本最大的变化,就是日志保存的位置由Kernel的Ringer Buf ...
- Android动态日志系统Holmes
背景 美团点评公司是全球领先的一站式生活服务平台,为6亿多消费者和超过450万优质商户提供连接线上线下的电子商务网络.美团点评的业务覆盖了超过200个丰富品类和2800个城区县网络,在餐饮.外卖.酒店 ...
- DPDK 18 log日志系统使用
概述: DPDK 日志系统分为1-8个等级,在lib/librte_eal/common/include/rte_log.h文件中定义,每个DPDK模块都可以定义一个预设日志输出等级,只有日志输出语句 ...
- C++ 实现简易 log 日志系统
1.log日志的作用 在软件开发周期中,不管是前台还是后台,系统一般会采用一个持久化的日志系统来记录运行情况. 在代码中嵌入log代码信息,主要记录下列信息: (1)记录系统运行异常信息. (2)记录 ...
- LVGL misc log日志系统(lv_log.h)
更多源码分析请访问:LVGL 源码分析大全 LVGL misc log日志系统目录 1.概述 2.API 2.1.日志级别 2.2.日志输出宏 3.使用方法 1.概述 LVGL的日志系统实现比较简单, ...
- C++实现log日志系统
1.log日志的作用 在软件开发周期中,不管是前台还是后台,系统一般会采用一个持久化的日志系统来记录运行情况. 在代码中嵌入log代码信息,主要记录下列信息: (1)记录系统运行异常信息. (2)记录 ...
最新文章
- REST API安全认证研究!
- 用python画动态樱花_利用python画一棵漂亮的樱花树,turtle画图代码大全,此处感谢知乎大佬小白...
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
- linux minicom usb串口
- Azure pipeline 配置根据条件执行脚本
- 经典排序算法-MFC实现之2:问题
- c语言 程序统计注释比例,C语言统计单词数量程序 超详解
- 以向量和矩阵的视角抽象万物
- NodeJS连接MySQL
- 机械设计课程设计含设计说明书
- 解决hive报错FAILED: SemanticException Cartesian products are disabled for safety的问题
- 微信小程序学习2022.11.22
- 宋宝华:slab在内核内存管理和用户态Memcached的双重存在
- Linux 下使用Trickle限制下载/上传带宽
- 电容笔和触控笔哪个好?平板电脑好用电容笔推荐
- 海信电视linux安装软件,海信电视无法安装软件怎么办,两种最新方法完美解决!...
- python实现面部特效_用Python获取摄像头并实时控制人脸的实现示例
- linux sctp 模块,Linux Kernel SCTP模块多个安全漏洞
- Python根据IP查找所在地理位置与运营商
- 电脑msvcp140.dll丢失的解决方法