Printing thread name using java.util.logging

Is it possible to print the thread name in the log statements generated by java.util.logging.Logger?

One alternative is to do something like the following:

logger.info(thread.getName() + " some useful info");

but it's repetitive and the logging framework should handle it.

Embarrassingly, but looks like java.util.logging can't do this...

The default java.util.logging.SimpleFormatter doesn't have the ability to log thread name at all. The java.util.logging.FileHandler supports few template placeholders, none of them is thread name.

java.util.logging.XMLFormatter is the closest one, but only logs thread id:

<record>
  <date>2011-07-31T13:15:32</date>
  <millis>1312110932680</millis>
  <sequence>0</sequence>
  <logger></logger>
  <level>INFO</level>
  <class>java.util.logging.LogManager$RootLogger</class>
  <method>log</method>
  <thread>10</thread>
  <message>Test</message>
</record>

If you think we're getting close - we're not. LogRecord class only holds the thread ID, not its name - not very useful.

java: Printing thread name using java.util.logging, Is it possible to print the thread name in the log statements generated by java.util. logging.Logger?One alternative is to do something like the� Is it possible to print the thread name in the log statements generated by java.util.logging.Logger? One alternative is to do something like the following: logger.info(thread.getName() + " some u Stack Overflow

I had similar problem. As answered here How to align log messages using java.util.logging you can extend java.util.logging.Formatter but instead getting LogRecord#getThreadID() you can get thread name by invoking Thread.currentThread().getName() like this:

public class MyLogFormatter extends Formatter
{

    private static final MessageFormat messageFormat = new MessageFormat("[{3,date,hh:mm:ss} {2} {0} {5}]{4} \n");

    public MyLogFormatter()
    {
        super();
    }

    @Override
    public String format(LogRecord record)
    {
        Object[] arguments = new Object[6];
        arguments[0] = record.getLoggerName();
        arguments[1] = record.getLevel();
        arguments[2] = Thread.currentThread().getName();
        arguments[3] = new Date(record.getMillis());
        arguments[4] = record.getMessage();
        arguments[5] = record.getSourceMethodName();
        return messageFormat.format(arguments);
    }

}

Logging: How to record the name (not ID) of the thread? : learnjava, Ultimately, it is strange/annoying/disappointing that java.util.logging. So is there some way to use logging to retrieve the name, rather than just the ID, of a thread where a prints. [INFO][main]: hello from main [WARNING][t1]: Hello from t1 Problem Description. How to get the name of a running thread? Solution. Following example shows how to get the name of a running thread.

Some application servers implicitly log the thread ID (I know of WebSphere). You can create your own LogFormatter. The records passed to the formatter contain the Thread ID, see here. I implemented that approach for Tomcat several times, but it'll work in Java SE environments as well.

BTW: The Thread name is not available to LogRecord.

How to use getThreadID method in java.util.logging , Best Java code snippets using java.util.logging. the thread's name //only possible if we are the thread (unless do something messy like cache or access private� Java comes with lots of utilities.In this tutorial we will go over simplest way to generate log files using SimpleFormatter and XMLFormatter.. On Crunchify, we have published few tutorials about logging some time back.

java.util.logging has many curious peculiarities. you can add a facade API to tweak its behaviors

public class Log

    Logger logger;

    static public Log of(Class clazz)
        return new Log( Logger.getLogger( clazz.getName() ));

    public void error(Throwable thrown, String msg, Object... params)
    {
        log(ERROR, thrown, msg, params);
    }

    void log(Level level, Throwable thrown, String msg, Object... params)
    {
        if( !logger.isLoggable(level) ) return;

        // bolt on thread name somewhere
        LogRecord record = new LogRecord(...);
        record.setXxx(...);
        ...
        logger.log(record);
    }

----

static final Log log = Log.of(Foo.class);
....
log.error(...);

People use java's logging mostly because they don't want to have 3rd party dependencies. That's also why they can't depend on existing logging facades like apache's or slf4j.

How do I add Thread IDs to log statements in IDM 5.x, 6 and , IDM/OpenIDM uses java.util logging, which allows you to extend logging using Write a custom log formatter using Java� that includes the thread ID. ThreadName : qtp440289386-156 - May 02, 2018 11:07:44.387 AM org. forgerock.openidm.repo.jdbc.impl. This content has been optimized for printing. By default Java Util logging (JUL) uses following configurations (JDK 8): handlers= java.util.logging.ConsoleHandler .level= INFO java.util.logging.ConsoleHandler

With a custom Formatter

Luckily, LogRecord contains the ID of the thread that produced the log message. We can get hold of this LogRecord when writing a custom Formatter. Once we have that, we only need to get the thread name via its ID.

There are a couple of ways to get the Thread object corresponding to that ID, here's mine:

static Optional<Thread> getThread(long threadId) {
    return Thread.getAllStackTraces().keySet().stream()
            .filter(t -> t.getId() == threadId)
            .findFirst();
}

The following is a minimal Formatter that only prints the thread name and the log message:

private static Formatter getMinimalFormatter() {
    return new Formatter() {

        @Override
        public String format(LogRecord record) {

            int threadId = record.getThreadID();
            String threadName = getThread(threadId)
                    .map(Thread::getName)
                    .orElseGet(() -> "Thread with ID " + threadId);

            return threadName + ": " + record.getMessage() + "\n";
        }
    };
}

To use your custom formatter, there are again different options, one way is to modify the default ConsoleHandler:

public static void main(final String... args) {

    getDefaultConsoleHandler().ifPresentOrElse(
            consoleHandler -> consoleHandler.setFormatter(getMinimalFormatter()),
            () -> System.err.println("Could not get default ConsoleHandler"));

    Logger log = Logger.getLogger(MyClass.class.getName());
    log.info("Hello from the main thread");
    SwingUtilities.invokeLater(() -> log.info("Hello from the event dispatch thread"));
}

static Optional<Handler> getDefaultConsoleHandler() {
    // All the loggers inherit configuration from the root logger. See:
    // https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html#a1.3
    var rootLogger = Logger.getLogger("")
    // The root logger's first handler is the default ConsoleHandler
    return first(Arrays.asList(rootLogger.getHandlers()));
}

static <T> Optional<T> first(List<T> list) {
    return list.isEmpty() ?
            Optional.empty() :
            Optional.ofNullable(list.get(0));
}

Your minimal Formatter should then produce the folowing log messages containing the thread name:

main: Hello from the main thread

and

AWT-EventQueue-0: Hello from the event dispatch thread


This is a Formatter that shows how to log more than thread name and log message:

private static Formatter getCustomFormatter() {
    return new Formatter() {

        @Override
        public String format(LogRecord record) {

            var dateTime = ZonedDateTime.ofInstant(record.getInstant(), ZoneId.systemDefault());

            int threadId = record.getThreadID();
            String threadName = getThread(threadId)
                    .map(Thread::getName)
                    .orElse("Thread with ID " + threadId);

            // See also: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Formatter.html
            var formatString = "%1$tF %1$tT %2$-7s [%3$s] %4$s.%5$s: %6$s %n%7$s";

            return String.format(
                    formatString,
                    dateTime,
                    record.getLevel().getName(),
                    threadName,
                    record.getSourceClassName(),
                    record.getSourceMethodName(),
                    record.getMessage(),
                    stackTraceToString(record)
            );
        }
    };
}

private static String stackTraceToString(LogRecord record) {
    final String throwableAsString;
    if (record.getThrown() != null) {
        var stringWriter = new StringWriter();
        var printWriter = new PrintWriter(stringWriter);
        printWriter.println();
        record.getThrown().printStackTrace(printWriter);
        printWriter.close();
        throwableAsString = stringWriter.toString();
    } else {
        throwableAsString = "";
    }
    return throwableAsString;
}

That Formatter produces log messages like these:

2019-04-27 13:21:01 INFO [AWT-EventQueue-0] package.ClassName.method: The log message

SimpleFormatter (Java Platform SE 8 ), Print a brief summary of the LogRecord in a human readable format. Formatter format string specified in the java.util.logging. representing the caller, if available; otherwise, the logger's name. logger - the logger's name. level - the log level. For example, in java.util.logging, you create a new Logger using Logger.getLogger(). getLogger() takes a string parameter that identifies the name of a Logger. If a Logger with that name already exists, then that Logger is returned; otherwise, a new Logger is created.

Java Logging Overview, Share to Facebook Share to Twitter Share to Email Share to Print Share to The Java Logging APIs, contained in the package java.util.logging, facilitate Logger objects are normally named entities, using dot-separated names such as java. awt. XMLTest</class> <method>writeLog</method> <thread>10</thread>� The java.lang.Thread.getName() method returns this thread's name. Declaration. Following is the declaration for java.lang.Thread.getName() method. public final String getName() Parameters. NA. Return Value. This method returns this thread's name. Exception. NA. Example. The following example shows the usage of java.lang.Thread.getName() method.

Logger in Java - Java Logging Example, We can create our own custom Formatter class by extending java.util.logging. addHandler(new MyHandler()); try { //FileHandler file name with max size and example program, you will notice that CONFIG log is not getting printed in file, that is LoggingExample</class> <method>main</method> <thread>1</thread> � Naming a Thread . In Java, each thread has a name i.e Thread-0, Thread-1, Thread-2,….so on. Java provides some methods to change the thread name. There are basically two methods to set the thread name. Both methods are defined in java.lang.Thread class.

Java Logging Basics |, For example, Apache Tomcat is hard-coded to use java.util.logging, although you can redirect logs getLogger() takes a string parameter that identifies the name of a Logger . This causes the Logger to print the following output to the console . The Thread class contains two methods that provide the ability to specify an� The following examples show how to use java.util.logging.XMLFormatter.These examples are extracted from open source projects.

Comments
  • I believe, using log4j or slf4j will be cleaner than the suggested solutions in the answers. :)
  • It's true that SimpleFormatter does not use the thread ID. But it's easy to define a custom formatter and get the thread name via the thread ID. No need for embarrassment :-)
  • Won't this put in the thread name of the thread calling the formatter and not the thread name of the thread that created the log entry? I guess they could be the same in some situations but there's no guarantee.
  • I was under the impression that it was best to not let constructors throw exceptions, as per Be wary of letting constructors throw exceptions
  • I do agree on that. Thanks for pointing it out @Scratte
  • LogRecord.getThreadID() does return a meaningful thread ID. You can correlate the ID with the Thread object using, for example, Thread.getAllStackTraces.
  • Thread.currentThread() is not necessarily the same thread as the one where the log message originated.