如何输出当前 java.util.logging.Logger 日志文件名的名称?

How can I output the name of the current java.util.logging.Logger log file name?

我有一个工具 运行 在多个 JVM 中,但记录到相同的 %t(临时)目录。我在 logging.properties 文件中使用 %u(唯一)模式变量,以便每个实例记录到不同的日志文件。

如果进程发现故障(这是一个监控工具),它会发送一封电子邮件,我想附上遇到故障的特定实例的日志文件。但是如何获取日志文件路径呢?如果这不是一个好方法,也很高兴接受是一种更好的方法。

JDK-4798814 getFiles() needed for java.util.logging.FileHandler 下向 Oracle 提交的 RFE 涵盖了这一点。

如果你没有使用安全管理器,你可以求助于反射。

public class GetFileHandler extends FileHandler {

    public GetFileHandler() throws IOException {
        super();
    }

    /**
     * Gets the files used by this handler.  Index zero is the file that is
     * in use.
     *
     * @return a array of files.
     * @throws IOException if there is an error.
     * @throws SecurityException if not allowed.
     */
    public File[] getFiles() throws IOException {
        return GetFileHandler.getFiles(this);
    }

    /**
     * Gets the files used by this handler.  Index zero is the file that is
     * in use.
     *
     * @param h any non null FileHandler.
     * @return a array of files.
     * @throws NullPointerException if the given FileHandler is null.
     * @throws IOException if there is an error.
     * @throws SecurityException if not allowed.
     */
    public static File[] getFiles(FileHandler h) throws IOException {
        try {
            Field f = FileHandler.class.getDeclaredField("files");
            f.setAccessible(true);
            synchronized (h) {
                return ((File[]) f.get(h)).clone();
            }
        } catch (ReflectiveOperationException roe) {
            throw new IOException(roe);
        }
    }
}

请记住,此解决方案可能会与文件轮换竞争。如果更改 FileHandler 源代码,它也可能会中断。

如果您不需要旋转,那么您可以随时扩展 StreamHandler 并提供已知的文件位置。

public class KnownFileHandler extends StreamHandler {

    private final File file;

    public KnownFileHandler() throws IOException {
        String v = LogManager.getLogManager().getProperty(getClass().getName() +".name");
        if(v == null) {
            v = "knownfilehandler.log";
        }
        file = new File(v);
        this.setOutputStream(new FileOutputStream(file));
    }


    public File getFile() {
        return this.file;
    }
}

如果监控工具支持传入的 TCP 连接,那么 java.util.logging.SocketHandler 将是一种将所有日志信息发送到监控工具的方法,然后您可以让监控工具决定存储或发送日志的位置日志数据。