Rather odd behaviour of Log

大城市里の小女人 提交于 2019-12-03 17:09:57

I should have read the documentation for logcat before I started hunting through source. According to logcat's documentation:

The Android logging system keeps multiple circular buffers for log messages, and not all of the log messages are sent to the default circular buffer.

Messages with a tag of SMS are sent to the radio buffer, not the main buffer. Hence you won't see them unless you go out of your way to do so. If you run the command:

adb logcat -b radio

you should see your missing log messages. The above information can be found in https://developer.android.com/tools/debugging/debugging-log.html.


Now, for those of you interested in code spelunking, below is my original answer:

The methods in the Log class are all wrappers around println_native which is a JNI method.
println_native performs some validation of its parameters and then calls __android_log_buf_write.

Now this latter method compares the tag parameter (from the original Log.d call) against several hard-coded strings (with the tag SMS being one of this list) and if it finds a match, winds up writing the log message to a different file!

By the way, other tags that get rerouted are GSM, STK, PHONE, CDMA, and a few others.

Relevant source can be read in

These aren't the official links and may disappear at some point. I'll try and track down the official links and edit this later this evening.

kcoppock

EDIT Ignore this, I'm apparently quite off base according to this.

So I thought this was interesting, and after digging through the source, I ended up finding out about Log.isLoggable():

Checks to see whether or not a log for the specified tag is loggable at the specified level. The default level of any tag is set to INFO. This means that any level above and including INFO will be logged. Before you make any calls to a logging method you should check to see if your tag should be logged. You can change the default level by setting a system property: 'setprop log.tag. ' Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will turn off all logging for your tag. You can also create a local.prop file that with the following in it: 'log.tag.=' and place that in /data/local.prop.

Parameters
tag The tag to check.
level The level to check.

Returns
Whether or not that this is allowed to be logged.

Apparently some tags are not allowed at certain log levels, seemingly defined in /data/local.prop, but there must be some system level properties file I haven't found yet. You can check against it using something like this, though:

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));

Which for me returned the following:

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

So you can log the tag SMS at a log level of INFO and above, but not VERBOSE or DEBUG.

I have to assume this is to prevent applications from accidentally logging personal information, but it seems like a fairly crude way of doing so.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!