Logging the line numbers is very helpful, particularly for easier debugging. It also helps us trace the execution flow through the code, making it easier to identify the sequence of events.

Using the custom logging

Another way to print the log messages with the line number is by using the Thread.currentThread().getStackTrace() method to obtain the call stack trace information. This method returns information such as class name, method name, filename and line number.

public class LineNumberLoggingExample {

    public static void main(String[] args) {
        logWithLineNumber("This is a log message.");
    }

    public static void logWithLineNumber(String message) {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        
        // The first element (index 0) is this method, 
        // the second element (index 1) is the caller, 
        // and so on.
        StackTraceElement caller = stackTrace[2];
        
        String logMessageWithLineNumber = 
            "[" + caller.getFileName() + ":" + caller.getLineNumber() + "] " + message;
        
        System.out.println(logMessageWithLineNumber);
    }
}

Example output:

[LineNumberLoggingExample.java:7] This is a log message.

Explanation:

In the above example, we have a logWithLineNumber method that takes a log message as a parameter. It gets the stack trace and extracts the information from the second element (index 2), which corresponds to the caller of the logWithLineNumber method and then it constructs a log message string that includes the caller’s file name and line number.

Using the Log4j

If you’re using a logging framework like Log4j (or its successor, Log4j2), adding line numbers to a log is so simple. Following is how you can configure Log4j2 to include line numbers.

I hope you already have Log4j installed and added it to your project’s dependency list.

Create a log4j2.xml or log4j2.properties configuration file if you don’t have one already.

In the following configuration, the %L is used in the PatternLayout to include the line number.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg (%L)%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

Now, in your Java code, use Log4j2 to log messages as usual. Line numbers will automatically be included in log entries, even in exceptions.

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4j2LineNumberLoggingExample {

    private static final Logger logger = LogManager.getLogger(Log4j2LineNumberLoggingExample.class);

    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            logger.info("Result: " + result);
        } catch (ArithmeticException e) {
            // Log the exception with line number
            logger.error("Error occurred: " + e.getMessage(), e);
        }
    }

    public static int divide(int dividend, int divisor) {
        return dividend / divisor;
    }
}

Categorized in:

Tagged in: