简体   繁体   中英

Find log file name at run time with Java 9 JDK Logging

I have the same question as Find actual opened logfile with JDK Logging , except that I want to use an API that's supported by Java 9.

In Java 8, I currently use nearly the same reflection hack as described in the answer to that question except that I look at the actual log file name instead of parsing the lockFileName.

Here's my code:

private static String logFileName = null;

public static String getLogFileName() {
    // determined on demand and cached so we only need to do all of this the first time.
    if (logFileName == null) {
        for (Handler handler : Logger.getLogger("").getHandlers()) {
            if (handler.getClass().isAssignableFrom(FileHandler.class)) {
                FileHandler fileHandler = (FileHandler) handler;
                try {
                    // FileHandler.files has private access, 
                    // so I'm going to resort to reflection to get the file name.
                    Field privateFilesField = fileHandler.getClass().getDeclaredField("files");
                    privateFilesField.setAccessible(true); // allow access to this private field
                    File[] files = (File[]) privateFilesField.get(fileHandler);
                    logFileName = files[0].getCanonicalPath();
                    break;
                } catch (NullPointerException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | IOException ex) {
                    logger.log(Level.SEVERE, "Unable to determine log file name.", ex);
                }
            }
        }
        if (logFileName == null) {
            logFileName = "your home directory"; // just be sure it's not null
            logger.warning("Unable to identify log file name.");
        }
    }
    return logFileName;
}

The reflection hack works fine in both Java 8 & 9, but in Java 9, it generates the following warning which I'd prefer to fix rather than ignore with the --illegal-access=permit flag.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.foo.MyApp (file:/C:/Users/me/Documents/foo/build/classes/java/main/) to field java.util.logging.FileHandler.files
WARNING: Please consider reporting this to the maintainers of org.foo.MyApp
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Any ideas? Thanks.

如果特定于Linux的解决方案足够好,您可以尝试解析/proc/self/fd/的伪符号链接,其中之一应该是当前打开的日志文件,与日志文件模式匹配。

There are several ways to do this:

  1. File a change request with the JDK to allow access to the field (at least make it protected so you can read it in a subclass).
  2. Parse the properties file used to configure the appender. You will have to copy some of the logic out of the Java 9 code but chances are that this code won't change for a long time (backwards compatibility).
  3. Copy a lot of code out of the logging API so you can write your own FileHandler which allows access to the field. While at it, you could also add code to iterate over all appenders.
  4. Use a different logging framework.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM