651.288.7000 info@intertech.com

Android is a Java platform, albeit a slightly different Java platform.  As such, many new Android developers I encounter are at first confused by Android’s logging features.  Admittedly, it is a bit different that some of the logging APIs and apparatus one encounters in Java SE or Java EE.  So I’m going to attempt to clarify some of Android’s logging capability and also highlight some very interesting points about how logging works.

The Log class

First off, logging is accomplished through Android’s android.util.Log class.  There are a collection of static methods that are called on the class itself to write to what is called the LogCat.  The documentation for the Log class can be found here, but below are the more significant methods.

Android Log method Purpose
e(String tag, String message) Log an error
w(String tag, String message) Log a warning
i(String tag, String message) Log an informational message
d(String tag, String message) Log a debug statement
v(String tag, String message) v stands for verbose.  Log verbose forms of the informational messages
wtf(String tag, String message) My favorite – indicating the Android developers truly have a sense of humor.  Log a failure (probably critical) that was never expected/anticipated to occur.  According to the documentation, wtf stands for what a terrible failure.  Ahhh – sure.  This method was added with Android 2.2 (API 8).  So it is not available in all Android environments.

Note, there are additional methods and those above are overloaded, but this is enough to get you started logging.

As you can see by the methods’ purpose, each method allows you to suggest the severity and importance of the log message.  The purpose of the first parameter to these methods, the tag parameter, is to identify the component that originated the log message.  The tag string can be very helpful in helping to filter out log messages (more on this topic below).  The second parameter to the Log methods is the message to be deposited in the LogCat.

As a matter of good Android development practice, create static final String constants to keep the tags consistent.

private static final String VIEW_TAG = "ContactDisplayActivity";

Use the Log class and its methods from anywhere in your Android code to add messages to the log file like the Activity below.

public class ContactDisplayActivity extends Activity {

    private static final String VIEW_TAG = "ContactDisplayActivity";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.v(VIEW_TAG, "In the onCreate method");
        // your code here
    }
}

The LogCat

So where do all those log messages go?  Android maintains a circular buffer (i.e. file) for log messages, stack traces, etc.  This file is located in /dev/log/main on the device (or Android Virtual Device during testing).  It is circular in that the file is maintained within a fixed size.  As new messages come in and the buffer/file fills up, old messages are pulled off the file (making room for the new messages).  The size of the LogCat buffer varies per device.  You can use the adb tool to see the size of the log (see details about adb here).  Call the following command:

adb logcat -g

Below is an example result indicating my device has a buffer size of 64K.

SNAGHTML67d6a1

Accessing LogCat

You access LogCat for an AVD or on an actual device (via USB cable) from either DDMS or an adb shell.  You can even use the same tools to control entries and formatting to the LogCat file.  See here for more details on reading and writing to the log.  If you use Eclipse, there is a DDMS perspective that provides a LogCat view for viewing (and filtering

image

In fact, these tools allow you to filter the log so as to be able to find relevant entries.  You can filter by message severity (as shown below).

image

You can also create other custom filters that filter messages by tag (and the reason why establishing good tags is good Android developer convention), message, process id, or application name.

image  SNAGHTML7f51e9

Turn Logging Off in Production

While access to the log file is limited (via the tools mentioned), you still have to be careful in that it is very easy to hook up a real device to a laptop via USB and see the information logged.  A Belgian bank create a very large security concern by logging information from a server to the log file during development and forgetting to remove the logging when the application went to production.  See here for the details of the story.  No doubt, you will hear and see of other such security concerns.  In fact, the Android Developer site provides some prudent guidance regarding the preparation of an application before it is ready to be released.  In that guidance, they tell us to “Make sure you deactivate logging and disable the debugging option before you build your application for release.”

Turning Off (or Down) Logging

To stop debugging, you can remove Log calls in your code.  Alternately, you can conditionalize Log calls and thereby allow a single variable (or set of variables) to help control what (if anything) gets logged.

public static boolean LOG_ON = true;

if (LOG_ON) Log.e(VIEW_TAG, “error message goes here”);

The adb can be used to temporarily set the log level as shown below, but the emphasis here is on temporary.

adb shell setprop log.tag.MyAppTag WARN

As a final alternative, you can also use a tool such as ProGuard to strip out logging statements.  ProGuard is a tool that shrinks, optimizes, and obfuscates Android Java code and is integrated into Android build systems.  You can learn more about these options from a nice StackOverflow thread here.

Why not System.out.println()

In “normal” Java, you may have used System.out.println() (and System.err) calls to drop debug and other log calls into the standard output (and standard error).  Good ol’ System.out still works in Android, but it should be avoided.  First of all, by default, System.out.println( ) calls are routed to an alternate /dev/null file.  These log statements can be rerouted to the LogCat file with some additional configuration.  However, another reason why you may find System.out.println() less than helpful is that these println() messages are tagged with default “System.out” tags and with info (I) level priority.  So it is not as easy to determine what component launched the logging and the severity may not be inline with the info level attributed to the log message.

image

Log4j (and other such common Java logging packages)

For those more familiar with Log4J or SLF4J logging packages, you will find these frameworks are also available in Android.  In fact, their Android versions serve as a wrapper to the LogCat functionality.  You’ll find Log4j for Android here and SLF4J for Android here.

Other Android Logging Secrets

There are a couple of other secrets to Logging that are often missed by Android developers.  In fact, these are not secrets but information that is buried a little bit in the Android documentation.

As mentioned already, all logging should be removed or at least reduced prior to shipping any Android application.  But you might be interested to know that debug log messages are compiled in to the Android code, but get stripped at runtime.  This is not the case with verbose log statements.  Therefore, as the documentation says, “Verbose should never be compiled into an application except during development.”  (Reference:  http://developer.android.com/reference/android/util/Log.html).

Another little hidden gem of knowledge deep in the documentation is that there are actually several circular log files.  Log messages go to /dev/log/main, but there exist telephony logs, event logs and system logs as well.  These can be found in /dev/log/radio, /dev/log/events and /dev/log/system respectively.  Use the following command to view these logs.

adb logcat -b <alternate log name like radio>

Wrap Up

Hopefully, this post can help you navigate your way around the Android log capability.  If you are just starting out and would like to learn more about Android, please join me for Complete Android at Intertech.  Contact Dan McCabe in our office for details on our next public class offering.

Pin It on Pinterest

Share This

Like What You've Read?

Subscribe to the Blog.

Every Friday we send that week's content from our Developers via email. Try it out!

Some ad blockers can block the form below.

You have Successfully Subscribed!