在Android系统中,提供了简单、便利的LOG机制,开发人员可以方便地使用。下面简单介绍在Android内核空间和用户空间中LOG的使用和查看方法。
一、内核开发时LOG的使用 printk提供了8种日志级别(linux/kern_levels.h):
#define KERN_EMERG KERN_SOH "0" /* system is unusable */
#define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */
#define KERN_CRIT KERN_SOH "2" /* critical conditions */
#define KERN_ERR KERN_SOH "3" /* error conditions */
#define KERN_WARNING KERN_SOH "4" /* warning conditions */
#define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */
#define KERN_INFO KERN_SOH "6" /* informational */
#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
printk的使用方法:
printk(KERN_ALERT”This is the log printed by printk in linux kernel space.”);
KERN_ALERT表示日志级别,后面紧跟着要格式化字符串。
在Android系统中,printk输出的日志信息保存在/proc/kmsg中,要查看/proc/kmsg的内容,
启动adb shell工具:
pengtg@pengtg:~$ adb shell
查看/proc/kmsg文件:
root@BBL7516A:/ # cat /proc/kmsg
二. 用户空间程序开发时LOG的使用。 在用户空间Android系统也提供了一套轻量级的日志系统,并且在C/C++和Java层分别提供了两种不同的接口,二者的区别是C/C++语言的logger是用于HAL层以及JNI层的开发和调试,而Java语言的logger则是用于应用层的开发和调试。
Android系统中的C/C++日志接口是通过宏来使用的。在system/core/include/android/log.h定义了日志的级别:
/*
* Android log priority values, in ascending priority order.
*/
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
在system/core/include/cutils/log.h中只是include了log/log.h
#include <log/log.h>
在/system/core/include/log/log.h中,定义了对应的宏,如对应于ANDROID_LOG_DEBUG的宏SLOGD:
/*
* Simplified macro to send a debug system log message using the current LOG_TAG.
*/
#ifndef SLOGD
#define SLOGD(...) ((void)MTK_LOG_BUF_PRI(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
#ifndef SLOGD_IF
#define SLOGD_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)MTK_LOG_BUF_PRI(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#endif
因此,如果要使用C/C++日志接口,只要定义自己的LOG_TAG宏和包含头文件system/core/include/cutils/log.h就可以了:
#define LOG_TAG "MY DEBUG TAG"
#include <cutils/log.h>
就可以了,例如使用LOGD:
LOGD("This is the log printed by LOGD in android user space.");
接下来看Java日志接口。Android系统在Frameworks层中定义了Log接口
(frameworks/base/core/java/android/util/Log.java):
public final class Log {
/**
* Priority constant for the println method; use Log.v.
*/
public static final int VERBOSE = 2;
/**
* Priority constant for the println method; use Log.d.
*/
public static final int DEBUG = 3;
/**
* Priority constant for the println method; use Log.i.
*/
public static final int INFO = 4;
/**
* Priority constant for the println method; use Log.w.
*/
public static final int WARN = 5;
/**
* Priority constant for the println method; use Log.e.
*/
public static final int ERROR = 6;
/**
* Priority constant for the println method.
*/
public static final int ASSERT = 7;
public static int v(String tag, String msg, Throwable tr) {
return println_native(LOG_ID_MAIN, VERBOSE, tag, msg + '\n' + getStackTraceString(tr));
}
public static int d(String tag, String msg) {
return println_native(LOG_ID_MAIN, DEBUG, tag, msg);
}
public static int d(String tag, String msg, Throwable tr) {
return println_native(LOG_ID_MAIN, DEBUG, tag, msg + '\n' + getStackTraceString(tr));
}
public static int i(String tag, String msg) {
return println_native(LOG_ID_MAIN, INFO, tag, msg);
}
public static int i(String tag, String msg, Throwable tr) {
return println_native(LOG_ID_MAIN, INFO, tag, msg + '\n' + getStackTraceString(tr));
}
public static int w(String tag, String msg) {
return println_native(LOG_ID_MAIN, WARN, tag, msg);
}
public static int w(String tag, String msg, Throwable tr) {
return println_native(LOG_ID_MAIN, WARN, tag, msg + '\n' + getStackTraceString(tr));
}
public static int w(String tag, Throwable tr) {
return println_native(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr));
}
public static int e(String tag, String msg) {
return println_native(LOG_ID_MAIN, ERROR, tag, msg);
}
public static int e(String tag, String msg, Throwable tr) {
return println_native(LOG_ID_MAIN, ERROR, tag, msg + '\n' + getStackTraceString(tr));
}
............
/** @hide */ public static native int println_native(int bufID,
int priority, String tag, String msg);
}
如果要使用Java日志接口,只要在类中定义的LOG_TAG常量和引用android.util.Log就可以了:
private static final String LOG_TAG = "MY_LOG_TAG";
Log.i(LOG_TAG, "This is the log printed by Log.i in android user space.");
要查看这些LOG的输出,可以配合logcat工具,在Android Studio就可以查看。也可以在命令端直接使用adb logcat 命令查看。