Android: How to Include Line Numbers, Class Names, and Method Names in Your Log Statements

Today, I’m going to share with you a handy tip for getting the most out of your Android log. I recommend that you create a wrapper class around the native Android Log class in order to:

  1. Have the ability to turn on or off logging.
  2. Have the ability to log handy things like line number, class names, and method names.

I’m going to show you a simple implementation of a Logger class that does these things:

import android.util.Log;

public class Logger
{
    private static boolean LOGGING_ENABLED;

    private static final int STACK_TRACE_LEVELS_UP = 5;

    public static void verbose(String tag, String message)
    {
	if (LOGGING_ENABLED)
	{
            Log.v(tag, getClassNameMethodNameAndLineNumber() + message);
	}
    }

    /**
     * Get the current line number. Note, this will only work as called from
     * this class as it has to go a predetermined number of steps up the stack
     * trace. In this case 5.
     * 
     * @author kvarela
     * @return int - Current line number.
     */
    private static int getLineNumber()
    {
	return Thread.currentThread().getStackTrace()[STACK_TRACE_LEVELS_UP].getLineNumber();
    }

    /**
     * Get the current class name. Note, this will only work as called from this
     * class as it has to go a predetermined number of steps up the stack trace.
     * In this case 5.
     * 
     * @author kvarela
     * @return String - Current line number.
     */
    private static String getClassName()
    {
	String fileName = Thread.currentThread().getStackTrace()[STACK_TRACE_LEVELS_UP].getFileName();

	// kvarela: Removing ".java" and returning class name
	return fileName.substring(0, fileName.length() - 5);
    }

    /**
     * Get the current method name. Note, this will only work as called from
     * this class as it has to go a predetermined number of steps up the stack
     * trace. In this case 5.
     * 
     * @author kvarela
     * @return String - Current line number.
     */
    private static String getMethodName()
    {
	return Thread.currentThread().getStackTrace()[STACK_TRACE_LEVELS_UP].getMethodName();
    }

    /**
     * Returns the class name, method name, and line number from the currently
     * executing log call in the form <class_name>.<method_name>()-<line_number>
     * 
     * @author kvarela
     * @return String - String representing class name, method name, and line
     *         number.
     */
    private static String getClassNameMethodNameAndLineNumber()
    {
	return "[" + getClassName() + "." + getMethodName() + "()-" + getLineNumber() + "]: ";
    }
}

 
As you can see, this uses Thread.currentThread().getStackTrace()[] to climb up the stack trace and get the information from the proper line of code. In my case, it has to climb 5 levels up to get this information. Yours could be different depending on how many levels of abstraction you have when you call getStackTrace(). I found the easiest way is just to experiment with different numbers.