赞
踩
原文使用有道云笔记创作, 看这个: http://note.youdao.com/noteshare?id=82f88b1c82652b80c27d54aad55af035
```
引言
> Android 的log,从操作系统分层上来讲,可以分为“Kernel Log”和“User Log”(这是我个人引入的术语)。
> 所谓“Kernel Log”就是操作系统内核打印的log。内核里调用printk等接口请求输出kernel log。
kernel log最后会被打印到/dev/kmsg文件上。可以通过dmesg查看到
> 所谓“User Log”分为2部分。
一类是Linux的标准输出设备中打印的log(stderr/stdout).
另一类是android特有的log流程。如通过android.util.Log类打印的log,eventslog, ALOG() native层log打印.
他们都可以通过logcat看到.
本文基于Android N源码, 对Android的log机制做介绍.
```
先给出一张Android Log系统的总图
![image](https://note.youdao.com/yws/public/resource/61a8527040499b2a0ff58d2fe3aa7bf9/xmlnote/WEBRESOURCE201e2aad89277aeb65c08a26c9b32701/19289)
# 1 Android特有Log流程
```
// java
import android.util.Log;
Log.d("cwj", "test log");
```
==android.util.Log== 是在做Android开发中最常用的log输出手段.这里输出的log, 我们通过"adb logcat"或"adb shell logcat"命令获取.
**那么从"Log.d("cwj", "test log");" 到"logcat"之间到底发生了什么呢?**
```
// C/C++
#define LOG_TAG "fingerprintd"
ALOG(LOG_VERBOSE, LOG_TAG, "lockout\n");
ALOGE("Invalid callback object");
ALOGD("onAcquired(%d), duplicatedFingerId(%d)", 1, 2);
```
**对于Native Code中的 ALOG 等的log打印 到logcat之间, 又发生了什么呢?**
## 1.1 android.util.Log 和 android.util.writeEvent
### 1.1.1 android.util.Log
java类Log的源码在 "frameworks/base/core/java/android/util/Log.java"
Lod中的 Log.d() / Log.v() 等打印不级别的函数, 最终都走到 ==println_native()== native函数.
```
public static int v(String tag, String msg) {
return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);
}
public static int d(String tag, String msg) {
return println_native(LOG_ID_MAIN, DEBUG, tag, msg);
}
/** @hide */ public static native int println_native(int bufID,
int priority, String tag, String msg);
```
println_native 的实现在 "/frameworks/base/core/jni/android_util_Log.cpp"
```
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
...
{ "println_native", "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },
...
};
/*
* In class android.util.Log:
* public static native int println_native(int buffer, int priority, String tag, String msg)
*/
static jint android_util_Log_println_native(JNIEnv* env, jobject clazz,
jint bufID, jint priority, jstring tagObj, jstring msgObj)
{
const char* tag = NULL;
const char* msg = NULL;
if (msgObj == NULL) {
jniThrowNullPointerException(env, "println needs a message");
return -1;
}
if (bufID < 0 || bufID >= LOG_ID_MAX) {
jniThrowNullPointerException(env, "bad bufID");
return -1;
}
if (tagObj != NULL)
tag = env->GetStringUTFChars(tagObj, NULL);
msg = env->GetStringUTFChars(msgObj, NULL);
int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
if (tag != NULL)
env->ReleaseStringUTFChars(tagObj, tag);
env->ReleaseStringUTFChars(msgObj, msg);
return res;
}
```
println_native() 对应的jni方法是 ==android_util_Log_println_native()==.
android_util_Log_println_native()很简单,就是简单的Log级别检查后, 就调用 ==__android_log_buf_write()== 做进一步处理.
__android_log_buf_write() 的声明在 "/system/core/include/log/log.h":
```
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);
```
__android_log_buf_write() 的定义(实现)在 "/system/core/liblog".
发现liblog中有多个 __android_log_buf_write() 的实现:
```
logd_write.c
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
...
logd_write_kern.c
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
...
logger_write.c
LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
...
```
那么我们用到的到底是哪个呢? 具体分析在[1.3 /system/core/liblog]介绍.
### 1.1.2 android.util.writeEvent
分析 writeEvent 到 liblog 的流程高度相似, 细节就不展开了, 这里直接贴下最终的结论:
```
/frameworks/base/core/java/android/util/EventLog.java writeEvent()
--> /frameworks/base/core/jni/android_util_EventLog.cp android_btWriteLog_xx()
--> /system/core/include/log/logger.h --> log.h android_btWriteLog()
--> /system/core/liblog/logger_write.c __android_log_btwrite() -> write_to_log()
```
==__android_log_btwrite()== 后面调用到 ==write_to_log()==. 前面提到的 __android_log_buf_write() 也是直接调用到 write_to_log() .
即结论是: android.util.EvnentLog 跟 Android.util.Log 打印日志的流程相同, 都是转到 /system/core/liblog/logger_write.c 去处理.
android.util.writeEvent.writeEvent() --> android_btWriteLog_xx() (/frameworks/base/core/jni/android_util_EventLog.cpp)
--> android_btWriteLog() (/system/core/include/log/log.h) --> __android_log_btwrite() (/system/core/liblog/logger_write.c) --> write_to_log()
## 1.2 Native Code : ALOG / ALOGE / ALOGD ..
我们还会看到一些native code(主要是C/C++)也有打印log:
```
// xxx.c / xxx.cpp
#define LOG_TAG "fingerprintd"
ALOG(LOG_VERBOSE, LOG_TAG, "lockout\n");
ALOGE("Invalid callback object");
ALOGD("onAcquired(%d), duplicatedFingerId(%d)", 1, 2);
```
这些形如 "[ASR]LOG[VDIWE]" 的函数的声明在 "/system/core/include/log/log.h":
```
// ALOGD/ALOGE ---> ALOG ---> LOG_PRI ---> android_printLog ---> __android_log_print()
/*
* Basic log message macro.
*
* Example:
* ALOG(LOG_WARN, NULL, "Failed with error %d", errno);
*
* The second argument may be NULL or "" to indicate the "global" tag.
*/
#ifndef ALOG
#define ALOG(priority, tag, ...) \
LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#endif
/*
* Simplified macro to send an error log message using the current LOG_TAG.
*/
#ifndef ALOGE
#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
#endif
/*
* Simplified macro to send a debug log message using the current LOG_TAG.
*/
#ifndef ALOGD
#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
/
/*
* Log macro that allows you to specify a number for the priority.
*/
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) \
android_printLog(priority, tag, __VA_ARGS__)
#endif
#define android_printLog(prio, tag, fmt...) \
__android_log_print(prio, tag, fmt)
```
在宏里兜兜转转,最后走到 __android_log_print() 函数:
ALOGD/ALOGE ---> ALOG ---> LOG_PRI ---> android_printLog ---> __android_log_print()
而 ==__android_log_print()== 函数的实现在 "/system/core/liblog":
```
// 只列出其中一个实现.
// /system/core/liblog/logger_write.c
LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag,
const char *msg)
{
return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
}
```
__android_log_print() 函数只是 __android_log_buf_write() 的简单包装.
所以, 形如 "[ASR]LOG[VDIWE]" 的的log输出, 最终跟 android.util.Log 一样, 也是走到 "/system/core/liblog"的 __android_log_buf_write() 处理.
## 1.3 /system/core/liblog
上面2节都提到, 关键函数 __android_log_buf_write() . 以及遗留了一个问题 "__android_log_buf_write() 的多个实现, 到底哪个才是最终的实现?
结论是 "有 "LIBLOG_ABI_PUBLIC" 宏修饰的, 是最终被使用的实现."
```
// /system/core/liblog/logger_write.c
LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
const char *tag, const char *msg)
{
// ....
return write_to_log(bufID, vec, 3);
}
```
那么怎么得道的这个结论呢?
__android_log_buf_write() 分别在 "logd_write.c" / "logd_write_kern.c" / "logger_write.c" 三个文件都有实现.
```
logd_write.c
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
...
logd_write_kern.c
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
...
logger_write.c
LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
...
```
根据liblog模块的mk文件 "/system/core/liblog/Android.mk", 知道前2个都没有参与编译. 只有第三个文件 "logger_write.c" 参与了编译.
另外结合阅读 liblog 模块的代码, 也可以确认, logd_write.c 和 logd_write_kern.c 都是历史残留代码.
在 [1.6 Android 4.4 liblog] 对旧的log逻辑做一些分析.
回到 logger_write.c 的 __android_log_buf_write() 继续跟进.
```
// /system/core/liblog/logger_write.c
LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
const char *tag, const char *msg)
{
struct iovec vec[3];
char tmp_tag[32];
if (!tag)
tag = "";
/* XXX: This needs to go! */
if ((bufID != LOG_ID_RADIO) &&
(!strcmp(tag, "HTC_RIL") ||
!strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
!strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
!strcmp(tag, "AT") ||
!strcmp(tag, "GSM") ||
!strcmp(tag, "STK") ||
!strcmp(tag, "CDMA") ||
!strcmp(tag, "PHONE") ||
!strcmp(tag, "SMS"))) {
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。