Monday, February 29, 2016

Android Logcat Tag Best Practices

The Android API provides a useful way for developers to collect and view system debug output. The tool, Logcat, contains stack traces from application crashes, as well as custom messages that developers can provide in their code. Every log message has an associated "tag" field, which is the main focus of this post.

Conventionally, developers will define a constant string field called TAG near the top of their code files. There are a variety of ways to define this field, but the main choices are usually:
  1. private static final String TAG = Foo.class.getName(); // "com.example.android.Foo"
  2. private static final String TAG = Foo.class.getCanonicalName(); // "com.example.android.Foo"
  3. private static final String TAG = Foo.class.getSimpleName(); // "Foo"
  4. private static final String TAG = "Foo"; // "Foo"

I'll state up front, I prefer option #4, for several reasons:
  1. #1-#3 all require the class to do some static initialization work. Yes, it's not MUCH work, but it's more work than nothing.
  2. #4 allows the compiler to more aggressively optimize, for example, by inlining the TAG string across all log statements at compile time.
  3. Log tags have a max length of 23 characters, and longer tags will be truncated.
    1. This means that #1 & #2 have an extremely high chance of truncation right off the bat. Having a tag of "com.example.android.in" instead of "Foo isn't very useful.
    2. Even with #3, if the class name is long you could still end up with a truncated log tag. With #4, you can customize your tag to ensure it's under 23 characters even if your class name is longer.
    3. As of Build Tools 21.0.3, there is a lint check for this, but the lint check can only detect tags created with string literals, as in option #4.
  4. If you're using Proguard to obfuscate your app, then class name Foo gets obfuscated and your tag becomes something like "a" instead of "Foo" if you're using #1-#3.
  5. #4 is what Google uses inside the AOSP codebase (though I'm not aware of any justification for Google on why they do this)

The main downside of option #4 is that the tag won't automatically be updated if you refactor the class name. However, since TAG is generally the first line in a class, it's likely that the discrepancy will be noticed either by the person doing the refactoring or someone who reviews the code change.

Another useful tip for using option #4 is to update your new class template in Android Studio to automatically create your tag for you. Just go to Preferences -> Editor -> File and Code Templates -> Class and change the template to the following:


This will automatically create a TAG field with the same name as your class file, and then you can customize it if needed.

Happy logging!