简体   繁体   中英

Subclassing java.util.logging.Formatter doesn't work

I am using java.util.logging for logging (I don't want to use log4j or anything else).

This is my complete private logging.properties:

handlers= java.util.logging.FileHandler
.level= INFO
java.util.logging.FileHandler.pattern = my.log
java.util.logging.FileHandler.limit = 500000
java.util.logging.FileHandler.count = 40
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

This is the code in my program:

public static Logger log = Logger.getLogger(MyClass.class.getName());
// Is there anything else to be init'ed here? 
// I don't. I just start using log directly in the code.

log.severe("something");
log.info("something else");

Since this gives each log message on 2 lines, I tried this

How do I get java logging output to appear on a single line?

Copied the LogFormatter class in the first reply exactly.

Changed one line in my logging.properties

java.util.logging.FileHandler.formatter = com.mycomp.myproj.LogFormatter;

Now my log has started appearing in XML. I have a strong feeling that the FileHandler doesn't like my com.mycomp.myproj.LogFormatter and hence defaulting to the default XMLFormatter . How do I figure out why FileHandler isn't using my LogFormatter class?

How do I figure out why FileHandler isn't using my LogFormatter class?

Start the program in a debugger and step through the code. Set a breakpoint in LogManager.getLogger() and/or LogManager.readConfiguration()

Or forget about java.util.logging and use a framework like logback that is easy to configure and gives you useful error messages when something is wrong.

You can set the formatter in the code itself on the FileHandler instance.

import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

// please change name of your own choice
Logger log = Logger.getLogger("CustomLogger"); 
log.setUseParentHandlers(false);
log.setLevel(Level.ALL);

FileHandler handler = new FileHandler("[log_file_location]");
handler.setFormatter(new CustomFormatter()); // set formatter
log.addHandler(handler);

log.info("test message");

handler.close(); // close the handler at some later point in your application.

The CustomFormatter class is defined as follows.

import java.util.logging.Formatter;
import java.util.logging.LogRecord;

public class CustomFormatter extends Formatter {

    @Override
    public String format(LogRecord record) {
        StringBuffer buffer = new StringBuffer();
        buffer.append(record.getMessage());
        return buffer.toString();
    }

}

You can code in CustomFormatter to output the messages in any format you want. Hope this helps.

Ok this one really annoyed me too, and was driving me nuts, I was checking the spelling endlessly, doing google searching etc - which is how I got here - I know this is a year old, but your going to kick yourself. Here is what I am pretty sure is your answer.

For :

java.util.logging.FileHandler.formatter = com.mycomp.myproj.LogFormatter;

That should be :

java.util.logging.FileHandler.formatter = com.mycomp.myproj.LogFormatter

Drop the training ";". It seems to need to match exactly to the class name I saw someone else complain they had trailing white space characters - which was what my problem was. A better error message would have been helpful.

Cheers - Mark

com.mycomp.myproj.LogFormatter is not in your system class path.

LogManager will do the following call for loading your class:

Formatter getFormatterProperty(String name, Formatter defaultValue) {
        String val = getProperty(name);
        try {
            if (val != null) {
                Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(val);
                return (Formatter) clz.newInstance();
            }
        } catch (Exception ex) {
            // We got one of a variety of exceptions in creating the
            // class or creating an instance.
            // Drop through.
        }
        // We got an exception.  Return the defaultValue.
        return defaultValue;
}

You need to make sure your class LogFormatter is in the system's class path.

I found that unless you set the format via the config, it does not apply the formatter. I tested this on JDK 11.

handlers= java.util.logging.FileHandler
.level= INFO
java.util.logging.FileHandler.pattern = my.log
java.util.logging.FileHandler.limit = 500000
java.util.logging.FileHandler.count = 40
java.util.logging.FileHandler.formatter = com.mycomp.myproj.LogFormatter
com.mycomp.myproj.LogFormatter.format = %n

ie add the last line com.mycomp.myproj.LogFormatter.format = %n

May be this is not relevant at this point but recently I have found one issue where $ in the format caused me a problem and it could not parse and fallen back to default format. Originally I had

[%1$tF %1$tT] [%4$-7s] %5$s %n

in logging.properties file which did not work as expected but

[%1\$tF %1\$tT] [%4\$-7s] %5\$s %n

this worked perfectly with \$ . May be it will be helpful for others in future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM