如何修改java.util.logging.Logger控制台输出的颜色?
Hey there, I totally get your frustration with java.util.logging making all console output red—no one wants info logs screaming at them like errors! Let's fix this without ditching the logger entirely, since using proper logging is way more scalable than System.out.println.
The root of the problem is that the default ConsoleHandler in java.util.logging uses System.err for all output, which most terminals render in red. We have two solid solutions to fix this:
Solution 1: Switch Output Streams by Log Level
We can create a custom ConsoleHandler that sends severe/warning logs to System.err (red) and all other levels to System.out (your terminal's default text color, usually white/gray).
Here's the custom handler code:
import java.util.logging.*; import java.io.IOException; public class LevelAwareConsoleHandler extends ConsoleHandler { @Override public void publish(LogRecord record) { if (!isLoggable(record)) { return; } try { // Route warnings/severes to System.err, everything else to System.out if (record.getLevel().intValue() >= Level.WARNING.intValue()) { super.setOutputStream(System.err); } else { super.setOutputStream(System.out); } super.publish(record); flush(); } catch (SecurityException e) { reportError(null, e, ErrorManager.FLUSH_FAILURE); } } }
Then, replace the default handler in your code:
Logger logger = Logger.getLogger(YourClassName.class.getName()); // Remove the default ConsoleHandler first for (Handler handler : logger.getParent().getHandlers()) { if (handler instanceof ConsoleHandler) { logger.getParent().removeHandler(handler); } } // Add our custom handler LevelAwareConsoleHandler customHandler = new LevelAwareConsoleHandler(); customHandler.setFormatter(new SimpleFormatter()); // Keep or customize the format logger.addHandler(customHandler); logger.setLevel(Level.ALL);
Solution 2: Add ANSI Color Codes for Granular Control
If you want more color customization (like yellow for warnings, green for info), you can use ANSI escape codes in a custom formatter. Most modern terminals (Windows Terminal, macOS Terminal, Linux shells) support these.
First, create a colored formatter:
import java.util.logging.*; public class ColoredLogFormatter extends SimpleFormatter { // ANSI color escape codes private static final String ANSI_RESET = "\u001B[0m"; private static final String ANSI_RED = "\u001B[31m"; private static final String ANSI_YELLOW = "\u001B[33m"; private static final String ANSI_GREEN = "\u001B[32m"; @Override public String format(LogRecord record) { String levelColor; switch (record.getLevel().getName()) { case "SEVERE": levelColor = ANSI_RED; break; case "WARNING": levelColor = ANSI_YELLOW; break; case "INFO": levelColor = ANSI_GREEN; break; default: // CONFIG, FINE, FINER, FINEST levelColor = ANSI_RESET; break; } // Wrap the level in color, then append the log message return String.format("%s%s%s: %s%n", levelColor, record.getLevel().getName(), ANSI_RESET, super.formatMessage(record)); } }
Then attach this formatter to a standard ConsoleHandler:
Logger logger = Logger.getLogger(YourClassName.class.getName()); // Remove default handler for (Handler handler : logger.getParent().getHandlers()) { if (handler instanceof ConsoleHandler) { logger.getParent().removeHandler(handler); } } ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setFormatter(new ColoredLogFormatter()); logger.addHandler(consoleHandler); logger.setLevel(Level.ALL);
Bonus: Configure via logging.properties
If you prefer not to modify code, you can set up these custom handlers/formatters in your logging.properties file:
# Replace default handlers with our custom one handlers = com.yourpackage.LevelAwareConsoleHandler # Set the formatter for our handler com.yourpackage.LevelAwareConsoleHandler.formatter = com.yourpackage.ColoredLogFormatter
Either approach will let you keep using java.util.logging properly, with the color differentiation you want—no need to go back to System.out.println!
内容的提问来源于stack exchange,提问作者Steve Staple

