Rather odd behaviour of Log

2019-08-23 00:54发布

我写了一个很简单的Android活动:

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d("TAG", "onCreate() Log call 1");
        Log.d("SMS", "onCreate() Log call 2");
        Log.d("TEST", "onCreate() Log call 3");

        finish();
    }

    @Override
    protected void onDestroy() {
        Log.d("TAG", "onDestroy() Log call 1");
        Log.d("SMS", "onDestroy() Log call 2");
        Log.d("TEST", "onDestroy() Log call 3");

        super.onDestroy();
    }
}

我希望它可以产生6条日志消息(3从onCreate() ,3来自onDestroy() 这里是logcat的:

04-14 17:31:58.363: D/TAG(18084): onCreate() Log call 1
04-14 17:31:58.363: D/TEST(18084): onCreate() Log call 3
04-14 17:31:59.905: D/TAG(18084): onDestroy() Log call 1
04-14 17:31:59.905: D/TEST(18084): onDestroy() Log call 3

可以看出,与标签“SMS”的台词也打不通。 这不,据我可以告诉一个记录的事情。 现在的问题是,为什么呢?

编辑:在回答更多细节。

一个相当不错的答案是由马修·伯克如下。 总之,对于源代码的基础上logd_write.c ,好像是:

  • Log使用以下标记请求被自动重定向到radio日志:
    • HTC_RIL
    • 开始标签RIL
    • AT
    • GSM
    • STK
    • CDMA
    • PHONE
    • SMS
  • 没有Log请求会被重定向到events日志(或在system日志中,也看到http://elinux.org/Android_Logging_System )
  • 所有其他Log请求转到main日志,即通常监测的一个。

Answer 1:

我应该阅读文档logcat之前,我开始通过源打猎。 据logcat的文档:

Android的日志系统保持多个循环缓冲区的日志信息,而不是所有的日志消息被发送到默认循环缓冲区。

与标签信息SMS发送到电台缓冲区,而不是主缓冲。 因此,你不会看到它们,除非你走出自己的方式来做到这一点。 如果您运行以下命令:

adb logcat -b radio

你应该看到丢失的日志信息。 上述信息中可以找到https://developer.android.com/tools/debugging/debugging-log.html 。


现在,对于那些你感兴趣的代码洞穴探险,下面是我原来的答复:

在这些方法Log类是围绕所有包装println_native其是JNI方法。
println_native执行其参数的一些验证,然后调用__android_log_buf_write

现在,这后一种方法的标签参数(从原来的比较Log.d针对多种硬编码字符串调用)(带有标签的短信是这个列表中的一个),如果找到匹配,卷起写日志信息传递到不同文件!

顺便说一句,这得到重新路由等标签是GSM,STK,电话,CDMA,和其他几个人。

有关人士可以读

  • http://www.java2s.com/Open-Source/Android/android-core/platform-frameworks-base/android/util/Log.java.htm

  • https://pdroid.googlecode.com/svn/android-2.3.4_r1/trunk/frameworks/base/core/jni/android_util_Log.cpp

  • https://in-the-box.googlecode.com/svn-history/r4/trunk/InTheBoxSim/liblog/logd_write.c

  • http://www.takatan.net/lxr/source/drivers/staging/android/logger.h#L33

这些都不是官方的链接,并可能在某个时候消失。 我会试着追查官方链接和编辑这个今晚稍后。



Answer 2:

编辑忽略这一点,我是根据显然相当关闭基地这个 。

所以,我认为这是有趣的,并通过源挖后,我最终找到了关于Log.isLoggable()

会检查日志指定标签是否是在指定的级别为loggable。 任何标签的默认级别设置为INFO。 这意味着,上述和包括INFO任何级别将被记录。 之前您对测井方法的任何调用你应该检查,看看你的标签应该被记录下来。 “setprop log.tag:您可以通过设置系统属性更改默认的水平。 “哪里的电平要么VERBOSE,DEBUG,INFO,WARN,ERROR,ASSERT,或抑制。 SUPPRESS将关闭所有日志记录您的标记。 您还可以创建一个local.prop文件,在它下面的:“log.tag =”,并放置在/data/local.prop。

参数
标签检查标签。
级别要检查的水平。

返回
不管是不是,这是允许被记录。

显然,一些标签不会在某些日志级别允许的,在看似定义/data/local.prop ,但必须有一些系统级的属性文件我还没发现呢。 你可以对证使用这样的事情,虽然:

boolean isLoggableV = Log.isLoggable("SMS", Log.VERBOSE);
boolean isLoggableD = Log.isLoggable("SMS", Log.DEBUG);
boolean isLoggableI = Log.isLoggable("SMS", Log.INFO);
boolean isLoggableW = Log.isLoggable("SMS", Log.WARN);
boolean isLoggableE = Log.isLoggable("SMS", Log.ERROR);
boolean isLoggableA = Log.isLoggable("SMS", Log.ASSERT);

Log.v("LogTest", String.format("Verbose: %b Debug: %b Info: %b Warn: %b Error: %b Assert: %b", isLoggableV, isLoggableD, isLoggableI, isLoggableW, isLoggableE, isLoggableA));

这对我来说返回以下:

Verbose: false Debug: false Info: true Warn: true Error: true Assert: true

所以,你可以登录标签SMS在日志级别INFO及以上,但不VERBOSEDEBUG

我要承担这是为了防止应用程序意外地登录的个人信息,但它似乎是这样做的相当粗暴的方式。



文章来源: Rather odd behaviour of Log