问题
my question is similar to Why does java.util.logging.Logger print to stderr? post. I want to use only one handler in my logging, where as it should print INFO statements on to out stream and WARNING & SEVERE onto error stream. Is this possible ? If I take two handlers for example, one for out stream - and level as INFO another for error stream - and level as WARNING/SEVERE in this case, application is showing messages twice one with out stream and another with error stream. So any solution ?
回答1:
This is possible with one or two handlers. The missing part is that you need to create a filter for the OUT handler that limits the highest level. Also you need to make sure there are no other ConsoleHandlers attached to the root logger which can pollute your test. You can print the logger tree to see what handlers are attached.
Here is a proof of concept:
import java.io.PrintStream;
import java.util.logging.ConsoleHandler;
import java.util.logging.Filter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
public class OutErrorTest {
private static final Logger log = Logger.getLogger("");
public static void main(String[] args) {
LogManager.getLogManager().reset(); //A quick way to remove all handlers.
Handler out = newSystemOut();
Handler err = newSystemErr();
final Level fence = Level.WARNING;
out.setLevel(Level.ALL);
out.setFilter(new LessThanLevelFilter(fence));
err.setLevel(fence);
log.addHandler(out);
log.addHandler(err);
log.setLevel(Level.ALL);
log.finest("Finest Log");
log.finer("Finer Log");
log.fine("Fine Log");
log.config("Config Log");
log.info("Info Log");
log.warning("Warning Log");
log.severe("Severe Log");
}
private static Handler newSystemErr() {
return new ConsoleHandler();
}
private static Handler newSystemOut() {
Handler h = null;
final PrintStream err = System.err;
System.setErr(System.out);
try {
h = new ConsoleHandler(); // Snapshot of System.err
} finally {
System.setErr(err);
}
return h;
}
public static class LessThanLevelFilter implements Filter {
private final int lvl;
public LessThanLevelFilter(final Level max) {
this(max.intValue());
}
public LessThanLevelFilter(final int max) {
this.lvl = max;
}
@Override
public boolean isLoggable(LogRecord r) {
return r.getLevel().intValue() < lvl;
}
}
}
来源:https://stackoverflow.com/questions/60648631/logging-handler-usage