Java 如何使用我的日志格式创建我自己的自定义控制台记录器?
我使用标准的Java日志api,即Java 如何使用我的日志格式创建我自己的自定义控制台记录器?,java,logging,Java,Logging,我使用标准的Java日志api,即Java.util.logging 我发现这方面的教程使用了扩展格式化程序,但是在Java8中格式化程序是最终的 我想要的是创建自己的类,该类确定在控制台中发送的消息的格式。这是我初始化日志记录的未完成代码: // Init logger { // get the global logger to configure it Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
Java.util.logging
我发现这方面的教程使用了扩展格式化程序
,但是在Java8中格式化程序是最终的
我想要的是创建自己的类,该类确定在控制台中发送的消息的格式。这是我初始化日志记录的未完成代码:
// 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());
}
这是我登录标准输出的类:
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吗?您必须始终向正在修改的日志记录者报告。否则,您的记录器可以与新连接的处理程序一起被垃圾收集
正如报告中所述:
日志记录器在日志命名空间中跟踪其父日志记录器。记录器的父级是其在日志名称空间中最近的现存祖先。根记录器(名为“”)没有父级
您正在将处理程序附加到全局\u记录器\u名称
。全局记录器的父级是根记录器。通常,全局记录器没有子项,因此,除非直接向全局记录器写入数据,否则不会看到任何输出。我的建议是忘记使用全局记录器。相反,请关注修改根记录器的输出格式,并让应用程序代码创建命名记录器
您不必创建自定义处理程序。而是创建一个自定义格式化程序,并将其安装在连接到根记录器的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
您应该考虑使用系统属性配置日志,并创建自己的代码>日志记录。属性文件。
< p>您必须始终对正在修改的记录器进行修改。否则,您的记录器可以与新连接的处理程序一起被垃圾收集 正如报告中所述: 日志记录器在日志命名空间中跟踪其父日志记录器。记录器的父级是其在日志名称空间中最近的现存祖先。根记录器(名为“”)没有父级 您正在将处理程序附加到全局\u记录器\u名称
。全局记录器的父级是根记录器。通常,全局记录器没有子项,因此,除非直接向全局记录器写入数据,否则不会看到任何输出。我的建议是忘记使用全局记录器。相反,请关注修改根记录器的输出格式,并让应用程序代码创建命名记录器
您不必创建自定义处理程序。而是创建一个自定义格式化程序,并将其安装在连接到根记录器的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
你应该考虑使用系统属性配置日志记录器并创建自己的代码>日志记录。属性< /COD>文件。< /P>你错了。是最终的,但不是。你错了。是最终的,但不是。