1-log 分类
Log 分类:1-UI(java)log, 2-C/C++ log, 3-kernel log
Log的等级有Verbose,Debug,Info,Warn,Error
Java log
import android.util.Log
,在需要打印Log的地方执行Log.v,Log.d,Log.i,Log.w,Log.e.
C/C++ log
#include
ALOGV,ALOGD,ALOGI,ALOGW,ALOGE。
kernel log
示例部分:
TAG=”MyActivity”;
运行时开启log: 在终端输入:setprop log.tag.MyActivity DEBUG
运行时关闭log: 在终端输入:setprop log.tag.MyActivity INFO
2-log 原理
---> Android 的log,从操作系统分层上来讲,可以分为“Kernel Log”和“User Log”
---> 所谓“Kernel Log”就是内核打印的log。内核里调用printk等接口请求输出kernel log。
kernel log最后会被打印到/dev/kmsg文件上。可以通过dmesg查看到
---> 所谓“User Log”分为2部分。
---->1是Linux的标准输出设备中打印的log(stderr/stdout).
---->2是android特有的log流程。如通过android.util.Log类打印的log,eventslog, ALOG() native层log打印.
2.1-java的log流程
"frameworks/base/core/java/android/util/Log.java"
"/frameworks/base/core/jni/android_util_Log.cpp"-----> println_native
"system/core/liblog/logger_write.c---->__android_log_buf_write
Log.d()--->
-->public static int d(String tag, String msg) [Log.java]
-->android_util_Log_println_native [android_util_Log.cpp]
--->__android_log_buf_write
2.2-C/C++: ALOG / ALOGE / ALOGD
/system/core/liblog/logger_write.c
ALOGD/ALOGE
---> ALOG
---> LOG_PRI
---> android_printLog
---> __android_log_print()
----->__android_log_buf_write()
"/system/core/liblog" 模块编译生成 "/system/lib(64)/liblog.so".
srw-rw-rw- 1 logd logd 0 1970-01-01 00:00 logd
srw-rw-rw- 1 logd logd 0 1970-01-01 00:00 logdr
s-w--w--w- 1 logd logd 0 1970-01-01 00:00 logdw
system/core/logd/logd.rc
service logd /system/bin/logd
socket logd stream 0666 logd logd
socket logdr seqpacket 0666 logd logd
socket logdw dgram 0222 logd logd
group root system readproc
writepid /dev/cpuset/system-background/tasks
logd 模块源码在 /system/core/logd/ 编译的目标是linux可执行文件 "/system/bin/logd"
logcat模块源码在 "/system/core/logcat", 编译目标为 "/system/bin/logcat"
logcatd模块源码在 "/system/core/logcat", 编译目标为 "/system/bin/logcatd"
LOCAL_PATH := $(call my-dir)
logcatLibs := liblog libbase libcutils libpcrecpp
include $(CLEAR_VARS)
LOCAL_MODULE := logcat
LOCAL_SRC_FILES := logcat_main.cpp event.logtags
LOCAL_SHARED_LIBRARIES := liblogcat $(logcatLibs)
LOCAL_CFLAGS := -Werror
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := logcatd
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := logcatd_main.cpp event.logtags
LOCAL_SHARED_LIBRARIES := liblogcat $(logcatLibs)
LOCAL_CFLAGS := -Werror
include $(BUILD_EXECUTABLE)
2.3-kernel log
通过设置" adb shell setprop logd.kernel true" 可以让logd去抓取 Kernel Log
实现原理其实是把 "/proc/kmsg" 和 "/dev/kmsg" 文件当作socket 文件来使用
/proc/kmsg -->实时监控
/dev/kmsg---> 一次读取
/system/core/logd/main.cpp
int main(int argc, char *argv[]) {
int fdPmesg = -1;
bool klogd = property_get_bool("logd.kernel", ------>setprop logd.kernel true 起作用
BOOL_DEFAULT_TRUE |
BOOL_DEFAULT_FLAG_PERSIST |
BOOL_DEFAULT_FLAG_ENG |
BOOL_DEFAULT_FLAG_SVELTE);
if (klogd) {
fdPmesg = open("/proc/kmsg", O_RDONLY | O_NDELAY); "/proc/kmsg"读kernel log
}
}
3-实现的logcat 系统
采用了locatd 进行实现,实际是service ,在user版本是selinux 权限permissive=1, 开启logd.kernel=true
init.target.rc
service logcatxxx /vendor/bin/init.xxx.logcat.sh
class main
user root
group root
init.xxx.logcat.sh
#!/system/bin/sh
while :
do
logcatd -L -b default,kernel -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n 60
done
备注:
根据实践文档要在user 版本把,logcatd build 到系统
PRODUCT_PACKAGES += logcatd
setprop persist.logd.logpersisted logcatd
chmod 766 /data/misc/logd/
实践:
C/C++ 添加log
使用logcatd打印系统日志
REF:
原文参考连接