android log

一 架构

android log_第1张图片

1 应用层api:

  在应用层,安卓系统封装了日志系统的Java接口,Log.java, Rlog.java, Slog.java EventLog.java。应用开发者比较熟悉Log.java,系统开发者对 Rlog,Slog,EventLog, 接口会比较熟悉。这几个接口作用类似,都是写入日志,差别是写入logd的日志节点不同。

  Java 接口封装在android.jar 中,作为SDK提供给开发者使用,在运行时通过libandroid_runtime.so 中的JNI 接口调用系统native api。

  对于C/C++ 的开发者,可以直接使用 log.h 中提供的ALOGD 等系列API 在native程序中打印日志。

2 native api

  日志系统的核心服务的logd,一个native守护进程。为了访问logd提供的api,安卓系统封装了一层liblog,便于应用层方便访问logd 的socket api

3 核心logd

  logd是日志系统的核心,开机时由init进程启动,在系统后台持续运行。logd维护了一个RAM buffer, 作为日志的缓存。各个进程的日志都会写入这个RAM buffer。如果日志写入过多,会删除最老的日志,删除算法类似于ring buffer的逻辑。

  logd 对外维护了3个socket api:

  • dev/socket/logd 传输控制指令

  • dev/socket/logw 写日志

  • dev/socket/logr 读日志

4 native bin

在native 层,安卓提供了一个/system/bin/logcat native 命令行程序,作为一个统一的客户端通信进程。开发者通过 adb logcat 相关指令可以读日志或者给logd发送指令。

二 日志流程

android log_第2张图片

详细过程如下:

1 客户端进程通过SDK 中提供的接口写入日志;

Log.d(TAG, “Message body”);

2 java代码通过JNI 调用liblog;

  android_util_Log_println_native

3 liblog封装了logd访问的socket接口;liblog通过socket通信,完成客户端日志写入logd;

  __android_log_buf_write
write_to_log
__write_to_log_init
__write_to_log_daemon
write_transport_for_each
 logdWrite.write
logdWrite

4 logd中维护main / system / crash 等各个log buffer,各个模块的日志缓存在此buffer中。

LogListener::onDataAvailable
LogBuffer::log
=>     stats.add(elem);
         maybePrune(elem->getLogId());

三 日志总结

1 跨进程通信的消耗:日志信息通过socket 发送到 logd;

2 内存消耗:logd中要维护对应的buffer。RAM 资源的消耗;

3 CPU 资源的消耗:logd中ring buffer会经常进行pruneLogs 操作,删减日志,耗费CPU资源。

4 IO消耗:在某些产品上,log会在后台进程/线程中写入文件,这些更会大量消耗IO,导致应用或者整机卡顿,产生性能问题。


 

你可能感兴趣的:(Android开发,android)