I assume most of you are aware of android.util.Log All logging methods accept \'String tag\' as a first argument.
And my question is How do you usually tag y
private static final String TAG = new RuntimeException().getStackTrace()[0].getClassName();
It is a very old question, but even thought an updated answer for July 2018 it is more preferable to use Timber. In order to Log the correct logging, errors and warns can be send to third party crash libraries, such as Firebase or Crashlytics.
In the class that implements Application you should add this:
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
} else {
Timber.plant(new CrashReportingTree());
}
}
/** A tree which logs important information for crash reporting. */
private static class CrashReportingTree extends Timber.Tree {
@Override protected void log(int priority, String tag, String message, Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
FakeCrashLibrary.log(priority, tag, message);
if (t != null) {
if (priority == Log.ERROR) {
FakeCrashLibrary.logError(t);
} else if (priority == Log.WARN) {
FakeCrashLibrary.logWarning(t);
}
}
}
}
Do not forget Timber dependency.
implementation 'com.jakewharton.timber:timber:4.7.1'
At the expense of updating these strings when I move code between methods or rename methods, I like doing the following. Philosophically it also seems to be better to keep "location" or "context" in the tag, not the message.
public class MyClass {
// note this is ALWAYS private...subclasses should define their own
private static final LOG_TAG = MyClass.class.getName();
public void f() {
Log.i(LOG_TAG + ".f", "Merry Christmas!");
}
}
The benefit here is that you can filter out a single method even if the content isn't static, e.g.
Log.i(LOG_TAG + ".f", String.valueOf(new Random().nextInt()));
The only drawback is that when I rename f()
to g()
I need to keep that string in mind. Also, automatic IDE refactoring won't catch these.
For a while I was a fan of using the short class name, I mean LOG_TAG = MyClass.class.getSimpleName()
. I found them harder to filter in the logs because there was less to go on.
AndroidStudio has a logt
template by default (you can type logt
and press tab to have it expand to a sinppet of code) . I recommend using this to avoid copy pasting the TAG definition from another class and forgetting to change the class you're referring to. The template expands by default to
private static final String TAG = "$CLASS_NAME$"
To avoid using the old class name after refactoring you could change that to
private static final String TAG = $CLASS_NAME$.class.getSimpleName();
Remember to check the "Edit variables" button and make sure that the CLASS_NAME
variable is defined to use the className()
Expression and has "Skip if defined" checked.
I use a TAG, but I initialise it like this:
private static final String TAG = MyActivity.class.getName();
This way when I refactor my code the tag will also change accordingly.
I have created a class of Static variables, methods and classes named as S
.
The following is the logging method:
public static void L(Context ctx, Object s) {
Log.d("CCC " + ctx.getClass().getName().replace(ctx.getPackageName(), ""), s.toString());
}
It is called in any class as S.L(this, whaterver_object);
The getClass().getName()
also appends the package name, hence, I am removing it out to avoid making the tag unnecessarily long.
Advantages:
Log.d(TAG,
toString
Log.d
ever as I just have to delete the method and the locations of all logs get marked red.CCC
(a short, easy to type string) so that it is easy to list only your logs in android monitor in Android Studio. Sometimes you are running services or other classes simultaneously. If you have to search by activity name alone then you cannot see exactly when a service response was obtained and then an action from your activity has occurred. A prefix like CCC helps as it gives you logs chronologically with the activity in which it occured