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。