Java JUL logging-消息上的实例前缀
我想让我的记录器在每条消息上加上一个文本字符串前缀,因为我需要确定哪个类实例记录了该消息。我怎样才能做到这一点 我不想在每次日志方法调用时都记住添加前缀,所以我正在寻找一种更像是插入的解决方案。当然,记录器本身不能再像正常情况那样是静态的 我已经调查了Java JUL logging-消息上的实例前缀,java,logging,java.util.logging,Java,Logging,Java.util.logging,我想让我的记录器在每条消息上加上一个文本字符串前缀,因为我需要确定哪个类实例记录了该消息。我怎样才能做到这一点 我不想在每次日志方法调用时都记住添加前缀,所以我正在寻找一种更像是插入的解决方案。当然,记录器本身不能再像正常情况那样是静态的 我已经调查了Fomatters和Handlers的使用情况,但是没有能够解决这个特定用例的问题。JUL基本上是为类级记录器设计的,而不是为实例级记录器设计的。也许我走错了方向 我想和七月住在一起 我已经调查了Fomatters和handler的使用,但是还没有
Fomatter
s和Handler
s的使用情况,但是没有能够解决这个特定用例的问题。JUL基本上是为类级记录器设计的,而不是为实例级记录器设计的。也许我走错了方向
我想和七月住在一起
我已经调查了Fomatters和handler的使用,但是还没有能够解决这个特定用例的问题。JUL基本上是为类级记录器设计的,而不是为实例级记录器设计的。也许我走错了方向
JUL只包含两个格式化程序。包含记录器名称。包含可设置为包含记录器名称的format属性。这里有一个测试程序,以确保您已正确设置了所有内容
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
public class SimpleFormatTest {
public static void main(String[] args) throws Exception {
//final String format = "%1$ta %1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS.%1$tL %1$Tp %2$s%n%4$s: %5$s%n";
final String format = "%1$tc %2$s%n%3$s %4$s: %5$s%6$s%n";
final String key = "java.util.logging.SimpleFormatter.format";
test(format);
test(System.getProperty(key, format));
test(LogManager.getLogManager().getProperty(key));
}
private static void test(String format) {
if (format != null) {
System.out.println("============");
LogRecord record = new LogRecord(Level.INFO, "msg");
record.setLoggerName("logger.name");
record.setSourceClassName(SimpleFormatTest.class.getName());
record.setSourceMethodName("test");
System.out.println(String.format(format,
new java.util.Date(record.getMillis()),
record.getSourceClassName(),
record.getLoggerName(),
record.getLevel().getLocalizedName(),
record.getMessage(),
record.getThrown() == null ? "" : record.getThrown()));
System.out.println("============");
}
}
}
但我正在寻找一种在消息文本中包含前缀的解决方案。我不知道用户想要使用什么格式化程序,他可能会选择不记录记录器名称(相比之下,没有人会创建忽略消息文本的格式化程序)
在应用程序中包含logging.properties
。您可以添加一个先决条件检查,以禁止代码工作。这将迫使用户设置配置
public class NoStart {
public static void main(String[] args) throws IOException {
String id = "logger.name";
LogRecord record = new LogRecord(Level.INFO, "msg");
record.setLoggerName(id);
File f = File.createTempFile("test", ".tmp");
try {
FileHandler fh = new FileHandler(f.getCanonicalPath(), false);
try {
Formatter fmt = fh.getFormatter();
String r = fmt.format(record);
if (!r.contains(id)) {
throw new IllegalStateException("Formatter must contain logger name.");
}
} finally {
fh.close();
}
} finally {
f.delete();
}
}
}
否则,您可以创建自定义筛选器来修改LogRecord消息
public class PrefixMessageFilter implements Filter {
private final String instanceId;
private final Filter target;
public PrefixMessageFilter(final String instanceId, final Filter target) {
this.instanceId = instanceId;
this.target = target;
}
@Override
public boolean isLoggable(LogRecord record) {
record.setMessage(instanceId + ' ' + record.getMessage());
return target == null || target.isLoggable(record);
}
//Example code to setup filter.
private Logger logger = Logger.getLogger(toString());
{
logger.setFilter(new PrefixMessageFilter(toString(), logger.getFilter()));
}
}
您只需在首次使用时修改记录器。您可以使用实例名称而不是类名初始化基于实例的记录器对象,然后将记录器名称包括在输出中。@DodgyCodeException。正确的。但是我正在寻找一种解决方案,在
message
文本中包含前缀。我不知道用户想要使用什么格式化程序,他可能会选择不记录记录器名称(相比之下,没有人会创建忽略消息文本的格式化程序)。您的回答中有一些有趣的想法。我正在调查。但是,我必须说我不同意“JUL假设您正在打包并设置应用程序的logging.properties”。在我看来,这个想法是操作员(即不是开发人员)可以自定义它,以适应他所处的执行环境的要求。@peterh我当然明白你的意思。我试图传达的要点是JVM包含一个用于其上下文的配置。Tomcat包含其上下文的配置,部署在Tomcat中的web应用可以包含其上下文的配置。该示例中的每个层都将映射到操作员角色。所以我的意思是,也许你应该为你的上下文提供一个启动配置,操作员可以对此进行调整。该配置将包括格式化为包含记录器名称的SimpleFormat。