问题描述
以下是我的记录器的代码。记录到文件工作正常,但控制台处理程序不会打印任何低于 Level.INFO 的消息。
this.rxStompService.watch('/topic/demo').subscribe((message: Message) => {
this.receivedMessages.push(message.body);
});
我用 public class ServerLogger {
/*
* Log file size
*/
final private static int FILE_SIZE = 1024 * 100;
/**
* Creates and return server logger
*
* @param dir log files directory
* @param consoleEnabled if set to true then logging to console is enabled
* @param debugEnabled if set to true then debug level of logging is enabled
*
* @return sever logger
*
* @throws SecurityException
* @throws IOException
*/
public static Logger getLogger(final String dir,final boolean consoleEnabled,final boolean debugEnabled)
throws SecurityException,IOException {
Logger logger = Logger.getLogger(Server.class.getName());
logger.setUseParentHandlers(false);
/*
* remove all handlers if any
*/
Handler[] handlers = logger.getHandlers();
if (handlers.length > 0) {
for (Handler handler : handlers)
logger.removeHandler(handler);
}
/*
* create formatter
*/
Formatter formatter = new LineFormatter();
/*
* if console logging is enabled then add console handler
*/
if (consoleEnabled) {
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
logger.addHandler(consoleHandler);
}
/*
* add file handler
*/
String nameTemplate = dir + "\\" + "server-log%g.txt";
FileHandler fileHandler = new FileHandler(nameTemplate,FILE_SIZE,10);
fileHandler.setFormatter(formatter);
logger.addHandler(fileHandler);
Level level = debugEnabled ? Level.FINE : Level.INFO;
logger.setLevel(level);
return logger;
}
static private class LineFormatter extends Formatter {
@Override
public String format(LogRecord record) {
return String.format("[%1$tF %1$tT] [%4$-7s] %5$s %n",record.getMillis(),record.getSourceMethodName(),record.getLoggerName(),record.getLevel(),record.getMessage(),record.getThrown());
}
};
public static void main(String[] args) throws SecurityException,IOException {
//test
Logger logger = ServerLogger.getLogger("C:\\logs",true,true);
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
替换了 ConsoleHandler
但这没有帮助。
用 StreamHandler
替换 logger.setLevel(level)
也无济于事。使用 logger.setLevel(Level.ALL)
设置处理程序级别不会改变某些内容。
控制台上的消息是:
handler.set(Level level)
你能帮忙吗。
解决方法
总是固定你的记录器,这样它就不会被垃圾收集。这是这样做的:
private static final Logger logger = Logger.getLogger(Server.class.getName());
如果记录器被垃圾收集,您的所有更改都将丢失并回退到 logging.properties。
下一个问题是,如果您以编程方式删除处理程序,您也必须关闭它们。
if (handlers.length > 0) { //The if is not needed,just the for loop.
for (Handler handler : handlers) {
logger.removeHandler(handler);
handler.close(); //Don't leak resources.
}
}
下一个问题是您必须将控制台处理程序级别设置为所有:
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
consoleHandler.setLevel(Level.ALL);
//consoleHandler.setLevel(debugEnabled ? Level.FINE : Level.INFO); //This would work too.
这允许您的处理程序接受低于 INFO 的日志记录。
虽然使用静态方法来设置日志配置“有效”,但您实际上只想设置一次配置。在运行时更改记录器树很不方便,可能会导致您丢失消息。您应该使用 logger configuration file,a logger class,or a static initializer block 以便配置加载一次且仅一次。
小心使用 StreamHandler + System.err 或 System.out。关闭 StreamHandler 隐式或显式将关闭它正在包装的系统流,这将停止所有输出到控制台。 ConsoleHandler 不会这样做。