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]

Reply via email to