Author: markt
Date: Mon Nov 2 21:57:21 2009
New Revision: 832123
URL: http://svn.apache.org/viewvc?rev=832123&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=47158
Update AccessLogValve and ExtendedAccessLogValve with all the recent threading
improvements
Modified:
tomcat/tc6.0.x/trunk/STATUS.txt
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/AccessLogValve.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ExtendedAccessLogValve.java
Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=832123&r1=832122&r2=832123&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Mon Nov 2 21:57:21 2009
@@ -165,17 +165,6 @@
+1: markt
-1:
-* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=47158
- Update AccessLogValve and ExtendedAccessLogValve with all the recent
threading
- improvements
- http://people.apache.org/~markt/patches/2009-08-15-AccessLogValve-tc6.patch
- +1: markt, kkolinko, fhanik
- -1:
-
- kkolinko: Also +1 to use StringBuilder everywhere in those classes, with
- exception of those places where it is passed as the argument to
- AccessLogValve.AccessLogElement#addElement().
-
* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=47699
Better handling of PID files
https://issues.apache.org/bugzilla/attachment.cgi?id=24202
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/AccessLogValve.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/AccessLogValve.java?rev=832123&r1=832122&r2=832123&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/AccessLogValve.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/AccessLogValve.java
Mon Nov 2 21:57:21 2009
@@ -223,34 +223,6 @@
/**
- * A date formatter to format Dates into a day string in the format
- * "dd".
- */
- private SimpleDateFormat dayFormatter = null;
-
-
- /**
- * A date formatter to format a Date into a month string in the format
- * "MM".
- */
- private SimpleDateFormat monthFormatter = null;
-
-
- /**
- * A date formatter to format a Date into a year string in the format
- * "yyyy".
- */
- private SimpleDateFormat yearFormatter = null;
-
-
- /**
- * A date formatter to format a Date into a time in the format
- * "kk:mm:ss" (kk is a 24-hour representation of the hour).
- */
- private SimpleDateFormat timeFormatter = null;
-
-
- /**
* The system timezone.
*/
private TimeZone timezone = null;
@@ -275,16 +247,32 @@
* is true.
*/
protected File currentLogFile = null;
+ private static class AccessDateStruct {
+ private Date currentDate = new Date();
+ private String currentDateString = null;
+ private SimpleDateFormat dayFormatter = new SimpleDateFormat("dd");
+ private SimpleDateFormat monthFormatter = new SimpleDateFormat("MM");
+ private SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy");
+ private SimpleDateFormat timeFormatter = new
SimpleDateFormat("HH:mm:ss");
+ public AccessDateStruct() {
+ TimeZone tz = TimeZone.getDefault();
+ dayFormatter.setTimeZone(tz);
+ monthFormatter.setTimeZone(tz);
+ yearFormatter.setTimeZone(tz);
+ timeFormatter.setTimeZone(tz);
+ }
+ }
/**
* The system time when we last updated the Date that this valve
* uses for log lines.
*/
- private Date currentDate = null;
-
- private volatile long currentMillis = 0;
-
-
+ private static final ThreadLocal<AccessDateStruct> currentDateStruct =
+ new ThreadLocal<AccessDateStruct>() {
+ protected AccessDateStruct initialValue() {
+ return new AccessDateStruct();
+ }
+ };
/**
* Resolve hosts.
*/
@@ -294,7 +282,7 @@
/**
* Instant when the log daily rotation was last checked.
*/
- private long rotationLastChecked = 0L;
+ private volatile long rotationLastChecked = 0L;
/**
* Do we check for log file existence? Helpful if an external
@@ -575,7 +563,7 @@
}
Date date = getDate();
- StringBuffer result = new StringBuffer();
+ StringBuffer result = new StringBuffer(128);
for (int i = 0; i < logElements.length; i++) {
logElements[i].addElement(result, date, request, response,
time);
@@ -648,15 +636,15 @@
// Only do a logfile switch check once a second, max.
long systime = System.currentTimeMillis();
if ((systime - rotationLastChecked) > 1000) {
-
- rotationLastChecked = systime;
-
- // Check for a change of date
- String tsDate = fileDateFormatter.format(new Date(systime));
-
- // If the date has changed, switch log files
- if (!dateStamp.equals(tsDate)) {
- synchronized (this) {
+ synchronized(this) {
+ if ((systime - rotationLastChecked) > 1000) {
+ rotationLastChecked = systime;
+
+ String tsDate;
+ // Check for a change of date
+ tsDate = fileDateFormatter.format(new Date(systime));
+
+ // If the date has changed, switch log files
if (!dateStamp.equals(tsDate)) {
close();
dateStamp = tsDate;
@@ -687,10 +675,12 @@
}
// Log this message
- if (writer != null) {
- writer.println(message);
- if (!buffered) {
- writer.flush();
+ synchronized(this) {
+ if (writer != null) {
+ writer.println(message);
+ if (!buffered) {
+ writer.flush();
+ }
}
}
@@ -757,15 +747,12 @@
private Date getDate() {
// Only create a new Date once per second, max.
long systime = System.currentTimeMillis();
- if ((systime - currentMillis) > 1000) {
- synchronized (this) {
- if ((systime - currentMillis) > 1000) {
- currentDate = new Date(systime);
- currentMillis = systime;
- }
- }
+ AccessDateStruct struct = currentDateStruct.get();
+ if ((systime - struct.currentDate.getTime()) > 1000) {
+ struct.currentDate.setTime(systime);
+ struct.currentDateString = null;
}
- return currentDate;
+ return struct.currentDate;
}
@@ -861,16 +848,7 @@
fileDateFormat = "yyyy-MM-dd";
fileDateFormatter = new SimpleDateFormat(fileDateFormat);
fileDateFormatter.setTimeZone(timezone);
- dayFormatter = new SimpleDateFormat("dd");
- dayFormatter.setTimeZone(timezone);
- monthFormatter = new SimpleDateFormat("MM");
- monthFormatter.setTimeZone(timezone);
- yearFormatter = new SimpleDateFormat("yyyy");
- yearFormatter.setTimeZone(timezone);
- timeFormatter = new SimpleDateFormat("HH:mm:ss");
- timeFormatter.setTimeZone(timezone);
- currentDate = new Date();
- dateStamp = fileDateFormatter.format(currentDate);
+ dateStamp =
fileDateFormatter.format(currentDateStruct.get().currentDate);
open();
}
@@ -922,22 +900,23 @@
/**
* write local IP address - %A
*/
- protected class LocalAddrElement implements AccessLogElement {
+ protected static class LocalAddrElement implements AccessLogElement {
- private String value = null;
+ private static final String LOCAL_ADDR_VALUE;
+
+ static {
+ String init;
+ try {
+ init = InetAddress.getLocalHost().getHostAddress();
+ } catch (Throwable e) {
+ init = "127.0.0.1";
+ }
+ LOCAL_ADDR_VALUE = init;
+ }
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
- if (value == null) {
- synchronized (this) {
- try {
- value = InetAddress.getLocalHost().getHostAddress();
- } catch (Throwable e) {
- value = "127.0.0.1";
- }
- }
- }
- buf.append(value);
+ buf.append(LOCAL_ADDR_VALUE);
}
}
@@ -1004,33 +983,29 @@
* write date and time, in Common Log Format - %t
*/
protected class DateAndTimeElement implements AccessLogElement {
- private Date currentDate = new Date(0);
-
- private String currentDateString = null;
+
+
+
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
- if (currentDate != date) {
- synchronized (this) {
- if (currentDate != date) {
- StringBuffer current = new StringBuffer(32);
- current.append('[');
- current.append(dayFormatter.format(date)); // Day
- current.append('/');
- current.append(lookup(monthFormatter.format(date)));
// Month
- current.append('/');
- current.append(yearFormatter.format(date)); // Year
- current.append(':');
- current.append(timeFormatter.format(date)); // Time
- current.append(' ');
- current.append(getTimeZone(date)); // Timezone
- current.append(']');
- currentDateString = current.toString();
- currentDate = date;
- }
- }
+ AccessDateStruct struct = currentDateStruct.get();
+ if (struct.currentDateString == null) {
+ StringBuffer current = new StringBuffer(32);
+ current.append('[');
+ current.append(struct.dayFormatter.format(date));
+ current.append('/');
+ current.append(lookup(struct.monthFormatter.format(date)));
+ current.append('/');
+ current.append(struct.yearFormatter.format(date));
+ current.append(':');
+ current.append(struct.timeFormatter.format(date));
+ current.append(' ');
+ current.append(getTimeZone(date));
+ current.append(']');
+ struct.currentDateString = current.toString();
}
- buf.append(currentDateString);
+ buf.append(struct.currentDateString);
}
}
@@ -1408,7 +1383,7 @@
if (buf.length() > 0) {
list.add(new StringElement(buf.toString()));
}
- return (AccessLogElement[]) list.toArray(new AccessLogElement[0]);
+ return list.toArray(new AccessLogElement[0]);
}
/**
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ExtendedAccessLogValve.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ExtendedAccessLogValve.java?rev=832123&r1=832122&r2=832123&view=diff
==============================================================================
---
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ExtendedAccessLogValve.java
(original)
+++
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ExtendedAccessLogValve.java
Mon Nov 2 21:57:21 2009
@@ -221,61 +221,55 @@
// ------------------------------------------------------ Lifecycle Methods
- protected class DateElement implements AccessLogElement {
- private Date currentDate = new Date(0);
-
- private String currentDateString = null;
-
- /**
- * A date formatter to format a Date into a date in the format
- * "yyyy-MM-dd".
- */
- private SimpleDateFormat dateFormatter = new
SimpleDateFormat("yyyy-MM-dd");
-
- public DateElement() {
- dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
- }
-
+ protected static class DateElement implements AccessLogElement {
+ // Milli-seconds in 24 hours
+ private static final long INTERVAL = (1000 * 60 * 60 * 24);
+
+ private static final ThreadLocal<ElementTimestampStruct> currentDate =
+ new ThreadLocal<ElementTimestampStruct>() {
+ protected ElementTimestampStruct initialValue() {
+ return new ElementTimestampStruct("yyyy-MM-dd");
+ }
+ };
+
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
- if (currentDate != date) {
- synchronized (this) {
- if (currentDate != date) {
- currentDateString = dateFormatter.format(date);
- currentDate = date;
- }
- }
+ ElementTimestampStruct eds = currentDate.get();
+ long millis = eds.currentTimestamp.getTime();
+ if (date.getTime() > (millis + INTERVAL -1) ||
+ date.getTime() < millis) {
+ eds.currentTimestamp.setTime(
+ date.getTime() - (date.getTime() % INTERVAL));
+ eds.currentTimestampString =
+ eds.currentTimestampFormat.format(eds.currentTimestamp);
}
- buf.append(currentDateString);
+ buf.append(eds.currentTimestampString);
}
}
- protected class TimeElement implements AccessLogElement {
- private Date currentDate = new Date(0);
-
- private String currentTimeString = null;
-
- /**
- * A date formatter to format a Date into a time in the format
- * "kk:mm:ss" (kk is a 24-hour representation of the hour).
- */
- private SimpleDateFormat timeFormatter = new
SimpleDateFormat("HH:mm:ss");
-
- public TimeElement() {
- timeFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
- }
+ protected static class TimeElement implements AccessLogElement {
+ // Milli-seconds in a second
+ private static final long INTERVAL = 1000;
+ private static final ThreadLocal<ElementTimestampStruct> currentTime =
+ new ThreadLocal<ElementTimestampStruct>() {
+ protected ElementTimestampStruct initialValue() {
+ return new ElementTimestampStruct("HH:mm:ss");
+ }
+ };
+
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
- if (currentDate != date) {
- synchronized (this) {
- if (currentDate != date) {
- currentTimeString = timeFormatter.format(date);
- currentDate = date;
- }
- }
+ ElementTimestampStruct eds = currentTime.get();
+ long millis = eds.currentTimestamp.getTime();
+ if (date.getTime() > (millis + INTERVAL -1) ||
+ date.getTime() < millis) {
+ eds.currentTimestamp.setTime(
+ date.getTime() - (date.getTime() % INTERVAL));
+ eds.currentTimestampString =
+ eds.currentTimestampFormat.format(eds.currentTimestamp);
}
- buf.append(currentTimeString);
+ buf.append(eds.currentTimestampString);
}
}
@@ -571,7 +565,7 @@
if (log.isDebugEnabled()) {
log.debug("finished decoding with element size of: " +
list.size());
}
- return (AccessLogElement[]) list.toArray(new AccessLogElement[0]);
+ return list.toArray(new AccessLogElement[0]);
} catch (IOException e) {
log.error("parse error", e);
return null;
@@ -843,5 +837,15 @@
+ parameter);
return null;
}
-
+
+ private static class ElementTimestampStruct {
+ private Date currentTimestamp = new Date(0);
+ private SimpleDateFormat currentTimestampFormat;
+ private String currentTimestampString;
+
+ ElementTimestampStruct(String format) {
+ currentTimestampFormat = new SimpleDateFormat(format);
+ currentTimestampFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]