amyroh 2002/11/22 12:27:13 Modified: catalina/src/share/org/apache/catalina/valves AccessLogValve.java Log: This patch allows for the following: %{xxx}i xxx is the name of the incoming header %{xxx}c xxx is the name of a specific cookie %{xxx}r xxx is an attribute in the ServletRequest %{xxx}s xxx is an attribute in the HttpSession For %A - uses InetAddress.getLocalHost() instead of hardcoded "127.0.0.1" Patch also allows access log not be rotated. This is done by adding a new attribute called rotatable. It defaults to true. If set to false - then the access log does not rotate. (Which will make a lot of tomcat-users happy) Submitted by Tim Funk <[EMAIL PROTECTED]> Revision Changes Path 1.15 +174 -26 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves/AccessLogValve.java Index: AccessLogValve.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves/AccessLogValve.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- AccessLogValve.java 9 Jun 2002 02:19:44 -0000 1.14 +++ AccessLogValve.java 22 Nov 2002 20:27:12 -0000 1.15 @@ -65,14 +65,17 @@ import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; +import java.net.InetAddress; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import org.apache.catalina.HttpResponse; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; @@ -124,8 +127,17 @@ * <code>%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"</code> * </ul> * - * <p><b>FIXME</b> - Improve the parsing so that things like - * <code>%{xxx}i</code> can be implemented.</p> + * <p> + * There is also support to write information from the cookie, incoming + * header, the Session or something else in the ServletRequest.<br> + * It is modeled after the apache syntax: + * <ul> + * <li><code>%{xxx}i</code> for incoming headers + * <li><code>%{xxx}c</code> for a specific cookie + * <li><code>%{xxx}r</code> xxx is an attribute in the ServletRequest + * <li><code>%{xxx}s</code> xxx is an attribute in the HttpSession + * </ul> + * </p> * * @author Craig R. McClanahan * @author Jason Brittain @@ -217,6 +229,12 @@ /** + * 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 = @@ -400,6 +418,28 @@ 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; + + } /** @@ -557,7 +597,31 @@ for (int i = 0; i < pattern.length(); i++) { char ch = pattern.charAt(i); if (replace) { - result.append(replace(ch, date, request, response)); + /* 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)); + } + } else { + result.append(replace(ch, date, request, response)); + } replace = false; } else if (ch == '%') { replace = true; @@ -599,28 +663,30 @@ */ public void log(String message, Date date) { - // Only do a logfile switch check once a second, max. - long systime = System.currentTimeMillis(); - if ((systime - rotationLastChecked) > 1000) { - - // We need a new currentDate - currentDate = new Date(systime); - rotationLastChecked = systime; - - // Check for a change of date - String tsDate = dateFormatter.format(currentDate); - - // If the date has changed, switch log files - if (!dateStamp.equals(tsDate)) { - synchronized (this) { - if (!dateStamp.equals(tsDate)) { - close(); - dateStamp = tsDate; - open(); + if (rotatable){ + // Only do a logfile switch check once a second, max. + long systime = System.currentTimeMillis(); + if ((systime - rotationLastChecked) > 1000) { + + // We need a new currentDate + currentDate = new Date(systime); + rotationLastChecked = systime; + + // Check for a change of date + String tsDate = dateFormatter.format(currentDate); + + // If the date has changed, switch log files + if (!dateStamp.equals(tsDate)) { + synchronized (this) { + if (!dateStamp.equals(tsDate)) { + close(); + dateStamp = tsDate; + open(); + } } } - } + } } // Log this message @@ -663,8 +729,15 @@ // Open the current log file try { - String pathname = dir.getAbsolutePath() + File.separator + - prefix + dateStamp + suffix; + 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 FileWriter(pathname, true), true); } catch (IOException e) { writer = null; @@ -699,7 +772,11 @@ if (pattern == 'a') { value = req.getRemoteAddr(); } else if (pattern == 'A') { - value = "127.0.0.1"; // FIXME + try { + value = InetAddress.getLocalHost().getHostAddress(); + } catch(Throwable e){ + value = "127.0.0.1"; + } } else if (pattern == 'b') { int length = response.getContentCount(); if (length <= 0) @@ -792,6 +869,77 @@ 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; + + ServletRequest req = request.getRequest(); + HttpServletRequest hreq = null; + if (req instanceof HttpServletRequest) + hreq = (HttpServletRequest) req; + + switch (type) { + case 'i': + if (null != hreq) + value = hreq.getHeader(header); + else + value= "??"; + break; +/* + // Someone please make me work + case 'o': + break; +*/ + case 'c': + Cookie[] c = hreq.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 != hreq) + value = hreq.getAttribute(header); + else + value= "??"; + break; + case 's': + if (null != hreq) { + HttpSession sess = hreq.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 "-"; + } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>