You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by bu...@apache.org on 2014/08/29 14:24:46 UTC
[Bug 45934] FileAppender should use virtual-machine shutdown hook
that flushes buffer automatically
https://issues.apache.org/bugzilla/show_bug.cgi?id=45934
--- Comment #2 from Jesus Alejandre <al...@gmail.com> ---
Comment on attachment 22667
--> https://issues.apache.org/bugzilla/attachment.cgi?id=22667
Patch to FileAppender.java that produces implementation of proposed feature.
>Index: src/main/java/org/apache/log4j/FileAppender.java
>===================================================================
>--- src/main/java/org/apache/log4j/FileAppender.java (revision 701074)
>+++ src/main/java/org/apache/log4j/FileAppender.java (working copy)
>@@ -17,14 +17,21 @@
>
> package org.apache.log4j;
>
>-import java.io.*;
>+import java.io.BufferedWriter;
>+import java.io.File;
>+import java.io.FileNotFoundException;
>+import java.io.FileOutputStream;
>+import java.io.IOException;
>+import java.io.InterruptedIOException;
>+import java.io.Writer;
>
>-import org.apache.log4j.spi.ErrorCode;
>-import org.apache.log4j.helpers.QuietWriter;
> import org.apache.log4j.helpers.LogLog;
>+import org.apache.log4j.helpers.QuietWriter;
>+import org.apache.log4j.spi.ErrorCode;
>
> // Contibutors: Jens Uwe Pipka <je...@gmx.de>
> // Ben Sandee
>+// Martin Burger <m...@rtin-burger.de>
>
> /**
> * FileAppender appends log events to a file.
>@@ -60,6 +67,11 @@
> */
> protected int bufferSize = 8*1024;
>
>+ /**
>+ * Do we use shutdown hook to flush buffer automatically?
>+ */
>+ protected boolean useShutdownHook = false;
>+
>
> /**
> The default constructor does not do anything.
>@@ -85,7 +97,7 @@
> FileAppender(Layout layout, String filename, boolean append, boolean bufferedIO,
> int bufferSize) throws IOException {
> this.layout = layout;
>- this.setFile(filename, append, bufferedIO, bufferSize);
>+ this.setFile(filename, append, bufferedIO, bufferSize, useShutdownHook);
> }
>
> /**
>@@ -101,7 +113,7 @@
> FileAppender(Layout layout, String filename, boolean append)
> throws IOException {
> this.layout = layout;
>- this.setFile(filename, append, false, bufferSize);
>+ this.setFile(filename, append, false, bufferSize, useShutdownHook);
> }
>
> /**
>@@ -156,7 +168,7 @@
> void activateOptions() {
> if(fileName != null) {
> try {
>- setFile(fileName, fileAppend, bufferedIO, bufferSize);
>+ setFile(fileName, fileAppend, bufferedIO, bufferSize, useShutdownHook);
> }
> catch(java.io.IOException e) {
> errorHandler.error("setFile("+fileName+","+fileAppend+") call failed.",
>@@ -167,6 +179,10 @@
> LogLog.warn("File option not set for appender ["+name+"].");
> LogLog.warn("Are you using FileAppender instead of ConsoleAppender?");
> }
>+
>+ if (this.bufferedIO && this.useShutdownHook) {
>+ Runtime.getRuntime().addShutdownHook(new FileAppenderShutdownHook(this));
>+ }
> }
>
> /**
>@@ -176,6 +192,9 @@
> void closeFile() {
> if(this.qw != null) {
> try {
>+ if (this.bufferedIO && this.useShutdownHook) {
>+ this.qw.flush();
>+ }
> this.qw.close();
> }
> catch(java.io.IOException e) {
>@@ -210,6 +229,15 @@
> return this.bufferSize;
> }
>
>+ /**
>+ Get the value of the <b>ShutdownHook</b> option.
>+
>+ */
>+ public
>+ boolean getShutdownHook() {
>+ return this.useShutdownHook;
>+ }
>+
>
>
> /**
>@@ -255,6 +283,43 @@
> }
>
> /**
>+ The <b>ShutdownHook</b> option takes a boolean value. It is set to
>+ <code>false</code> by default. If <code>true</code> and <code>BufferedIO</code>
>+ is set to <code>true</code> as well, a virtual-machine shutdown hook will
>+ be registered that flushes and closes the underling stream.
>+
>+ <p>Use this option to avoid lost log messages.</p>
>+
>+ @see WriterAppender#setImmediateFlush(boolean)
>+ */
>+ public
>+ void setShutdownHook(boolean shutdownHook) {
>+ this.useShutdownHook = shutdownHook;
>+ }
>+
>+
>+ /**
>+ <p>Sets and <i>opens</i> the file where the log output will
>+ go. The specified file must be writable.
>+
>+ <p>If there was already an opened file, then the previous file
>+ is closed first.
>+
>+ <p><b>Do not use this method directly. To configure a FileAppender
>+ or one of its subclasses, set its properties one by one and then
>+ call activateOptions.</b>
>+
>+ @param fileName The path to the log file.
>+ @param append If true will append to fileName. Otherwise will
>+ truncate fileName. */
>+ public
>+ synchronized
>+ void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
>+ throws IOException {
>+ this.setFile(fileName, append, bufferedIO, bufferSize, useShutdownHook);
>+ }
>+
>+ /**
> <p>Sets and <i>opens</i> the file where the log output will
> go. The specified file must be writable.
>
>@@ -270,7 +335,7 @@
> truncate fileName. */
> public
> synchronized
>- void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
>+ void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize, boolean shutdownHook)
> throws IOException {
> LogLog.debug("setFile called: "+fileName+", "+append);
>
>@@ -313,6 +378,7 @@
> this.fileAppend = append;
> this.bufferedIO = bufferedIO;
> this.bufferSize = bufferSize;
>+ this.useShutdownHook = shutdownHook;
> writeHeader();
> LogLog.debug("setFile ended");
> }
>@@ -338,5 +404,20 @@
> this.fileName = null;
> super.reset();
> }
>+
>+
>+ private static class FileAppenderShutdownHook extends Thread {
>+
>+ private final FileAppender appender;
>+
>+ public FileAppenderShutdownHook(FileAppender appender) {
>+ this.appender = appender;
>+ }
>+
>+ public void run() {
>+ this.appender.close();
>+ }
>+ }
>+
> }
>
>
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org