Author: rjung
Date: Wed Nov 28 20:04:52 2012
New Revision: 1414889
URL: http://svn.apache.org/viewvc?rev=1414889&view=rev
Log:
Add new ALV attribute "renameOnRotate" (Default:false).
If set to "true", the "fileDateFormat" will not be part
of the current log file. Only at the time of log rotation
the file is renamed to the final name including the
"fileDateFormat".
This mimics the behavior e.g. of Log4J and similar frameworks,
where the active file does not have the timestamp in the file
name.
Pro: current file has stable name, all files with
timestamp in name are old.
Con: Slightly more complex impl.
Modified:
tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java
tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml
tomcat/trunk/webapps/docs/config/valve.xml
Modified: tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java?rev=1414889&r1=1414888&r2=1414889&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java (original)
+++ tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java Wed Nov 28
20:04:52 2012
@@ -208,6 +208,12 @@ public class AccessLogValve extends Valv
*/
protected boolean rotatable = true;
+ /**
+ * Should we defer inclusion of the date stamp in the file
+ * name until rotate time? Default is false.
+ */
+ protected boolean renameOnRotate = false;
+
/**
* Buffered logging.
@@ -729,6 +735,26 @@ public class AccessLogValve extends Valv
/**
+ * Should we defer inclusion of the date stamp in the file
+ * name until rotate time
+ */
+ public boolean isRenameOnRotate() {
+ return renameOnRotate;
+ }
+
+
+ /**
+ * Set the value if we should defer inclusion of the date
+ * stamp in the file name until rotate time
+ *
+ * @param renameOnRotate true if defer inclusion of date stamp
+ */
+ public void setRenameOnRotate(boolean renameOnRotate) {
+ this.renameOnRotate = renameOnRotate;
+ }
+
+
+ /**
* Is the logging buffered
*/
public boolean isBuffered() {
@@ -968,7 +994,7 @@ public class AccessLogValve extends Valv
if (currentLogFile != null) {
File holder = currentLogFile;
- close();
+ close(false);
try {
holder.renameTo(new File(newFileName));
} catch (Throwable e) {
@@ -994,12 +1020,76 @@ public class AccessLogValve extends Valv
/**
* Close the currently open log file (if any)
*/
- private synchronized void close() {
+ private File getLogFile(boolean useDateStamp) {
+
+ // Create the directory if necessary
+ File dir = new File(directory);
+ if (!dir.isAbsolute()) {
+ dir = new File(getContainer().getCatalinaBase(), directory);
+ }
+ if (!dir.mkdirs() && !dir.isDirectory()) {
+ log.error(sm.getString("accessLogValve.openDirFail", dir));
+ }
+
+ // Calculate the current log file name
+ File pathname;
+ if (useDateStamp) {
+ pathname = new File(dir.getAbsoluteFile(), prefix + dateStamp
+ + suffix);
+ } else {
+ pathname = new File(dir.getAbsoluteFile(), prefix + suffix);
+ }
+ File parent = pathname.getParentFile();
+ if (!parent.mkdirs() && !parent.isDirectory()) {
+ log.error(sm.getString("accessLogValve.openDirFail", parent));
+ }
+ return pathname;
+ }
+
+ /**
+ * Move a current but rotated log file back to the unrotated
+ * one. Needed if date stamp inclusion is deferred to rotation
+ * time.
+ */
+ private void restore() {
+ File newLogFile = getLogFile(false);
+ File rotatedLogFile = getLogFile(true);
+ if (rotatedLogFile.exists() && !newLogFile.exists() &&
+ !rotatedLogFile.equals(newLogFile)) {
+ try {
+ if (!rotatedLogFile.renameTo(newLogFile)) {
+ log.error(sm.getString("accessLogValve.renameFail",
rotatedLogFile, newLogFile));
+ }
+ } catch (Throwable e) {
+ ExceptionUtils.handleThrowable(e);
+ log.error(sm.getString("accessLogValve.renameFail",
rotatedLogFile, newLogFile), e);
+ }
+ }
+ }
+
+
+ /**
+ * Close the currently open log file (if any)
+ *
+ * @param rename Rename file to final name after closing
+ */
+ private synchronized void close(boolean rename) {
if (writer == null) {
return;
}
writer.flush();
writer.close();
+ if (rename && renameOnRotate) {
+ File newLogFile = getLogFile(true);
+ try {
+ if (!currentLogFile.renameTo(newLogFile)) {
+ log.error(sm.getString("accessLogValve.renameFail",
currentLogFile, newLogFile));
+ }
+ } catch (Throwable e) {
+ ExceptionUtils.handleThrowable(e);
+ log.error(sm.getString("accessLogValve.renameFail",
currentLogFile, newLogFile), e);
+ }
+ }
writer = null;
dateStamp = "";
currentLogFile = null;
@@ -1027,7 +1117,7 @@ public class AccessLogValve extends Valv
// If the date has changed, switch log files
if (!dateStamp.equals(tsDate)) {
- close();
+ close(true);
dateStamp = tsDate;
open();
}
@@ -1041,7 +1131,7 @@ public class AccessLogValve extends Valv
synchronized (this) {
if (currentLogFile != null && !currentLogFile.exists()) {
try {
- close();
+ close(false);
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
log.info(sm.getString("accessLogValve.closeFail"), e);
@@ -1078,28 +1168,9 @@ public class AccessLogValve extends Valv
* Open the new log file for the date specified by <code>dateStamp</code>.
*/
protected synchronized void open() {
- // Create the directory if necessary
- File dir = new File(directory);
- if (!dir.isAbsolute()) {
- dir = new File(getContainer().getCatalinaBase(), directory);
- }
- if (!dir.mkdirs() && !dir.isDirectory()) {
- log.error(sm.getString("accessLogValve.openDirFail", dir));
- }
-
// Open the current log file
- File pathname;
// If no rotate - no need for dateStamp in fileName
- if (rotatable) {
- pathname = new File(dir.getAbsoluteFile(), prefix + dateStamp
- + suffix);
- } else {
- pathname = new File(dir.getAbsoluteFile(), prefix + suffix);
- }
- File parent = pathname.getParentFile();
- if (!parent.mkdirs() && !parent.isDirectory()) {
- log.error(sm.getString("accessLogValve.openDirFail", parent));
- }
+ File pathname = getLogFile(rotatable && !renameOnRotate);
Charset charset = null;
if (encoding != null) {
@@ -1222,6 +1293,9 @@ public class AccessLogValve extends Valv
fileDateFormatter = new SimpleDateFormat(format, Locale.US);
fileDateFormatter.setTimeZone(timezone);
dateStamp = fileDateFormatter.format(new
Date(System.currentTimeMillis()));
+ if (rotatable && renameOnRotate) {
+ restore();
+ }
open();
setState(LifecycleState.STARTING);
@@ -1239,7 +1313,7 @@ public class AccessLogValve extends Valv
protected synchronized void stopInternal() throws LifecycleException {
setState(LifecycleState.STOPPING);
- close();
+ close(false);
}
/**
Modified: tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties?rev=1414889&r1=1414888&r2=1414889&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties Wed
Nov 28 20:04:52 2012
@@ -22,6 +22,7 @@ accessLogValve.openFail=Failed to open a
accessLogValve.closeFail=Failed to close access log file
accessLogValve.openDirFail=Failed to create directory [{0}] for access logs
accessLogValve.rotateFail=Failed to rotate access log
+accessLogValve.renameFail=Failed to rename access log from [{0}] to [{1}]
accessLogValve.invalidLocale=Failed to set locale to [{0}]
accessLogValve.unsupportedEncoding=Failed to set encoding to [{0}], will use
the system default character set.
Modified: tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml?rev=1414889&r1=1414888&r2=1414889&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml
(original)
+++ tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml Wed Nov
28 20:04:52 2012
@@ -94,6 +94,11 @@
is="true"
type="boolean"/>
+ <attribute name="renameOnRotate"
+ description="Flag to defer inclusion of the date stamp in the
log file name until rotation."
+ is="true"
+ type="boolean"/>
+
<attribute name="stateName"
description="The name of the LifecycleState that this component
is currently in"
type="java.lang.String"
@@ -252,6 +257,11 @@
is="true"
type="boolean"/>
+ <attribute name="renameOnRotate"
+ description="Flag to defer inclusion of the date stamp in the
log file name until rotation."
+ is="true"
+ type="boolean"/>
+
<attribute name="suffix"
description="The suffix that is added to log file filenames"
type="java.lang.String"/>
Modified: tomcat/trunk/webapps/docs/config/valve.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/valve.xml?rev=1414889&r1=1414888&r2=1414889&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/valve.xml (original)
+++ tomcat/trunk/webapps/docs/config/valve.xml Wed Nov 28 20:04:52 2012
@@ -180,6 +180,20 @@
</p>
</attribute>
+ <attribute name="renameOnRotate" required="false">
+ <p>By default for a rotatable log the active access log file name
+ will contain the current timestamp in <code>fileDateFormat</code>.
+ During rotation the file is closed and a new file with the next
+ timestamp in the name is created and used. When setting
+ <code>renameOnRotate</code> to <code>true</code>, the timestamp
+ is no longer part of the active log file name. Only during rotation
+ the file is closed and then renamed to include the timestamp.
+ This is similar to the behavior of most log frameworks when
+ doing time based rotation.
+ Default value: <code>false</code>
+ </p>
+ </attribute>
+
<attribute name="conditionIf" required="false">
<p>Turns on conditional logging. If set, requests will be
logged only if <code>ServletRequest.getAttribute()</code> is
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]