Author: carnold
Date: Sat Feb 13 18:24:46 2010
New Revision: 909868
URL: http://svn.apache.org/viewvc?rev=909868&view=rev
Log:
Bug 48704: Add purient mode to FileAppender
Added:
logging/log4j/trunk/src/main/java/org/apache/log4j/helpers/PrudentWriter.java
logging/log4j/trunk/tests/witness/prudent
- copied, changed from r909853, logging/log4j/trunk/tests/witness/simple
Modified:
logging/log4j/trunk/src/changes/changes.xml
logging/log4j/trunk/src/main/java/org/apache/log4j/FileAppender.java
logging/log4j/trunk/tests/src/java/org/apache/log4j/FileAppenderTest.java
logging/log4j/trunk/tests/src/java/org/apache/log4j/MinimumTestCase.java
Modified: logging/log4j/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/logging/log4j/trunk/src/changes/changes.xml?rev=909868&r1=909867&r2=909868&view=diff
==============================================================================
--- logging/log4j/trunk/src/changes/changes.xml (original)
+++ logging/log4j/trunk/src/changes/changes.xml Sat Feb 13 18:24:46 2010
@@ -94,6 +94,7 @@
<action action="add" issue="48187">Typo ("two three goals") in log4j
FAQ</action>
<action action="fix" issue="48531">Unit tests fail for system dates
after 2009-12-31</action>
<action action="fix" issue="48604">Download page does not have link to
KEYS file</action>
+ <action action="add" issue="48704">Add purient mode to
FileAppender.</action>
</release>
Modified: logging/log4j/trunk/src/main/java/org/apache/log4j/FileAppender.java
URL:
http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/FileAppender.java?rev=909868&r1=909867&r2=909868&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/FileAppender.java
(original)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/FileAppender.java Sat
Feb 13 18:24:46 2010
@@ -65,6 +65,12 @@
* Determines the size of IO buffer be. Default is 8K.
*/
protected int bufferSize = 8*1024;
+
+ /**
+ * Determines whether "prudent" mode used.
+ * @since 1.2.16
+ */
+ private boolean prudent = false;
/**
@@ -259,6 +265,44 @@
void setBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
}
+
+ /**
+ * Determines if the FileAppender should attempt to use
+ * java.nio.FileChannel.lock to gain exclusive access
+ * to the file during write operations. The effectiveness
+ * and performance impact is JVM and operating system dependent.
+ * Avoiding concurrent writes to the same file by appenders
+ * and streams either within or outside a single JVM
+ * is recommended.
+ *
+ * Prudent mode requires JDK 1.4 or later.
+ *
+ * @return true if prudent mode is enabled.
+ * @since 1.2.16
+ */
+ public final boolean isPrudent() {
+ return prudent;
+ }
+
+ /**
+ * Sets if the FileAppender should attempt to use
+ * java.nio.FileChannel.lock to gain exclusive access
+ * to the file during write operations. The effectiveness
+ * and performance impact is JVM and operating system dependent.
+ * Avoiding concurrent writes to the same file by appenders
+ * and streams either within or outside a single JVM
+ * is recommended.
+ *
+ * Prudent mode requires JDK 1.4 or later.
+ *
+ * @param valve true to enable prudent mode on next call to
+ * activateOptions or setFile.
+ *
+ * @since 1.2.16
+ */
+ public void setPrudent(final boolean value) {
+ prudent = value;
+ }
/**
<p>Sets and <i>opens</i> the file where the log output will
@@ -311,7 +355,9 @@
}
}
Writer fw = createWriter(ostream);
- if(bufferedIO) {
+ if (prudent) {
+ fw = new org.apache.log4j.helpers.PrudentWriter(fw, ostream);
+ } else if(bufferedIO) {
fw = new BufferedWriter(fw, bufferSize);
}
this.setQWForFiles(fw);
Added:
logging/log4j/trunk/src/main/java/org/apache/log4j/helpers/PrudentWriter.java
URL:
http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/helpers/PrudentWriter.java?rev=909868&view=auto
==============================================================================
---
logging/log4j/trunk/src/main/java/org/apache/log4j/helpers/PrudentWriter.java
(added)
+++
logging/log4j/trunk/src/main/java/org/apache/log4j/helpers/PrudentWriter.java
Sat Feb 13 18:24:46 2010
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.helpers;
+
+import java.io.FileOutputStream;
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+
+/**
+ * An implementation of the "prudent" mode where file locking and
+ * repositioning are used to minimize the consequences of
+ * concurrent writes to a log file multiple appenders or
+ * programs. The effectiveness is operating system and
+ * Java platform dependent. Avoiding concurrent writing
+ * of log files is recommended.
+ *
+ * @since 1.2.16
+ */
+public final class PrudentWriter extends FilterWriter {
+ /**
+ * File channel associated with encapsulated writer.
+ */
+ private final FileChannel channel;
+
+ /**
+ * Constructs a new instance.
+ * @param out writer to encapsulate, may not be null.
+ * @param ostream file stream corresponding to writer, may not be null.
+ */
+ public PrudentWriter(final Writer out, final FileOutputStream ostream) {
+ super(out);
+ channel = ostream.getChannel();
+ }
+
+ /**
+ * Write string to encapsulated writer within a lock
+ * on the associated FileChannel. Channel will be
+ * repositioned to the end of the file if necessary.
+ */
+ public void write(final String str) throws IOException {
+ FileLock lock = null;
+ try {
+ lock = channel.lock();
+ long size = channel.size();
+ if (size != channel.position()) {
+ channel.position(size);
+ }
+ super.write(str);
+ super.flush();
+ } finally {
+ if (lock != null) {
+ lock.release();
+ }
+ }
+ }
+
+}
Modified:
logging/log4j/trunk/tests/src/java/org/apache/log4j/FileAppenderTest.java
URL:
http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/FileAppenderTest.java?rev=909868&r1=909867&r2=909868&view=diff
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/FileAppenderTest.java
(original)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/FileAppenderTest.java
Sat Feb 13 18:24:46 2010
@@ -84,4 +84,17 @@
Priority debug = Level.DEBUG;
assertTrue(appender.isAsSevereAsThreshold(debug));
}
+
+ /**
+ * Tests prudent mutator and accessor.
+ * See bug 48704.
+ */
+ public void testIsPrudent() {
+ FileAppender appender = new FileAppender();
+ assertFalse(appender.isPrudent());
+ appender.setPrudent(true);
+ assertTrue(appender.isPrudent());
+ appender.setPrudent(false);
+ assertFalse(appender.isPrudent());
+ }
}
Modified:
logging/log4j/trunk/tests/src/java/org/apache/log4j/MinimumTestCase.java
URL:
http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/MinimumTestCase.java?rev=909868&r1=909867&r2=909868&view=diff
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/MinimumTestCase.java
(original)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/MinimumTestCase.java
Sat Feb 13 18:24:46 2010
@@ -79,6 +79,32 @@
assertTrue(Compare.compare(FILTERED, "witness/simple"));
}
+ public void prudent() throws Exception {
+ try {
+ java.io.FileOutputStream.class.getMethod("getChannel",
(Class[]) null);
+ } catch(NoSuchMethodException ex) {
+ // earlier than JDK 1.4
+ return;
+ }
+ Layout layout = new SimpleLayout();
+ FileAppender appender = new FileAppender();
+
+ appender.setPrudent(true);
+ appender.setFile("output/prudent");
+ appender.setLayout(layout);
+ appender.activateOptions();
+ root.addAppender(appender);
+ common();
+
+ Transformer.transform(
+ "output/prudent", FILTERED,
+ new Filter[] { new LineNumberFilter(),
+ new SunReflectFilter(),
+ new JunitTestRunnerFilter() });
+ assertTrue(Compare.compare(FILTERED, "witness/prudent"));
+ }
+
+
public void ttcc() throws Exception {
Layout layout = new
TTCCLayout(AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT);
@@ -200,6 +226,7 @@
TestSuite suite = new TestSuite();
suite.addTest(new MinimumTestCase("simple"));
suite.addTest(new MinimumTestCase("ttcc"));
+ suite.addTest(new MinimumTestCase("prudent"));
return suite;
}
Copied: logging/log4j/trunk/tests/witness/prudent (from r909853,
logging/log4j/trunk/tests/witness/simple)
URL:
http://svn.apache.org/viewvc/logging/log4j/trunk/tests/witness/prudent?p2=logging/log4j/trunk/tests/witness/prudent&p1=logging/log4j/trunk/tests/witness/simple&r1=909853&r2=909868&rev=909868&view=diff
==============================================================================
--- logging/log4j/trunk/tests/witness/simple (original)
+++ logging/log4j/trunk/tests/witness/prudent Sat Feb 13 18:24:46 2010
@@ -30,7 +30,7 @@
DEBUG - Message 29
java.lang.Exception: Just testing.
at org.apache.log4j.MinimumTestCase.common(MinimumTestCase.java:XXX)
- at org.apache.log4j.MinimumTestCase.simple(MinimumTestCase.java:XXX)
+ at org.apache.log4j.MinimumTestCase.prudent(MinimumTestCase.java:XXX)
at junit.framework.TestCase.runTest(TestCase.java:XXX)
at junit.framework.TestCase.runBare(TestCase.java:XXX)
at junit.framework.TestResult$1.protect(TestResult.java:XXX)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]