Configuring Java FileHandler Logging to create directories if they do not exist

后端 未结 5 793
既然无缘
既然无缘 2020-12-17 15:45

I\'m trying to configure the Java Logging API\'s FileHandler to log my server to a file within a folder in my home directory, but I don\'t want to have to create those direc

5条回答
  •  天涯浪人
    2020-12-17 16:43

    As a possible solution I think there are 2 approaches (look at some of the previous answers). I can extend a Java Logging Handler class and write my own custom handler. I could also copy the log4j functionality and adapt it to the Java Logging framework.

    Here's an example of copying the basic FileHandler and creating a CustomFileHandler see pastebin for full class:

    The key is the openFiles() method where it tries to create a FileOutputStream and checking and creating the parent directory if it doesn't exist (I also had to copy package protected LogManager methods, why did they even make those package protected anyways):

    // Private method to open the set of output files, based on the
    // configured instance variables.
    private void openFiles() throws IOException {
        LogManager manager = LogManager.getLogManager();
    

    ...

        // Create a lock file. This grants us exclusive access
        // to our set of output files, as long as we are alive.
        int unique = -1;
        for (;;) {
            unique++;
            if (unique > MAX_LOCKS) {
                throw new IOException("Couldn't get lock for " + pattern);
            }
            // Generate a lock file name from the "unique" int.
            lockFileName = generate(pattern, 0, unique).toString() + ".lck";
            // Now try to lock that filename.
            // Because some systems (e.g. Solaris) can only do file locks
            // between processes (and not within a process), we first check
            // if we ourself already have the file locked.
            synchronized (locks) {
                if (locks.get(lockFileName) != null) {
                    // We already own this lock, for a different FileHandler
                    // object. Try again.
                    continue;
                }
                FileChannel fc;
                try {
                    File lockFile = new File(lockFileName);
                    if (lockFile.getParent() != null) {
                        File lockParentDir = new File(lockFile.getParent());
                        // create the log dir if it does not exist
                        if (!lockParentDir.exists()) {
                            lockParentDir.mkdirs();
                        }
                    }
    
                    lockStream = new FileOutputStream(lockFileName);
                    fc = lockStream.getChannel();
                } catch (IOException ix) {
                    // We got an IOException while trying to open the file.
                    // Try the next file.
                    continue;
                }
                try {
                    FileLock fl = fc.tryLock();
                    if (fl == null) {
                        // We failed to get the lock. Try next file.
                        continue;
                    }
                    // We got the lock OK.
                } catch (IOException ix) {
                    // We got an IOException while trying to get the lock.
                    // This normally indicates that locking is not supported
                    // on the target directory. We have to proceed without
                    // getting a lock. Drop through.
                }
                // We got the lock. Remember it.
                locks.put(lockFileName, lockFileName);
                break;
            }
        }
    

    ... }

提交回复
热议问题