我们都知道在写Android程序的时候经常需要log输出来调试我们代码,在程序开发过程中,LOG是广泛使用的用来记录程序执行过程的机制,它既可以用于程序调试,也可以用于产品运营中的事件记录。在Android系统中,提供了简单、便利的LOG机制,开发人员可以方便地使用。在这一篇文章中,我们简单介绍在非android应用程序中怎样使用log 输出日志信息用于调试我们一下脚本或者其他东西。比如android中运行shell脚本就无法用log输出。
在adb shell 模式下,输入log打印出一下信息
USAGE: log [-p priorityChar] [-t tag] message
priorityChar should be one of:
v,d,i,w,e
上面介绍了 log 工具的使用方法,-p 是我们的优先级,我们知道log有以下几种优先级
LOG的标签是一个简短的描述来指示发生在哪一个系统部件内,在写LOG时指定。(比如:“View”就是查看VIEW系统的标签).
· 优先级有下列几种,按照优先级从低到高顺序排列为:
o V — Verbose (最低优先级)
o D — Debug
o I — Info
o W — Warning
o E — Error
o F — Fatal
o S — Silent (最高优先级,没有任何输出)
-t tag 表示紧跟tag信息,等于
MY_LOG_TAG
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.");
message就是等于This is the log printed by Log.i in android user space.
测试一下,我们在linux下adb connect android 设备,打开两个android shell 终端命令窗口,分别是一个发送log信息端。一个是接收log端
接收端 先 adb shell ,然后在shell下 adb logcat -s Test,接着发送端shell下 adb shell 接着 log -p e -t Test ssssssssss
-p e 代表优先级 是 error , -t Test 代表 tag =Test ,message=ssssssssss,
上面是接收端,下面是发送端
可以清楚看到当发送端通过log命令发送信息。log接收端可以接收发送端的信息!!
log的源码在system/core/toolbox下log.c文件中,
int log_main(int argc, char *argv[])
{
android_LogPriority priority;
const char *tag = "log";
char buffer[4096];
int i;
priority = ANDROID_LOG_INFO;
for (;;) {
int ret;
ret = getopt(argc, argv, "t:p:h");
if (ret < 0) {
break;
}
switch(ret) {
case 't':
tag = optarg;
break;
case 'p':
priority = filterCharToPri(optarg[0]);
if (priority == ANDROID_LOG_UNKNOWN) {
usage(argv[0]);
}
break;
case 'h':
usage(argv[0]);
break;
}
}
if (optind == argc) {
usage(argv[0]);
}
buffer[0] = '\0';
for (i = optind ; i < argc ; i++) {
strlcat(buffer, argv[i], sizeof(buffer)-1);
strlcat(buffer, " ", sizeof(buffer)-1);
}
if(buffer[0] == 0) {
usage(argv[0]);
}
printf("hello===========\n");
__android_log_print(priority, tag, "%s", buffer);
return 0;
}
这是log工具的源码很简单开始for(;;)
for (;;) {
int ret;
ret = getopt(argc, argv, "t:p:h");
if (ret < 0) {
break;
}
switch(ret) {
case 't':
tag = optarg;
break;
case 'p':
priority = filterCharToPri(optarg[0]);
if (priority == ANDROID_LOG_UNKNOWN) {
usage(argv[0]);
}
break;
case 'h':
usage(argv[0]);
break;
}
解析我们传递参数很简单!!这里就不介绍了
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
{
va_list ap;
char buf[LOG_BUF_SIZE];
#ifdef HAVE_XLOG_FEATURE
#if !defined(FAKE_LOG_DEVICE)
if(!xlogf_native_tag_is_on(tag, prio))
return -1;
#endif
#endif
va_start(ap, fmt);
vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
va_end(ap);
return __android_log_write(prio, tag, buf);
}
log工具传递给下面函数四个参数
__android_log_print(priority, tag, "%s", buffer);
分别是优先级 tag msg和buffer大小,
xlogf_native_tag_is_on(tag, prio)这个函数是mtk内部函数。没有源码。这个SB公司产品。我们在root过后就是因为优先级问题导致所有的
d一下权限信息都看不到,
接着调用
<strong> __android_log_write(prio, tag, buf);</strong>
int __android_log_write(int prio, const char *tag, const char *msg)
{
struct iovec vec[3];
log_id_t log_id = LOG_ID_MAIN;
char tmp_tag[32];
if (!tag)
tag = "";
/* XXX: This needs to go! */
if (!strcmp(tag, "HTC_RIL") ||
#ifdef MTK_DT_SUPPORT
!strncmp(tag, "RIL3", 4) ||
!strcmp(tag, "AT3") ||
!strcmp(tag, "MUXD3") ||
#endif
#ifdef EVDO_DT_SUPPORT
!strcmp(tag, "VIA_RIL") ||
!strcmp(tag, "VIA_AT") ||
!strcmp(tag, "VIA_RILC") ||
!strcmp(tag, "VIA_RILD") ||
#endif /* EVDO_DT_SUPPORT */
!strcmp(tag, "RILMD2") ||
!strcmp(tag, "ATMD2") ||
!strcmp(tag, "MUXDMD2") ||
!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, "MUXD") ||
!strcmp(tag, "GSM") ||
!strcmp(tag, "STK") ||
!strcmp(tag, "CDMA") ||
!strcmp(tag, "PHONE") ||
!strcmp(tag, "SMS")) {
log_id = LOG_ID_RADIO;
// Inform third party apps/ril/radio.. to use Rlog or RLOG
snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
tag = tmp_tag;
}
vec[0].iov_base = (unsigned char *) &prio;
vec[0].iov_len = 1;
vec[1].iov_base = (void *) tag;
vec[1].iov_len = strlen(tag) + 1;
vec[2].iov_base = (void *) msg;
vec[2].iov_len = strlen(msg) + 1;
return write_to_log(log_id, vec, 3);
}
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
{
struct iovec vec[3];
char tmp_tag[32];
printf("------\n");
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"))) {
bufID = LOG_ID_RADIO;
// Inform third party apps/ril/radio.. to use Rlog or RLOG
snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
tag = tmp_tag;
}
vec[0].iov_base = (unsigned char *) &prio;
vec[0].iov_len = 1;
vec[1].iov_base = (void *) tag;
vec[1].iov_len = strlen(tag) + 1;
vec[2].iov_base = (void *) msg;
vec[2].iov_len = strlen(msg) + 1;
return write_to_log(bufID, vec, 3);
}
上面这段函数和我一个博文(
)一样,就不分析了