You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2007/01/08 21:51:01 UTC
svn commit: r494191 - in
/tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves: AccessLogValve.java
FastAccessLogValve.java FastCommonAccessLogValve.java
Author: remm
Date: Mon Jan 8 12:51:00 2007
New Revision: 494191
URL: http://svn.apache.org/viewvc?view=rev&rev=494191
Log:
- Replace AccessLogValve with the new fast one (since I don't think 3 valves doing the same thing are needed).
- Remove FastCommon, which has the same optimizations.
- Add a new buffered field to allow flushing on each request, which should make the behavior equivalent to the
old AccessLogValve.
Removed:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/FastAccessLogValve.java
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/AccessLogValve.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/FastCommonAccessLogValve.java
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?view=diff&rev=494191&r1=494190&r2=494191
==============================================================================
--- 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 Jan 8 12:51:00 2007
@@ -19,15 +19,17 @@
package org.apache.catalina.valves;
+import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
-import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
+import java.util.List;
import java.util.TimeZone;
import javax.servlet.ServletException;
@@ -105,7 +107,9 @@
*
* @author Craig R. McClanahan
* @author Jason Brittain
- * @version $Revision$ $Date$
+ * @author Remy Maucherat
+ * @author Takayuki Kaneko
+ * @version $Revision$ $Date: 2007-01-04 12:17:11 +0900
*/
public class AccessLogValve
@@ -120,11 +124,7 @@
* Construct a new instance of this class with default property values.
*/
public AccessLogValve() {
-
- super();
setPattern("common");
-
-
}
@@ -148,7 +148,7 @@
* The descriptive information about this implementation.
*/
protected static final String info =
- "org.apache.catalina.valves.AccessLogValve/1.0";
+ "org.apache.catalina.valves.FastAccessLogValve/1.0";
/**
@@ -166,21 +166,6 @@
/**
- * If the current log pattern is the same as the common access log
- * format pattern, then we'll set this variable to true and log in
- * a more optimal and hard-coded way.
- */
- private boolean common = false;
-
-
- /**
- * For the combined format (common, plus useragent and referer), we do
- * the same
- */
- private boolean combined = false;
-
-
- /**
* The pattern used to format our access log lines.
*/
private String pattern = null;
@@ -199,6 +184,12 @@
/**
+ * Buffered logging.
+ */
+ private boolean buffered = true;
+
+
+ /**
* The string manager for this package.
*/
private StringManager sm =
@@ -245,12 +236,6 @@
/**
- * Time taken formatter for 3 decimal places.
- */
- private DecimalFormat timeTakenFormatter = null;
-
-
- /**
* A date formatter to format a Date into a year string in the format
* "yyyy".
*/
@@ -289,12 +274,8 @@
* uses for log lines.
*/
private Date currentDate = null;
-
-
- /**
- * When formatting log lines, we often use strings like this one (" ").
- */
- private String space = " ";
+
+ private long currentMillis = 0;
/**
@@ -319,6 +300,11 @@
* Date format to place in log file name. Use at your own risk!
*/
private String fileDateFormat = null;
+
+ /**
+ * Array of AccessLogElement, they will be used to make log message.
+ */
+ private AccessLogElement[] logElements = null;
// ------------------------------------------------------------- Properties
@@ -327,9 +313,7 @@
* Return the directory in which we create log files.
*/
public String getDirectory() {
-
return (directory);
-
}
@@ -339,9 +323,7 @@
* @param directory The new log file directory
*/
public void setDirectory(String directory) {
-
this.directory = directory;
-
}
@@ -349,9 +331,7 @@
* Return descriptive information about this implementation.
*/
public String getInfo() {
-
return (info);
-
}
@@ -359,9 +339,7 @@
* Return the format pattern.
*/
public String getPattern() {
-
return (this.pattern);
-
}
@@ -371,7 +349,6 @@
* @param pattern The new pattern
*/
public void setPattern(String pattern) {
-
if (pattern == null)
pattern = "";
if (pattern.equals(Constants.AccessLog.COMMON_ALIAS))
@@ -379,17 +356,7 @@
if (pattern.equals(Constants.AccessLog.COMBINED_ALIAS))
pattern = Constants.AccessLog.COMBINED_PATTERN;
this.pattern = pattern;
-
- if (this.pattern.equals(Constants.AccessLog.COMMON_PATTERN))
- common = true;
- else
- common = false;
-
- if (this.pattern.equals(Constants.AccessLog.COMBINED_PATTERN))
- combined = true;
- else
- combined = false;
-
+ logElements = createLogElements();
}
@@ -397,9 +364,7 @@
* Return the log file prefix.
*/
public String getPrefix() {
-
return (prefix);
-
}
@@ -409,9 +374,7 @@
* @param prefix The new log file prefix
*/
public void setPrefix(String prefix) {
-
this.prefix = prefix;
-
}
@@ -419,9 +382,7 @@
* Should we rotate the logs
*/
public boolean isRotatable() {
-
return rotatable;
-
}
@@ -431,9 +392,25 @@
* @param rotatable true is we should rotate.
*/
public void setRotatable(boolean rotatable) {
-
this.rotatable = rotatable;
+ }
+
+ /**
+ * Is the logging buffered
+ */
+ public boolean isBuffered() {
+ return buffered;
+ }
+
+
+ /**
+ * Set the value if the logging should be buffered
+ *
+ * @param buffered true if buffered.
+ */
+ public void setBuffered(boolean buffered) {
+ this.buffered = buffered;
}
@@ -441,9 +418,7 @@
* Return the log file suffix.
*/
public String getSuffix() {
-
return (suffix);
-
}
@@ -453,9 +428,7 @@
* @param suffix The new log file suffix
*/
public void setSuffix(String suffix) {
-
this.suffix = suffix;
-
}
@@ -465,9 +438,7 @@
* @param resolveHosts The new resolve hosts value
*/
public void setResolveHosts(boolean resolveHosts) {
-
this.resolveHosts = resolveHosts;
-
}
@@ -475,9 +446,7 @@
* Get the value of the resolve hosts flag.
*/
public boolean isResolveHosts() {
-
return resolveHosts;
-
}
@@ -487,9 +456,7 @@
* request is logged.
*/
public String getCondition() {
-
return condition;
-
}
@@ -500,9 +467,7 @@
* @param condition Set to null to log everything
*/
public void setCondition(String condition) {
-
this.condition = condition;
-
}
/**
@@ -522,6 +487,16 @@
// --------------------------------------------------------- Public Methods
+ /**
+ * Execute a periodic task, such as reloading, etc. This method will be
+ * invoked inside the classloading context of this container. Unexpected
+ * throwables will be caught and logged.
+ */
+ public void backgroundProcess() {
+ if (writer != null && buffered) {
+ writer.flush();
+ }
+ }
/**
* Log a message summarizing the specified request and response, according
@@ -533,141 +508,30 @@
* @exception IOException if an input/output error has occurred
* @exception ServletException if a servlet error has occurred
*/
- public void invoke(Request request, Response response)
- throws IOException, ServletException {
+ public void invoke(Request request, Response response) throws IOException,
+ ServletException {
// Pass this request on to the next valve in our pipeline
- long t1=System.currentTimeMillis();
+ long t1 = System.currentTimeMillis();
getNext().invoke(request, response);
- long t2=System.currentTimeMillis();
- long time=t2-t1;
+ long t2 = System.currentTimeMillis();
+ long time = t2 - t1;
- if (condition!=null &&
- null!=request.getRequest().getAttribute(condition)) {
+ if (condition != null
+ && null != request.getRequest().getAttribute(condition)) {
return;
}
-
Date date = getDate();
StringBuffer result = new StringBuffer();
- // Check to see if we should log using the "common" access log pattern
- if (common || combined) {
- String value = null;
-
- if (isResolveHosts())
- result.append(request.getRemoteHost());
- else
- result.append(request.getRemoteAddr());
-
- result.append(" - ");
-
- value = request.getRemoteUser();
- if (value == null)
- result.append("- ");
- else {
- result.append(value);
- result.append(space);
- }
-
- result.append("[");
- result.append(dayFormatter.format(date)); // Day
- result.append('/');
- result.append(lookup(monthFormatter.format(date))); // Month
- result.append('/');
- result.append(yearFormatter.format(date)); // Year
- result.append(':');
- result.append(timeFormatter.format(date)); // Time
- result.append(space);
- result.append(getTimeZone(date)); // Time Zone
- result.append("] \"");
-
- result.append(request.getMethod());
- result.append(space);
- result.append(request.getRequestURI());
- if (request.getQueryString() != null) {
- result.append('?');
- result.append(request.getQueryString());
- }
- result.append(space);
- result.append(request.getProtocol());
- result.append("\" ");
-
- result.append(response.getStatus());
-
- result.append(space);
-
- int length = response.getContentCount();
-
- if (length <= 0)
- value = "-";
- else
- value = "" + length;
- result.append(value);
-
- if (combined) {
- result.append(space);
- result.append("\"");
- String referer = request.getHeader("referer");
- if(referer != null)
- result.append(referer);
- else
- result.append("-");
- result.append("\"");
-
- result.append(space);
- result.append("\"");
- String ua = request.getHeader("user-agent");
- if(ua != null)
- result.append(ua);
- else
- result.append("-");
- result.append("\"");
- }
-
- } else {
- // Generate a message based on the defined pattern
- boolean replace = false;
- for (int i = 0; i < pattern.length(); i++) {
- char ch = pattern.charAt(i);
- if (replace) {
- /* For code that processes {, the behavior will be ... if I
- * do not enounter a closing } - then I ignore the {
- */
- if ('{' == ch){
- StringBuffer name = new StringBuffer();
- int j = i + 1;
- for(;j < pattern.length() && '}' != pattern.charAt(j); j++) {
- name.append(pattern.charAt(j));
- }
- if (j+1 < pattern.length()) {
- /* the +1 was to account for } which we increment now */
- j++;
- result.append(replace(name.toString(),
- pattern.charAt(j),
- request,
- response));
- i=j; /*Since we walked more than one character*/
- } else {
- //D'oh - end of string - pretend we never did this
- //and do processing the "old way"
- result.append(replace(ch, date, request, response, time));
- }
- } else {
- result.append(replace(ch, date, request, response,time ));
- }
- replace = false;
- } else if (ch == '%') {
- replace = true;
- } else {
- result.append(ch);
- }
- }
+ for (int i = 0; i < logElements.length; i++) {
+ logElements[i].addElement(result, date, request, response, time);
}
- log(result.toString(), date);
+ log(result.toString());
}
@@ -678,14 +542,13 @@
* Close the currently open log file (if any)
*/
private synchronized void close() {
-
- if (writer == null)
+ if (writer == null) {
return;
+ }
writer.flush();
writer.close();
writer = null;
dateStamp = "";
-
}
@@ -694,12 +557,9 @@
* has changed since the previous log call.
*
* @param message Message to be logged
- * @param date the current Date object (so this method doesn't need to
- * create a new one)
*/
- public void log(String message, Date date) {
-
- if (rotatable){
+ public void log(String message) {
+ if (rotatable) {
// Only do a logfile switch check once a second, max.
long systime = System.currentTimeMillis();
if ((systime - rotationLastChecked) > 1000) {
@@ -721,13 +581,15 @@
}
}
}
-
}
}
// Log this message
if (writer != null) {
writer.println(message);
+ if (!buffered) {
+ writer.flush();
+ }
}
}
@@ -740,7 +602,6 @@
* @param month Month number ("01" .. "12").
*/
private String lookup(String month) {
-
int index;
try {
index = Integer.parseInt(month) - 1;
@@ -748,7 +609,6 @@
index = 0; // Can not happen, in theory
}
return (months[index]);
-
}
@@ -756,7 +616,6 @@
* Open the new log file for the date specified by <code>dateStamp</code>.
*/
private synchronized void open() {
-
// Create the directory if necessary
File dir = new File(directory);
if (!dir.isAbsolute())
@@ -767,228 +626,40 @@
try {
String pathname;
// If no rotate - no need for dateStamp in fileName
- if (rotatable){
- pathname = dir.getAbsolutePath() + File.separator +
- prefix + dateStamp + suffix;
+ if (rotatable) {
+ pathname = dir.getAbsolutePath() + File.separator + prefix
+ + dateStamp + suffix;
} else {
- pathname = dir.getAbsolutePath() + File.separator +
- prefix + suffix;
+ pathname = dir.getAbsolutePath() + File.separator + prefix
+ + suffix;
}
- writer = new PrintWriter(new FileWriter(pathname, true), true);
+ writer = new PrintWriter(new BufferedWriter(new FileWriter(
+ pathname, true), 128000), false);
} catch (IOException e) {
writer = null;
}
-
}
-
-
+
/**
- * Return the replacement text for the specified pattern character.
- *
- * @param pattern Pattern character identifying the desired text
- * @param date the current Date so that this method doesn't need to
- * create one
- * @param request Request being processed
- * @param response Response being processed
+ * This method returns a Date object that is accurate to within one second.
+ * If a thread calls this method to get a Date and it's been less than 1
+ * second since a new Date was created, this method simply gives out the
+ * same Date again so that the system doesn't spend time creating Date
+ * objects unnecessarily.
+ *
+ * @return Date
*/
- private String replace(char pattern, Date date, Request request,
- Response response, long time) {
-
- String value = null;
-
- if (pattern == 'a') {
- value = request.getRemoteAddr();
- } else if (pattern == 'A') {
- try {
- value = InetAddress.getLocalHost().getHostAddress();
- } catch(Throwable e){
- value = "127.0.0.1";
- }
- } else if (pattern == 'b') {
- int length = response.getContentCount();
- if (length <= 0)
- value = "-";
- else
- value = "" + length;
- } else if (pattern == 'B') {
- value = "" + response.getContentLength();
- } else if (pattern == 'h') {
- value = request.getRemoteHost();
- } else if (pattern == 'H') {
- value = request.getProtocol();
- } else if (pattern == 'l') {
- value = "-";
- } else if (pattern == 'm') {
- if (request != null)
- value = request.getMethod();
- else
- value = "";
- } else if (pattern == 'p') {
- value = "" + request.getServerPort();
- } else if (pattern == 'D') {
- value = "" + time;
- } else if (pattern == 'q') {
- String query = null;
- if (request != null)
- query = request.getQueryString();
- if (query != null)
- value = "?" + query;
- else
- value = "";
- } else if (pattern == 'r') {
- StringBuffer sb = new StringBuffer();
- if (request != null) {
- sb.append(request.getMethod());
- sb.append(space);
- sb.append(request.getRequestURI());
- if (request.getQueryString() != null) {
- sb.append('?');
- sb.append(request.getQueryString());
+ 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;
}
- sb.append(space);
- sb.append(request.getProtocol());
- } else {
- sb.append("- - ");
- sb.append(request.getProtocol());
}
- value = sb.toString();
- } else if (pattern == 'S') {
- if (request != null)
- if (request.getSession(false) != null)
- value = request.getSessionInternal(false).getIdInternal();
- else value = "-";
- else
- value = "-";
- } else if (pattern == 's') {
- if (response != null)
- value = "" + response.getStatus();
- else
- value = "-";
- } else if (pattern == 't') {
- StringBuffer temp = new StringBuffer("[");
- temp.append(dayFormatter.format(date)); // Day
- temp.append('/');
- temp.append(lookup(monthFormatter.format(date))); // Month
- temp.append('/');
- temp.append(yearFormatter.format(date)); // Year
- temp.append(':');
- temp.append(timeFormatter.format(date)); // Time
- temp.append(' ');
- temp.append(getTimeZone(date)); // Timezone
- temp.append(']');
- value = temp.toString();
- } else if (pattern == 'T') {
- value = timeTakenFormatter.format(time/1000d);
- } else if (pattern == 'u') {
- if (request != null)
- value = request.getRemoteUser();
- if (value == null)
- value = "-";
- } else if (pattern == 'U') {
- if (request != null)
- value = request.getRequestURI();
- else
- value = "-";
- } else if (pattern == 'v') {
- value = request.getServerName();
- } else {
- value = "???" + pattern + "???";
}
-
- if (value == null)
- return ("");
- else
- return (value);
-
- }
-
-
- /**
- * Return the replacement text for the specified "header/parameter".
- *
- * @param header The header/parameter to get
- * @param type Where to get it from i=input,c=cookie,r=ServletRequest,s=Session
- * @param request Request being processed
- * @param response Response being processed
- */
- private String replace(String header, char type, Request request,
- Response response) {
-
- Object value = null;
-
- switch (type) {
- case 'i':
- if (null != request)
- value = request.getHeader(header);
- else
- value= "??";
- break;
-/*
- // Someone please make me work
- case 'o':
- break;
-*/
- case 'c':
- Cookie[] c = request.getCookies();
- for (int i=0; c != null && i < c.length; i++){
- if (header.equals(c[i].getName())){
- value = c[i].getValue();
- break;
- }
- }
- break;
- case 'r':
- if (null != request)
- value = request.getAttribute(header);
- else
- value= "??";
- break;
- case 's':
- if (null != request) {
- HttpSession sess = request.getSession(false);
- if (null != sess)
- value = sess.getAttribute(header);
- }
- break;
- default:
- value = "???";
- }
-
- /* try catch in case toString() barfs */
- try {
- if (value!=null)
- if (value instanceof String)
- return (String)value;
- else
- return value.toString();
- else
- return "-";
- } catch(Throwable e) {
- return "-";
- }
- }
-
-
- /**
- * This method returns a Date object that is accurate to within one
- * second. If a thread calls this method to get a Date and it's been
- * less than 1 second since a new Date was created, this method
- * simply gives out the same Date again so that the system doesn't
- * spend time creating Date objects unnecessarily.
- *
- * @return Date
- */
- private Date getDate() {
- if(currentDate == null) {
- currentDate = new Date();
- } else {
- // Only create a new Date once per second, max.
- long systime = System.currentTimeMillis();
- if ((systime - currentDate.getTime()) > 1000) {
- currentDate = new Date(systime);
- }
- }
-
return currentDate;
}
@@ -1004,21 +675,21 @@
private String calculateTimeZoneOffset(long offset) {
StringBuffer tz = new StringBuffer();
- if ((offset<0)) {
+ if ((offset < 0)) {
tz.append("-");
offset = -offset;
} else {
tz.append("+");
}
- long hourOffset = offset/(1000*60*60);
- long minuteOffset = (offset/(1000*60)) % 60;
+ long hourOffset = offset / (1000 * 60 * 60);
+ long minuteOffset = (offset / (1000 * 60)) % 60;
- if (hourOffset<10)
+ if (hourOffset < 10)
tz.append("0");
tz.append(hourOffset);
- if (minuteOffset<10)
+ if (minuteOffset < 10)
tz.append("0");
tz.append(minuteOffset);
@@ -1035,9 +706,7 @@
* @param listener The listener to add
*/
public void addLifecycleListener(LifecycleListener listener) {
-
lifecycle.addLifecycleListener(listener);
-
}
@@ -1046,9 +715,7 @@
* Lifecycle has no listeners registered, a zero-length array is returned.
*/
public LifecycleListener[] findLifecycleListeners() {
-
return lifecycle.findLifecycleListeners();
-
}
@@ -1058,9 +725,7 @@
* @param listener The listener to add
*/
public void removeLifecycleListener(LifecycleListener listener) {
-
lifecycle.removeLifecycleListener(listener);
-
}
@@ -1076,8 +741,8 @@
// Validate and update our current component state
if (started)
- throw new LifecycleException
- (sm.getString("accessLogValve.alreadyStarted"));
+ throw new LifecycleException(sm
+ .getString("accessLogValve.alreadyStarted"));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
@@ -1086,9 +751,9 @@
timeZoneNoDST = calculateTimeZoneOffset(timezone.getRawOffset());
Calendar calendar = Calendar.getInstance(timezone);
int offset = calendar.get(Calendar.DST_OFFSET);
- timeZoneDST = calculateTimeZoneOffset(timezone.getRawOffset()+offset);
-
- if (fileDateFormat==null || fileDateFormat.length()==0)
+ timeZoneDST = calculateTimeZoneOffset(timezone.getRawOffset() + offset);
+
+ if (fileDateFormat == null || fileDateFormat.length() == 0)
fileDateFormat = "yyyy-MM-dd";
dateFormatter = new SimpleDateFormat(fileDateFormat);
dateFormatter.setTimeZone(timezone);
@@ -1102,10 +767,7 @@
timeFormatter.setTimeZone(timezone);
currentDate = new Date();
dateStamp = dateFormatter.format(currentDate);
- timeTakenFormatter = new DecimalFormat("0.000");
-
open();
-
}
@@ -1121,12 +783,539 @@
// Validate and update our current component state
if (!started)
- throw new LifecycleException
- (sm.getString("accessLogValve.notStarted"));
+ throw new LifecycleException(sm
+ .getString("accessLogValve.notStarted"));
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
-
close();
+ }
+
+ /**
+ * AccessLogElement writes the partial message into the buffer.
+ */
+ private interface AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time);
+ }
+
+ /**
+ * write local IP address - %A
+ */
+ private class LocalAddrElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ String value;
+ try {
+ value = InetAddress.getLocalHost().getHostAddress();
+ } catch (Throwable e) {
+ value = "127.0.0.1";
+ }
+ buf.append(value);
+ }
+ }
+
+ /**
+ * write remote IP address - %a
+ */
+ private class RemoteAddrElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ buf.append(request.getRemoteAddr());
+ }
+ }
+
+ /**
+ * write remote host name - %h
+ */
+ private class HostElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ buf.append(request.getRemoteHost());
+ }
+ }
+
+ /**
+ * write remote logical username from identd (always returns '-') - %l
+ */
+ private class LogicalUserNameElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ buf.append('-');
+ }
+ }
+
+ /**
+ * write request protocol - %H
+ */
+ private class ProtocolElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ buf.append(request.getProtocol());
+ }
+ }
+
+ /**
+ * write remote user that was authenticated (if any), else '-' - %u
+ */
+ private class UserElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ if (request != null) {
+ String value = request.getRemoteUser();
+ if (value != null) {
+ buf.append(value);
+ } else {
+ buf.append('-');
+ }
+ } else {
+ buf.append('-');
+ }
+ }
+ }
+
+ /**
+ * write date and time, in Common Log Format - %t
+ */
+ private 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;
+ }
+ }
+ }
+ buf.append(currentDateString);
+ }
+ }
+
+ /**
+ * write first line of the request (method and request URI) - %r
+ */
+ private class RequestElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ if (request != null) {
+ buf.append(request.getMethod());
+ buf.append(' ');
+ buf.append(request.getRequestURI());
+ if (request.getQueryString() != null) {
+ buf.append('?');
+ buf.append(request.getQueryString());
+ }
+ buf.append(' ');
+ buf.append(request.getProtocol());
+ } else {
+ buf.append("- - ");
+ buf.append(request.getProtocol());
+ }
+ }
+ }
+
+ /**
+ * write HTTP status code of the response - %s
+ */
+ private class HttpStatusCodeElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ if (response != null) {
+ buf.append(response.getStatus());
+ } else {
+ buf.append('-');
+ }
+ }
+ }
+
+ /**
+ * write local port on which this request was received - %p
+ */
+ private class LocalPortElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ buf.append(request.getServerPort());
+ }
+ }
+
+ /**
+ * write bytes sent, excluding HTTP headers - %b, %B
+ */
+ private class ByteSentElement implements AccessLogElement {
+ private boolean conversion;
+
+ /**
+ * if conversion is true, write '-' instead of 0 - %b
+ */
+ public ByteSentElement(boolean conversion) {
+ this.conversion = conversion;
+ }
+
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ int length = response.getContentCount();
+ if (length <= 0 && conversion) {
+ buf.append('-');
+ } else {
+ buf.append(length);
+ }
+ }
+ }
+
+ /**
+ * write request method (GET, POST, etc.) - %m
+ */
+ private class MethodElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ if (request != null) {
+ buf.append(request.getMethod());
+ }
+ }
+ }
+
+ /**
+ * write time taken to process the request - %D, %T
+ */
+ private class ElapsedTimeElement implements AccessLogElement {
+ private boolean millis;
+
+ /**
+ * if millis is true, write time in millis - %D
+ * if millis is false, write time in seconds - %T
+ */
+ public ElapsedTimeElement(boolean millis) {
+ this.millis = millis;
+ }
+
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ if (millis) {
+ buf.append(time);
+ } else {
+ // second
+ buf.append(time / 1000);
+ buf.append('.');
+ int remains = (int) (time % 1000);
+ buf.append(remains / 100);
+ remains = remains % 100;
+ buf.append(remains / 10);
+ buf.append(remains % 10);
+ }
+ }
+ }
+
+ /**
+ * write Query string (prepended with a '?' if it exists) - %q
+ */
+ private class QueryElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ String query = null;
+ if (request != null)
+ query = request.getQueryString();
+ if (query != null) {
+ buf.append('?');
+ buf.append(query);
+ }
+ }
+ }
+
+ /**
+ * write user session ID - %S
+ */
+ private class SessionIdElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ if (request != null) {
+ if (request.getSession(false) != null) {
+ buf.append(request.getSessionInternal(false)
+ .getIdInternal());
+ } else {
+ buf.append('-');
+ }
+ } else {
+ buf.append('-');
+ }
+ }
+ }
+
+ /**
+ * write requested URL path - %U
+ */
+ private class RequestURIElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ if (request != null) {
+ buf.append(request.getRequestURI());
+ } else {
+ buf.append('-');
+ }
+ }
+ }
+
+ /**
+ * write local server name - %v
+ */
+ private class LocalServerNameElement implements AccessLogElement {
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ buf.append(request.getServerName());
+ }
+ }
+
+ /**
+ * write any string
+ */
+ private class StringElement implements AccessLogElement {
+ private String str;
+
+ public StringElement(String str) {
+ this.str = str;
+ }
+
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ buf.append(str);
+ }
+ }
+
+ /**
+ * write incoming headers - %{xxx}i
+ */
+ private class HeaderElement implements AccessLogElement {
+ private String header;
+
+ public HeaderElement(String header) {
+ this.header = header;
+ }
+
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ buf.append(request.getHeader(header));
+ }
+ }
+
+ /**
+ * write a specific cookie - %{xxx}c
+ */
+ private class CookieElement implements AccessLogElement {
+ private String header;
+
+ public CookieElement(String header) {
+ this.header = header;
+ }
+
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ String value = "-";
+ Cookie[] c = request.getCookies();
+ if (c != null) {
+ for (int i = 0; i < c.length; i++) {
+ if (header.equals(c[i].getName())) {
+ value = c[i].getValue();
+ break;
+ }
+ }
+ }
+ buf.append(value);
+ }
+ }
+
+ /**
+ * write an attribute in the ServletRequest - %{xxx}r
+ */
+ private class RequestAttributeElement implements AccessLogElement {
+ private String header;
+
+ public RequestAttributeElement(String header) {
+ this.header = header;
+ }
+
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ Object value = null;
+ if (request != null) {
+ value = request.getAttribute(header);
+ } else {
+ value = "??";
+ }
+ if (value != null) {
+ if (value instanceof String) {
+ buf.append((String) value);
+ } else {
+ buf.append(value.toString());
+ }
+ } else {
+ buf.append('-');
+ }
+ }
+ }
+
+ /**
+ * write an attribute in the HttpSession - %{xxx}s
+ */
+ private class SessionAttributeElement implements AccessLogElement {
+ private String header;
+
+ public SessionAttributeElement(String header) {
+ this.header = header;
+ }
+
+ public void addElement(StringBuffer buf, Date date, Request request,
+ Response response, long time) {
+ Object value = null;
+ if (null != request) {
+ HttpSession sess = request.getSession(false);
+ if (null != sess)
+ value = sess.getAttribute(header);
+ } else {
+ value = "??";
+ }
+ if (value != null) {
+ if (value instanceof String) {
+ buf.append((String) value);
+ } else {
+ buf.append(value.toString());
+ }
+ } else {
+ buf.append('-');
+ }
+ }
+ }
+
+
+
+
+ /**
+ * parse pattern string and create the array of AccessLogElement
+ */
+ private AccessLogElement[] createLogElements() {
+ List list = new ArrayList();
+ boolean replace = false;
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < pattern.length(); i++) {
+ char ch = pattern.charAt(i);
+ if (replace) {
+ /*
+ * For code that processes {, the behavior will be ... if I do
+ * not enounter a closing } - then I ignore the {
+ */
+ if ('{' == ch) {
+ StringBuffer name = new StringBuffer();
+ int j = i + 1;
+ for (; j < pattern.length() && '}' != pattern.charAt(j); j++) {
+ name.append(pattern.charAt(j));
+ }
+ if (j + 1 < pattern.length()) {
+ /* the +1 was to account for } which we increment now */
+ j++;
+ list.add(createAccessLogElement(name.toString(),
+ pattern.charAt(j)));
+ i = j; /* Since we walked more than one character */
+ } else {
+ // D'oh - end of string - pretend we never did this
+ // and do processing the "old way"
+ list.add(createAccessLogElement(ch));
+ }
+ } else {
+ list.add(createAccessLogElement(ch));
+ }
+ replace = false;
+ } else if (ch == '%') {
+ replace = true;
+ list.add(new StringElement(buf.toString()));
+ buf = new StringBuffer();
+ } else {
+ buf.append(ch);
+ }
+ }
+ if (buf.length() > 0) {
+ list.add(new StringElement(buf.toString()));
+ }
+ return (AccessLogElement[]) list.toArray(new AccessLogElement[0]);
+ }
+
+ /**
+ * create an AccessLogElement implementation which needs header string
+ */
+ private AccessLogElement createAccessLogElement(String header, char pattern) {
+ switch (pattern) {
+ case 'i':
+ return new HeaderElement(header);
+ case 'c':
+ return new CookieElement(header);
+ case 'r':
+ return new RequestAttributeElement(header);
+ case 's':
+ return new SessionAttributeElement(header);
+ default:
+ return new StringElement("???");
+ }
+ }
+
+ /**
+ * create an AccessLogElement implementation
+ */
+ private AccessLogElement createAccessLogElement(char pattern) {
+ switch (pattern) {
+ case 'a':
+ return new RemoteAddrElement();
+ case 'A':
+ return new LocalAddrElement();
+ case 'b':
+ return new ByteSentElement(true);
+ case 'B':
+ return new ByteSentElement(false);
+ case 'D':
+ return new ElapsedTimeElement(true);
+ case 'h':
+ return new HostElement();
+ case 'H':
+ return new ProtocolElement();
+ case 'l':
+ return new LogicalUserNameElement();
+ case 'm':
+ return new MethodElement();
+ case 'p':
+ return new LocalPortElement();
+ case 'q':
+ return new QueryElement();
+ case 'r':
+ return new RequestElement();
+ case 's':
+ return new HttpStatusCodeElement();
+ case 'S':
+ return new SessionIdElement();
+ case 't':
+ return new DateAndTimeElement();
+ case 'T':
+ return new ElapsedTimeElement(false);
+ case 'u':
+ return new UserElement();
+ case 'U':
+ return new RequestURIElement();
+ case 'v':
+ return new LocalServerNameElement();
+ default:
+ return new StringElement("???" + pattern + "???");
+ }
}
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/FastCommonAccessLogValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/FastCommonAccessLogValve.java?view=diff&rev=494191&r1=494190&r2=494191
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/FastCommonAccessLogValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/FastCommonAccessLogValve.java Mon Jan 8 12:51:00 2007
@@ -19,838 +19,9 @@
package org.apache.catalina.valves;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-import javax.servlet.ServletException;
-
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.util.LifecycleSupport;
-import org.apache.catalina.util.StringManager;
-
-
/**
- * <p>Implementation of the <b>Valve</b> interface that generates a web server
- * access log with the detailed line contents matching either the common or
- * combined patterns. As an additional feature, automatic rollover of log files
- * when the date changes is also supported.</p>
- * <p>
- * Conditional logging is also supported. This can be done with the
- * <code>condition</code> property.
- * If the value returned from ServletRequest.getAttribute(condition)
- * yields a non-null value. The logging will be skipped.
- * </p>
- *
- * @author Craig R. McClanahan
- * @author Jason Brittain
- * @author Remy Maucherat
- * @version $Revision$ $Date$
+ * @deprecated
*/
-public final class FastCommonAccessLogValve
- extends ValveBase
- implements Lifecycle {
-
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Construct a new instance of this class with default property values.
- */
- public FastCommonAccessLogValve() {
-
- super();
- setPattern("common");
-
-
- }
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * The as-of date for the currently open log file, or a zero-length
- * string if there is no open log file.
- */
- private String dateStamp = "";
-
-
- /**
- * The directory in which log files are created.
- */
- private String directory = "logs";
-
-
- /**
- * The descriptive information about this implementation.
- */
- protected static final String info =
- "org.apache.catalina.valves.FastCommonAccessLogValve/1.0";
-
-
- /**
- * The lifecycle event support for this component.
- */
- protected LifecycleSupport lifecycle = new LifecycleSupport(this);
-
-
- /**
- * The set of month abbreviations for log messages.
- */
- protected static final String months[] =
- { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-
- /**
- * If the current log pattern is the same as the common access log
- * format pattern, then we'll set this variable to true and log in
- * a more optimal and hard-coded way.
- */
- private boolean common = false;
-
-
- /**
- * For the combined format (common, plus useragent and referer), we do
- * the same
- */
- private boolean combined = false;
-
-
- /**
- * The pattern used to format our access log lines.
- */
- private String pattern = null;
-
-
- /**
- * The prefix that is added to log file filenames.
- */
- private String prefix = "access_log.";
-
-
- /**
- * Should we rotate our log file? Default is true (like old behavior)
- */
- private boolean rotatable = true;
-
-
- /**
- * The string manager for this package.
- */
- private StringManager sm =
- StringManager.getManager(Constants.Package);
-
-
- /**
- * Has this component been started yet?
- */
- private boolean started = false;
-
-
- /**
- * The suffix that is added to log file filenames.
- */
- private String suffix = "";
-
-
- /**
- * The PrintWriter to which we are currently logging, if any.
- */
- private PrintWriter writer = null;
-
-
- /**
- * A date formatter to format a Date into a date in the format
- * "yyyy-MM-dd".
- */
- private SimpleDateFormat dateFormatter = null;
-
-
- /**
- * 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;
-
-
- /**
- * The time zone offset relative to GMT in text form when daylight saving
- * is not in operation.
- */
- private String timeZoneNoDST = null;
-
- /**
- * The time zone offset relative to GMT in text form when daylight saving
- * is in operation.
- */
- private String timeZoneDST = null;
-
-
- /**
- * The system time when we last updated the Date that this valve
- * uses for log lines.
- */
- private String currentDateString = null;
-
-
- /**
- * The instant where the date string was last updated.
- */
- private long currentDate = 0L;
-
-
- /**
- * When formatting log lines, we often use strings like this one (" ").
- */
- private String space = " ";
-
-
- /**
- * Resolve hosts.
- */
- private boolean resolveHosts = false;
-
-
- /**
- * Instant when the log daily rotation was last checked.
- */
- private long rotationLastChecked = 0L;
-
-
- /**
- * Are we doing conditional logging. default false.
- */
- private String condition = null;
-
-
- /**
- * Date format to place in log file name. Use at your own risk!
- */
- private String fileDateFormat = null;
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Return the directory in which we create log files.
- */
- public String getDirectory() {
-
- return (directory);
-
- }
-
-
- /**
- * Set the directory in which we create log files.
- *
- * @param directory The new log file directory
- */
- public void setDirectory(String directory) {
-
- this.directory = directory;
-
- }
-
-
- /**
- * Return descriptive information about this implementation.
- */
- public String getInfo() {
-
- return (info);
-
- }
-
-
- /**
- * Return the format pattern.
- */
- public String getPattern() {
-
- return (this.pattern);
-
- }
-
-
- /**
- * Set the format pattern, first translating any recognized alias.
- *
- * @param pattern The new pattern
- */
- public void setPattern(String pattern) {
-
- if (pattern == null)
- pattern = "";
- if (pattern.equals(Constants.AccessLog.COMMON_ALIAS))
- pattern = Constants.AccessLog.COMMON_PATTERN;
- if (pattern.equals(Constants.AccessLog.COMBINED_ALIAS))
- pattern = Constants.AccessLog.COMBINED_PATTERN;
- this.pattern = pattern;
-
- if (this.pattern.equals(Constants.AccessLog.COMBINED_PATTERN))
- combined = true;
- else
- combined = false;
-
- }
-
-
- /**
- * Return the log file prefix.
- */
- public String getPrefix() {
-
- return (prefix);
-
- }
-
-
- /**
- * Set the log file prefix.
- *
- * @param prefix The new log file prefix
- */
- public void setPrefix(String prefix) {
-
- this.prefix = prefix;
-
- }
-
-
- /**
- * Should we rotate the logs
- */
- public boolean isRotatable() {
-
- return rotatable;
-
- }
-
-
- /**
- * Set the value is we should we rotate the logs
- *
- * @param rotatable true is we should rotate.
- */
- public void setRotatable(boolean rotatable) {
-
- this.rotatable = rotatable;
-
- }
-
-
- /**
- * Return the log file suffix.
- */
- public String getSuffix() {
-
- return (suffix);
-
- }
-
-
- /**
- * Set the log file suffix.
- *
- * @param suffix The new log file suffix
- */
- public void setSuffix(String suffix) {
-
- this.suffix = suffix;
-
- }
-
-
- /**
- * Set the resolve hosts flag.
- *
- * @param resolveHosts The new resolve hosts value
- */
- public void setResolveHosts(boolean resolveHosts) {
-
- this.resolveHosts = resolveHosts;
-
- }
-
-
- /**
- * Get the value of the resolve hosts flag.
- */
- public boolean isResolveHosts() {
-
- return resolveHosts;
-
- }
-
-
- /**
- * Return whether the attribute name to look for when
- * performing conditional loggging. If null, every
- * request is logged.
- */
- public String getCondition() {
-
- return condition;
-
- }
-
-
- /**
- * Set the ServletRequest.attribute to look for to perform
- * conditional logging. Set to null to log everything.
- *
- * @param condition Set to null to log everything
- */
- public void setCondition(String condition) {
-
- this.condition = condition;
-
- }
-
- /**
- * Return the date format date based log rotation.
- */
- public String getFileDateFormat() {
- return fileDateFormat;
- }
-
-
- /**
- * Set the date format date based log rotation.
- */
- public void setFileDateFormat(String fileDateFormat) {
- this.fileDateFormat = fileDateFormat;
- }
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Execute a periodic task, such as reloading, etc. This method will be
- * invoked inside the classloading context of this container. Unexpected
- * throwables will be caught and logged.
- */
- public void backgroundProcess() {
- if (writer != null)
- writer.flush();
- }
-
-
- /**
- * Log a message summarizing the specified request and response, according
- * to the format specified by the <code>pattern</code> property.
- *
- * @param request Request being processed
- * @param response Response being processed
- *
- * @exception IOException if an input/output error has occurred
- * @exception ServletException if a servlet error has occurred
- */
- public void invoke(Request request, Response response)
- throws IOException, ServletException {
-
- // Pass this request on to the next valve in our pipeline
- getNext().invoke(request, response);
-
- if (condition!=null &&
- null!=request.getRequest().getAttribute(condition)) {
- return;
- }
-
- StringBuffer result = new StringBuffer();
-
- // Check to see if we should log using the "common" access log pattern
- String value = null;
-
- if (isResolveHosts())
- result.append(request.getRemoteHost());
- else
- result.append(request.getRemoteAddr());
-
- result.append(" - ");
-
- value = request.getRemoteUser();
- if (value == null)
- result.append("- ");
- else {
- result.append(value);
- result.append(space);
- }
-
- result.append(getCurrentDateString());
-
- result.append(request.getMethod());
- result.append(space);
- result.append(request.getRequestURI());
- if (request.getQueryString() != null) {
- result.append('?');
- result.append(request.getQueryString());
- }
- result.append(space);
- result.append(request.getProtocol());
- result.append("\" ");
-
- result.append(response.getStatus());
-
- result.append(space);
-
- int length = response.getContentCount();
-
- if (length <= 0)
- value = "-";
- else
- value = "" + length;
- result.append(value);
-
- if (combined) {
- result.append(space);
- result.append("\"");
- String referer = request.getHeader("referer");
- if(referer != null)
- result.append(referer);
- else
- result.append("-");
- result.append("\"");
-
- result.append(space);
- result.append("\"");
- String ua = request.getHeader("user-agent");
- if(ua != null)
- result.append(ua);
- else
- result.append("-");
- result.append("\"");
- }
-
- log(result.toString());
-
- }
-
-
- // -------------------------------------------------------- Private Methods
-
-
- /**
- * Close the currently open log file (if any)
- */
- private synchronized void close() {
-
- if (writer == null)
- return;
- writer.flush();
- writer.close();
- writer = null;
- dateStamp = "";
-
- }
-
-
- /**
- * Log the specified message to the log file, switching files if the date
- * has changed since the previous log call.
- *
- * @param message Message to be logged
- */
- public void log(String message) {
-
- // Log this message
- if (writer != null) {
- writer.println(message);
- }
-
- }
-
-
- /**
- * Return the month abbreviation for the specified month, which must
- * be a two-digit String.
- *
- * @param month Month number ("01" .. "12").
- */
- private String lookup(String month) {
-
- int index;
- try {
- index = Integer.parseInt(month) - 1;
- } catch (Throwable t) {
- index = 0; // Can not happen, in theory
- }
- return (months[index]);
-
- }
-
-
- /**
- * Open the new log file for the date specified by <code>dateStamp</code>.
- */
- private synchronized void open() {
-
- // Create the directory if necessary
- File dir = new File(directory);
- if (!dir.isAbsolute())
- dir = new File(System.getProperty("catalina.base"), directory);
- dir.mkdirs();
-
- // Open the current log file
- try {
- String pathname;
- // If no rotate - no need for dateStamp in fileName
- if (rotatable){
- pathname = dir.getAbsolutePath() + File.separator +
- prefix + dateStamp + suffix;
- } else {
- pathname = dir.getAbsolutePath() + File.separator +
- prefix + suffix;
- }
- writer = new PrintWriter(new BufferedWriter
- (new FileWriter(pathname, true), 128000), false);
- } catch (IOException e) {
- writer = null;
- }
-
- }
-
-
- /**
- * This method returns a Date object that is accurate to within one
- * second. If a thread calls this method to get a Date and it's been
- * less than 1 second since a new Date was created, this method
- * simply gives out the same Date again so that the system doesn't
- * spend time creating Date objects unnecessarily.
- *
- * @return Date
- */
- private String getCurrentDateString() {
- // Only create a new Date once per second, max.
- long systime = System.currentTimeMillis();
- if ((systime - currentDate) > 1000) {
- synchronized (this) {
- // We don't care about being exact here: if an entry does get
- // logged as having happened during the previous second
- // it will not make any difference
- if ((systime - currentDate) > 1000) {
-
- // Format the new date
- Date date = new Date();
- StringBuffer result = new StringBuffer(32);
- result.append("[");
- // Day
- result.append(dayFormatter.format(date));
- result.append('/');
- // Month
- result.append(lookup(monthFormatter.format(date)));
- result.append('/');
- // Year
- result.append(yearFormatter.format(date));
- result.append(':');
- // Time
- result.append(timeFormatter.format(date));
- result.append(space);
- // Time zone
- result.append(getTimeZone(date));
- result.append("] \"");
-
- // Check for log rotation
- if (rotatable) {
- // Check for a change of date
- String tsDate = dateFormatter.format(date);
- // If the date has changed, switch log files
- if (!dateStamp.equals(tsDate)) {
- synchronized (this) {
- if (!dateStamp.equals(tsDate)) {
- close();
- dateStamp = tsDate;
- open();
- }
- }
- }
- }
-
- currentDateString = result.toString();
- currentDate = date.getTime();
- }
- }
- }
- return currentDateString;
- }
-
-
- private String getTimeZone(Date date) {
- if (timezone.inDaylightTime(date)) {
- return timeZoneDST;
- } else {
- return timeZoneNoDST;
- }
- }
-
-
- private String calculateTimeZoneOffset(long offset) {
- StringBuffer tz = new StringBuffer();
- if ((offset<0)) {
- tz.append("-");
- offset = -offset;
- } else {
- tz.append("+");
- }
-
- long hourOffset = offset/(1000*60*60);
- long minuteOffset = (offset/(1000*60)) % 60;
-
- if (hourOffset<10)
- tz.append("0");
- tz.append(hourOffset);
-
- if (minuteOffset<10)
- tz.append("0");
- tz.append(minuteOffset);
-
- return tz.toString();
- }
-
-
- // ------------------------------------------------------ Lifecycle Methods
-
-
- /**
- * Add a lifecycle event listener to this component.
- *
- * @param listener The listener to add
- */
- public void addLifecycleListener(LifecycleListener listener) {
-
- lifecycle.addLifecycleListener(listener);
-
- }
-
-
- /**
- * Get the lifecycle listeners associated with this lifecycle. If this
- * Lifecycle has no listeners registered, a zero-length array is returned.
- */
- public LifecycleListener[] findLifecycleListeners() {
-
- return lifecycle.findLifecycleListeners();
-
- }
-
-
- /**
- * Remove a lifecycle event listener from this component.
- *
- * @param listener The listener to add
- */
- public void removeLifecycleListener(LifecycleListener listener) {
-
- lifecycle.removeLifecycleListener(listener);
-
- }
-
-
- /**
- * Prepare for the beginning of active use of the public methods of this
- * component. This method should be called after <code>configure()</code>,
- * and before any of the public methods of the component are utilized.
- *
- * @exception LifecycleException if this component detects a fatal error
- * that prevents this component from being used
- */
- public void start() throws LifecycleException {
-
- // Validate and update our current component state
- if (started)
- throw new LifecycleException
- (sm.getString("accessLogValve.alreadyStarted"));
- lifecycle.fireLifecycleEvent(START_EVENT, null);
- started = true;
-
- // Initialize the timeZone, Date formatters, and currentDate
- timezone = TimeZone.getDefault();
- timeZoneNoDST = calculateTimeZoneOffset(timezone.getRawOffset());
- Calendar calendar = Calendar.getInstance(timezone);
- int offset = calendar.get(Calendar.DST_OFFSET);
- timeZoneDST = calculateTimeZoneOffset(timezone.getRawOffset()+offset);
-
- if (fileDateFormat==null || fileDateFormat.length()==0)
- fileDateFormat = "yyyy-MM-dd";
- dateFormatter = new SimpleDateFormat(fileDateFormat);
- dateFormatter.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);
- currentDateString = getCurrentDateString();
- dateStamp = dateFormatter.format(new Date());
-
- open();
-
- }
-
-
- /**
- * Gracefully terminate the active use of the public methods of this
- * component. This method should be the last one called on a given
- * instance of this component.
- *
- * @exception LifecycleException if this component detects a fatal error
- * that needs to be reported
- */
- public void stop() throws LifecycleException {
-
- // Validate and update our current component state
- if (!started)
- throw new LifecycleException
- (sm.getString("accessLogValve.notStarted"));
- lifecycle.fireLifecycleEvent(STOP_EVENT, null);
- started = false;
-
- close();
-
- }
-}
+public final class FastCommonAccessLogValve extends AccessLogValve {
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org