javajava.util.logging

How to remove package name from log line?


The Java util logging uses the following output line format:

java.util.logging.SimpleFormatter.format = %4$s %2$s %n

This gives the following output, where first main is a package name, while the last main is a method name:

INFO main.MySuperPuperClassName main

How to eliminate of the package name here? So that the resulting log line would look like this:

INFO MySuperPuperClassName main

The idea is to not output the package name in the log line.


Solution

  • I’m pretty sure you cannot do this with logging properties alone. However, you can write your own Formatter class:

    import java.time.ZonedDateTime;
    import java.time.ZoneId;
    
    import java.io.StringWriter;
    import java.io.PrintWriter;
    
    import java.util.IllegalFormatException;
    
    import java.util.logging.LogManager;
    import java.util.logging.LogRecord;
    import java.util.logging.SimpleFormatter;
    
    public class NoPackageFormatter
    extends SimpleFormatter {
        private static final String FORMAT_PROPERTY =
            "java.util.logging.SimpleFormatter.format";
    
        private static final String DEFAULT_FORMAT = "%4$s %2$s%6$s%n";
        // Java SE's default for US English locale
        //private static final String DEFAULT_FORMAT =
        //    "%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%6$s%n";
    
        private static final ZoneId ZONE = ZoneId.systemDefault();
    
        private static String stripPackage(String name) {
            return name.substring(name.lastIndexOf('.') + 1);
        }
    
        @Override
        public String format(LogRecord record) {
            String formatString = System.getProperty(FORMAT_PROPERTY);
            if (formatString == null) {
                formatString =
                    LogManager.getLogManager().getProperty(FORMAT_PROPERTY);
            }
            if (formatString == null) {
                formatString = DEFAULT_FORMAT;
            }
    
            String name = record.getLoggerName();
            name = stripPackage(name);
    
            String sourceClass = record.getSourceClassName();
            String sourceMethod = record.getSourceMethodName();
            String source = sourceClass != null && sourceMethod != null ?
                stripPackage(sourceClass) + ' ' + sourceMethod : name;
    
            String stackTrace = "";
            if (record.getThrown() != null) {
                StringWriter writer = new StringWriter();
                record.getThrown().printStackTrace(new PrintWriter(writer));
                stackTrace = System.lineSeparator() + writer;
            }
    
            Object[] args = {
                record.getInstant().atZone(ZONE),
                source,
                name,
                record.getLevel().getLocalizedName(),
                formatMessage(record),
                stackTrace
            };
    
            try {
                return String.format(formatString, args);
            } catch (IllegalFormatException e) {
                return String.format(DEFAULT_FORMAT, args);
            }
        }
    }
    

    To use it, you can refer to it in logging properties:

    java.util.logging.ConsoleHandler.formatter: com.example.NoPackageFormatter
    java.util.logging.FileHandler.formatter:    com.example.NoPackageFormatter
    java.util.logging.SocketHandler.formatter:  com.example.NoPackageFormatter
    

    Or, you can set it programmatically:

    private static final Logger logger;
    
    static {
        logger = Logger.getLogger(MyApplication.class.getName());
    
        Formatter formatter = new NoPackageFormatter();
    
        for (Logger l = logger; l != null; l = l.getParent()) {
            for (Handler handler : l.getHandlers()) {
                handler.setFormatter(formatter);
            }
        }
    }