Android logging levels

2019-01-16 08:44发布

问题:

I'm having a little difficulty configuring Android logging. Here's what my code looks like:

    if (Log.isLoggable("MY_TAG", Log.VERBOSE)) {
        Log.v("MY_TAG", "Here's a log message");
    }

Pretty simple, right?

However, I'm having quite a bit of difficulty getting the Log.isLoggable("MY_TAG", Log.VERBOSE) to return true.

Per http://developer.android.com/reference/android/util/Log.html, I tried adding a local.prop file to the /data/ directory which looks like this:

log.tag.MY_TAG=VERBOSE

but no luck. I also tried:

System.setProperty("log.tag.MY_TAG", String.valueOf(Log.VERBOSE));

but that doesn't work either.

Any ideas on what I'm doing wrong here? I'm running Android 2.1-update1 on a Nexus 1 if that makes any difference.

回答1:

Try

adb shell setprop log.tag.MyAppTag VERBOSE


回答2:

It seems that later versions of Android want /data/local.prop to be writable by root only. The adb push command appears to initially create files with granting everyone read/write access (because default file mask is 777). Android, wisely, ignores /data/local.prop since this can be a security risk.

I have only experimented with Android 2.3.3, and 4.1.2. The former has no issues with reading a local.prop that is world writable, while the latter appears to silently ignore the file's contents.

Creating a local.prop file as described in the original question:

log.tag.MY_TAG=VERBOSE

And then pushing it onto the device as follows seems to do the trick:

adb push local.prop /data/local.prop
adb shell chmod 644 /data/local.prop
adb shell chown root.root /data/local.prop
adb reboot

You can double check to make sure that the values in local.prop were read by executing:

adb shell getprop | grep log.tag

So in summary:

  • /data/local.prop is only read during boot.
  • Later versions of Android appear to require that the permissions on the /data/local.prop file must be properly set, or it will not be read. The file must be writable by root only.

Using adb shell setprop log.tag.MyAppTag VERBOSE also work. The issue is that the property values are lost after a reboot.



回答3:

An important goal is to not ship a production app with a ton of log calls left in it, increasing its size, and even possibly even impacting its performance.

To do this, my recommendation is to put these constants at the top of each class that is going to have log calls:

static final boolean DEBUG = false;
static final String TAG = "<MyClass>"

Now where you log, do this:

if (DEBUG) Log.v(TAG, "Something");

Turn on your logs by changing the DEBUG constant to true. (If you want, you could have one class with these statics for all of your app's code to use... That makes sense for a small app, but as things get large it is nice to decide which parts to turn logging on.)

By doing this, when you build your app with DEBUG = false, all of your logging code not only isn't executed, but is completely stripped out of your app. This is nice because it allows you to leave fairly extensive logging in your code to be turned on when you need it, without worrying about how that will impact the size of your shipping app. Basically just throw logs in wherever you need them and don't worry about leaving them in.

This is the approach that a lot of the Android framework takes. For example, the Activity ManagerService.

This has those constants at the top, and various log lines sprinkled throughout based on them. (And a bunch of other sub-debug constants for various aspects of it, since this file is ridiculously stupidly large.)