audit4j / audit4j-core

An open source auditing framework.
http://audit4j.org
Apache License 2.0
126 stars 76 forks source link

ZeroCopyFileWriter leaks file handlers #93

Open agori opened 4 years ago

agori commented 4 years ago

Basically that AuditFileWriter implementation opens new files on every attempt and never closes them. After some time the server crashes because of "too many open files". I have to say this is a quite bewildering and severe bug for an audit library, whose purpose is, after all, to write to a file.

To me this method is clearly the culprit:

   @Override
    public ZeroCopyFileWriter write(String event) {
//        String realPath = FileHandlerUtil.generateOutputFilePath(path);

        String realPath = FileHandlerUtil.generateOutputFilePath(
                path, 
                FileHandlerUtil.generateAuditFileName());

        try {
            if (FileHandlerUtil.isFileAlreadyExists(realPath)) {
                randomAccessFile = new RandomAccessFile(realPath, CoreConstants.READ_WRITE);
            } else {
                randomAccessFile = new RandomAccessFile(new File(realPath), CoreConstants.READ_WRITE);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        fileChannel = randomAccessFile.getChannel();

        String str2 = event + CoreConstants.NEW_LINE;

        long numBytes = str2.getBytes().length;

        InputStream inputStream = new ByteArrayInputStream(str2.getBytes(Charset.forName("UTF-8")));

        try {

            // move the cursor to the end of the file
            randomAccessFile.seek(randomAccessFile.length());

            // obtain the a file channel from the RandomAccessFile
            try (ReadableByteChannel inputChannel = Channels.newChannel(inputStream);) {
                fileChannel.transferFrom(inputChannel, randomAccessFile.length(), numBytes);
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return this;
    }