我使用标准的Java日志记录api,即java.util.logging
。
关于这一点的教程,我发现使用extends Formatter
,但在java 8 Formatter中是最终的。
我想要的是创建自己的类来确定在控制台中发送的消息的格式。这是我未完成的初始化日志记录的代码:
// Init logger
{
// get the global logger to configure it
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
// Remove all old/default loggers
Logger rootLogger = Logger.getLogger("");
java.util.logging.Handler[] handlers = rootLogger.getHandlers();
for(java.util.logging.Handler h: handlers)
rootLogger.removeHandler(h);
logger.addHandler(new ConsoleLoggerBase());
}
这是我登录stdout的课程:
package cz.autoclient.logging;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
public class ConsoleLoggerBase extends Handler {
@Override
public void publish(LogRecord record) {
System.out.println(record.getMessage());
}
@Override
public void flush() {
System.out.flush();
}
// No need to close system.out
@Override
public void close() throws SecurityException {}
}
但程序日志是空的......我很惊讶在互联网上找不到关于此的简明信息。任何人都可以解释我应该如何使用这个API?
答案 0 :(得分:0)
您必须始终hold a strong non-local reference要修改的记录器。否则,您的记录器可能会与新连接的处理程序一起被垃圾收集。
中所述记录器会在日志记录命名空间中跟踪其父记录器。记录器的父级是其在日志记录命名空间中最近的现存祖先。根记录器(名为"")没有父记录。
您正在将处理程序附加到GLOBAL_LOGGER_NAME
。全局记录器的父级是根记录器。通常情况下,全局记录器没有子节点,除非您直接写入全局记录器,否则您将看不到任何输出。我的建议是忘记使用全局记录器。而是专注于修改根记录器的输出格式,并让应用程序代码创建命名记录器。
您不必创建自定义处理程序。而是创建一个自定义格式化程序并将其安装在连接到根记录器的ConsoleHandler上。
以下是一个示例程序:
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
public class ModifyRoot {
private static final Logger[] PINNED_LOGGERS;
static {
//Assuming the default config file.
PINNED_LOGGERS = new Logger[]{
Logger.getLogger(""),
Logger.getLogger(ModifyRoot.class.getName())
};
for (Logger l : PINNED_LOGGERS) {
for (Handler h : l.getHandlers()) {
if (h instanceof ConsoleHandler) {
h.setFormatter(new DynamicFormatter());
h.setLevel(Level.ALL);
}
}
}
//Safe because it is already pinned.
Logger.getLogger(ModifyRoot.class.getName()).setLevel(Level.ALL);
}
private static class DynamicFormatter extends java.util.logging.Formatter {
@Override
public String format(LogRecord record) {
if (isJumpSite(record)) {
return record.getSourceClassName() + '.'
+ record.getSourceMethodName() + ' '
+ formatMessage(record) + System.lineSeparator();
} else {
return formatMessage(record) + System.lineSeparator();
}
}
private boolean isJumpSite(LogRecord record) {
//Check the raw message not the formatted message.
final String msg = String.valueOf(record.getMessage());
return msg.startsWith("ENTRY") || msg.startsWith("RETURN")
|| msg.startsWith("THROW");
}
}
//========
private static final String CLASS_NAME = ModifyRoot.class.getName();
private static final Logger logger = Logger.getLogger(CLASS_NAME);
public static void main(String[] args) {
logger.entering(CLASS_NAME, "main");
logger.info("Hello World!");
logger.exiting(CLASS_NAME, "main");
}
}
哪个输出:
ModifyRoot.main ENTRY
Hello World!
ModifyRoot.main RETURN
您应该考虑使用java.util.logging.config.file系统属性配置记录器并创建自己的logging.properties
文件。