e.g. Calendar Search Help
You must enter a value before pressing Search
tomcat

Class: org.apache.catalina.valves.AccessLogValve   ©

 OK to copy?
0001 /*
0002  * Copyright 1999-2001,2004 The Apache Software Foundation.
0003  * 
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  * 
0008  *      http://www.apache.org/licenses/LICENSE-2.0
0009  * 
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
0015  */
0016 
0017 
0018 package org.apache.catalina.valves;
0019 
0020 
0021 import java.io.File;
0022 import java.io.FileWriter;
0023 import java.io.IOException;
0024 import java.io.PrintWriter;
0025 import java.net.InetAddress;
0026 import java.text.DecimalFormat;
0027 import java.text.SimpleDateFormat;
0028 import java.util.Date;
0029 import java.util.TimeZone;
0030 
0031 import javax.servlet.ServletException;
0032 import javax.servlet.http.Cookie;
0033 import javax.servlet.http.HttpSession;
0034 
0035 import org.apache.catalina.Lifecycle;
0036 import org.apache.catalina.LifecycleException;
0037 import org.apache.catalina.LifecycleListener;
0038 import org.apache.catalina.connector.Request;
0039 import org.apache.catalina.connector.Response;
0040 import org.apache.catalina.util.LifecycleSupport;
0041 import org.apache.catalina.util.StringManager;
0042 
0043 
0044 /**
0045  * <p>Implementation of the <b>Valve</b> interface that generates a web server
0046  * access log with the detailed line contents matching a configurable pattern.
0047  * The syntax of the available patterns is similar to that supported by the
0048  * Apache <code>mod_log_config</code> module.  As an additional feature,
0049  * automatic rollover of log files when the date changes is also supported.</p>
0050  *
0051  * <p>Patterns for the logged message may include constant text or any of the
0052  * following replacement strings, for which the corresponding information
0053  * from the specified Response is substituted:</p>
0054  * <ul>
0055  * <li><b>%a</b> - Remote IP address
0056  * <li><b>%A</b> - Local IP address
0057  * <li><b>%b</b> - Bytes sent, excluding HTTP headers, or '-' if no bytes
0058  *     were sent
0059  * <li><b>%B</b> - Bytes sent, excluding HTTP headers
0060  * <li><b>%h</b> - Remote host name
0061  * <li><b>%H</b> - Request protocol
0062  * <li><b>%l</b> - Remote logical username from identd (always returns '-')
0063  * <li><b>%m</b> - Request method
0064  * <li><b>%p</b> - Local port
0065  * <li><b>%q</b> - Query string (prepended with a '?' if it exists, otherwise
0066  *     an empty string
0067  * <li><b>%r</b> - First line of the request
0068  * <li><b>%s</b> - HTTP status code of the response
0069  * <li><b>%S</b> - User session ID
0070  * <li><b>%t</b> - Date and time, in Common Log Format format
0071  * <li><b>%u</b> - Remote user that was authenticated
0072  * <li><b>%U</b> - Requested URL path
0073  * <li><b>%v</b> - Local server name
0074  * <li><b>%D</b> - Time taken to process the request, in millis
0075  * <li><b>%T</b> - Time taken to process the request, in seconds
0076  * </ul>
0077  * <p>In addition, the caller can specify one of the following aliases for
0078  * commonly utilized patterns:</p>
0079  * <ul>
0080  * <li><b>common</b> - <code>%h %l %u %t "%r" %s %b</code>
0081  * <li><b>combined</b> -
0082  *   <code>%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"</code>
0083  * </ul>
0084  *
0085  * <p>
0086  * There is also support to write information from the cookie, incoming
0087  * header, the Session or something else in the ServletRequest.<br>
0088  * It is modeled after the apache syntax:
0089  * <ul>
0090  * <li><code>%{xxx}i</code> for incoming headers
0091  * <li><code>%{xxx}c</code> for a specific cookie
0092  * <li><code>%{xxx}r</code> xxx is an attribute in the ServletRequest
0093  * <li><code>%{xxx}s</code> xxx is an attribute in the HttpSession
0094  * </ul>
0095  * </p>
0096  *
0097  * <p>
0098  * Conditional logging is also supported. This can be done with the
0099  * <code>condition</code> property.
0100  * If the value returned from ServletRequest.getAttribute(condition)
0101  * yields a non-null value. The logging will be skipped.
0102  * </p>
0103  *
0104  * @author Craig R. McClanahan
0105  * @author Jason Brittain
0106  * @version $Revision: 1.12 $ $Date: 2004/06/24 16:20:21 $
0107  */
0108 
0109 public final class AccessLogValve
0110     extends ValveBase
0111     implements Lifecycle {
0112 
0113 
0114     // ----------------------------------------------------------- Constructors
0115 
0116 
0117     /**
0118      * Construct a new instance of this class with default property values.
0119      */
0120     public AccessLogValve() {
0121 
0122         super();
0123         setPattern("common");
0124 
0125 
0126     }
0127 
0128 
0129     // ----------------------------------------------------- Instance Variables
0130 
0131 
0132     /**
0133      * The as-of date for the currently open log file, or a zero-length
0134      * string if there is no open log file.
0135      */
0136     private String dateStamp = "";
0137 
0138 
0139     /**
0140      * The directory in which log files are created.
0141      */
0142     private String directory = "logs";
0143 
0144 
0145     /**
0146      * The descriptive information about this implementation.
0147      */
0148     protected static final String info =
0149         "org.apache.catalina.valves.AccessLogValve/1.0";
0150 
0151 
0152     /**
0153      * The lifecycle event support for this component.
0154      */
0155     protected LifecycleSupport lifecycle = new LifecycleSupport(this);
0156 
0157 
0158     /**
0159      * The set of month abbreviations for log messages.
0160      */
0161     protected static final String months[] =
0162     { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
0163       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
0164 
0165 
0166     /**
0167      * If the current log pattern is the same as the common access log
0168      * format pattern, then we'll set this variable to true and log in
0169      * a more optimal and hard-coded way.
0170      */
0171     private boolean common = false;
0172 
0173 
0174     /**
0175      * For the combined format (common, plus useragent and referer), we do
0176      * the same
0177      */
0178     private boolean combined = false;
0179 
0180 
0181     /**
0182      * The pattern used to format our access log lines.
0183      */
0184     private String pattern = null;
0185 
0186 
0187     /**
0188      * The prefix that is added to log file filenames.
0189      */
0190     private String prefix = "access_log.";
0191 
0192 
0193     /**
0194      * Should we rotate our log file? Default is true (like old behavior)
0195      */
0196     private boolean rotatable = true;
0197 
0198 
0199     /**
0200      * The string manager for this package.
0201      */
0202     private StringManager sm =
0203         StringManager.getManager(Constants.Package);
0204 
0205 
0206     /**
0207      * Has this component been started yet?
0208      */
0209     private boolean started = false;
0210 
0211 
0212     /**
0213      * The suffix that is added to log file filenames.
0214      */
0215     private String suffix = "";
0216 
0217 
0218     /**
0219      * The PrintWriter to which we are currently logging, if any.
0220      */
0221     private PrintWriter writer = null;
0222 
0223 
0224     /**
0225      * A date formatter to format a Date into a date in the format
0226      * "yyyy-MM-dd".
0227      */
0228     private SimpleDateFormat dateFormatter = null;
0229 
0230 
0231     /**
0232      * A date formatter to format Dates into a day string in the format
0233      * "dd".
0234      */
0235     private SimpleDateFormat dayFormatter = null;
0236 
0237 
0238     /**
0239      * A date formatter to format a Date into a month string in the format
0240      * "MM".
0241      */
0242     private SimpleDateFormat monthFormatter = null;
0243 
0244 
0245     /**
0246      * Time taken formatter for 3 decimal places.
0247      */
0248      private DecimalFormat timeTakenFormatter = null;
0249 
0250 
0251     /**
0252      * A date formatter to format a Date into a year string in the format
0253      * "yyyy".
0254      */
0255     private SimpleDateFormat yearFormatter = null;
0256 
0257 
0258     /**
0259      * A date formatter to format a Date into a time in the format
0260      * "kk:mm:ss" (kk is a 24-hour representation of the hour).
0261      */
0262     private SimpleDateFormat timeFormatter = null;
0263 
0264 
0265     /**
0266      * The time zone relative to GMT.
0267      */
0268     private String timeZone = null;
0269 
0270 
0271     /**
0272      * The system time when we last updated the Date that this valve
0273      * uses for log lines.
0274      */
0275     private Date currentDate = null;
0276 
0277 
0278     /**
0279      * When formatting log lines, we often use strings like this one (" ").
0280      */
0281     private String space = " ";
0282 
0283 
0284     /**
0285      * Resolve hosts.
0286      */
0287     private boolean resolveHosts = false;
0288 
0289 
0290     /**
0291      * Instant when the log daily rotation was last checked.
0292      */
0293     private long rotationLastChecked = 0L;
0294 
0295 
0296     /**
0297      * Are we doing conditional logging. default false.
0298      */
0299     private String condition = null;
0300 
0301 
0302     /**
0303      * Date format to place in log file name. Use at your own risk!
0304      */
0305     private String fileDateFormat = null;
0306 
0307     // ------------------------------------------------------------- Properties
0308 
0309 
0310     /**
0311      * Return the directory in which we create log files.
0312      */
0313     public String getDirectory() {
0314 
0315         return (directory);
0316 
0317     }
0318 
0319 
0320     /**
0321      * Set the directory in which we create log files.
0322      *
0323      * @param directory The new log file directory
0324      */
0325     public void setDirectory(String directory) {
0326 
0327         this.directory = directory;
0328 
0329     }
0330 
0331 
0332     /**
0333      * Return descriptive information about this implementation.
0334      */
0335     public String getInfo() {
0336 
0337         return (info);
0338 
0339     }
0340 
0341 
0342     /**
0343      * Return the format pattern.
0344      */
0345     public String getPattern() {
0346 
0347         return (this.pattern);
0348 
0349     }
0350 
0351 
0352     /**
0353      * Set the format pattern, first translating any recognized alias.
0354      *
0355      * @param pattern The new pattern
0356      */
0357     public void setPattern(String pattern) {
0358 
0359         if (pattern == null)
0360             pattern = "";
0361         if (pattern.equals(Constants.AccessLog.COMMON_ALIAS))
0362             pattern = Constants.AccessLog.COMMON_PATTERN;
0363         if (pattern.equals(Constants.AccessLog.COMBINED_ALIAS))
0364             pattern = Constants.AccessLog.COMBINED_PATTERN;
0365         this.pattern = pattern;
0366 
0367         if (this.pattern.equals(Constants.AccessLog.COMMON_PATTERN))
0368             common = true;
0369         else
0370             common = false;
0371 
0372         if (this.pattern.equals(Constants.AccessLog.COMBINED_PATTERN))
0373             combined = true;
0374         else
0375             combined = false;
0376 
0377     }
0378 
0379 
0380     /**
0381      * Return the log file prefix.
0382      */
0383     public String getPrefix() {
0384 
0385         return (prefix);
0386 
0387     }
0388 
0389 
0390     /**
0391      * Set the log file prefix.
0392      *
0393      * @param prefix The new log file prefix
0394      */
0395     public void setPrefix(String prefix) {
0396 
0397         this.prefix = prefix;
0398 
0399     }
0400 
0401 
0402     /**
0403      * Should we rotate the logs
0404      */
0405     public boolean isRotatable() {
0406 
0407         return rotatable;
0408 
0409     }
0410 
0411 
0412     /**
0413      * Set the value is we should we rotate the logs
0414      *
0415      * @param rotatable true is we should rotate.
0416      */
0417     public void setRotatable(boolean rotatable) {
0418 
0419         this.rotatable = rotatable;
0420 
0421     }
0422 
0423 
0424     /**
0425      * Return the log file suffix.
0426      */
0427     public String getSuffix() {
0428 
0429         return (suffix);
0430 
0431     }
0432 
0433 
0434     /**
0435      * Set the log file suffix.
0436      *
0437      * @param suffix The new log file suffix
0438      */
0439     public void setSuffix(String suffix) {
0440 
0441         this.suffix = suffix;
0442 
0443     }
0444 
0445 
0446     /**
0447      * Set the resolve hosts flag.
0448      *
0449      * @param resolveHosts The new resolve hosts value
0450      */
0451     public void setResolveHosts(boolean resolveHosts) {
0452 
0453         this.resolveHosts = resolveHosts;
0454 
0455     }
0456 
0457 
0458     /**
0459      * Get the value of the resolve hosts flag.
0460      */
0461     public boolean isResolveHosts() {
0462 
0463         return resolveHosts;
0464 
0465     }
0466 
0467 
0468     /**
0469      * Return whether the attribute name to look for when
0470      * performing conditional loggging. If null, every
0471      * request is logged.
0472      */
0473     public String getCondition() {
0474 
0475         return condition;
0476 
0477     }
0478 
0479 
0480     /**
0481      * Set the ServletRequest.attribute to look for to perform
0482      * conditional logging. Set to null to log everything.
0483      *
0484      * @param condition Set to null to log everything
0485      */
0486     public void setCondition(String condition) {
0487 
0488         this.condition = condition;
0489 
0490     }
0491 
0492     /**
0493      *  Return the date format date based log rotation.
0494      */
0495     public String getFileDateFormat() {
0496         return fileDateFormat;
0497     }
0498 
0499 
0500     /**
0501      *  Set the date format date based log rotation.
0502      */
0503     public void setFileDateFormat(String fileDateFormat) {
0504         this.fileDateFormat =  fileDateFormat;
0505     }
0506 
0507     // --------------------------------------------------------- Public Methods
0508 
0509 
0510     /**
0511      * Log a message summarizing the specified request and response, according
0512      * to the format specified by the <code>pattern</code> property.
0513      *
0514      * @param request Request being processed
0515      * @param response Response being processed
0516      * @param context The valve context used to invoke the next valve
0517      *  in the current processing pipeline
0518      *
0519      * @exception IOException if an input/output error has occurred
0520      * @exception ServletException if a servlet error has occurred
0521      */
0522     public void invoke(Request request, Response response)
0523         throws IOException, ServletException {
0524 
0525         // Pass this request on to the next valve in our pipeline
0526         long t1=System.currentTimeMillis();
0527 
0528         getNext().invoke(request, response);
0529 
0530         long t2=System.currentTimeMillis();
0531         long time=t2-t1;
0532 
0533         if (condition!=null &&
0534                 null!=request.getRequest().getAttribute(condition)) {
0535             return;
0536         }
0537 
0538 
0539         Date date = getDate();
0540         StringBuffer result = new StringBuffer();
0541 
0542         // Check to see if we should log using the "common" access log pattern
0543         if (common || combined) {
0544             String value = null;
0545 
0546             if (isResolveHosts())
0547                 result.append(request.getRemoteHost());
0548             else
0549                 result.append(request.getRemoteAddr());
0550 
Rate0551             result.append(" - ");
0552 
0553             value = request.getRemoteUser();
0554             if (value == null)
0555                 result.append("- ");
0556             else {
0557                 result.append(value);
0558                 result.append(space);
0559             }
0560 
0561             result.append("[");
0562             result.append(dayFormatter.format(date));            // Day
0563             result.append('/');
0564             result.append(lookup(monthFormatter.format(date))); // Month
0565             result.append('/');
0566             result.append(yearFormatter.format(date));            // Year
0567             result.append(':');
0568             result.append(timeFormatter.format(date));        // Time
0569             result.append(space);
0570             result.append(timeZone);                            // Time Zone
0571             result.append("] \"");
0572 
0573             result.append(request.getMethod());
0574             result.append(space);
0575             result.append(request.getRequestURI());
0576             if (request.getQueryString() != null) {
0577                 result.append('?');
0578                 result.append(request.getQueryString());
0579             }
0580             result.append(space);
0581             result.append(request.getProtocol());
0582             result.append("\" ");
0583 
0584             result.append(response.getStatus());
0585 
0586             result.append(space);
0587 
0588             int length = response.getContentCount();
0589 
0590             if (length <= 0)
0591                 value = "-";
0592             else
0593                 value = "" + length;
0594             result.append(value);
0595 
0596             if (combined) {
0597                 result.append(space);
0598                 result.append("\"");
0599                 String referer = request.getHeader("referer");
0600                 if(referer != null)
0601                     result.append(referer);
0602                 else
0603                     result.append("-");
0604                 result.append("\"");
0605 
0606                 result.append(space);
0607                 result.append("\"");
0608                 String ua = request.getHeader("user-agent");
0609                 if(ua != null)
0610                     result.append(ua);
0611                 else
0612                     result.append("-");
0613                 result.append("\"");
0614             }
0615 
0616         } else {
0617             // Generate a message based on the defined pattern
0618             boolean replace = false;
0619             for (int i = 0; i < pattern.length(); i++) {
0620                 char ch = pattern.charAt(i);
0621                 if (replace) {
0622                     /* For code that processes {, the behavior will be ... if I
0623                      * do not enounter a closing } - then I ignore the {
0624                      */
0625                     if ('{' == ch){
0626                         StringBuffer name = new StringBuffer();
0627                         int j = i + 1;
0628                         for(;j < pattern.length() && '}' != pattern.charAt(j); j++) {
0629                             name.append(pattern.charAt(j));
0630                         }
0631                         if (j+1 < pattern.length()) {
0632                             /* the +1 was to account for } which we increment now */
0633                             j++;
0634                             result.append(replace(name.toString(),
0635                                                 pattern.charAt(j),
0636                                                 request,
0637                                                 response));
0638                             i=j; /*Since we walked more than one character*/
0639                         } else {
0640                             //D'oh - end of string - pretend we never did this
0641                             //and do processing the "old way"
0642                             result.append(replace(ch, date, request, response, time));
0643                         }
0644                     } else {
0645                         result.append(replace(ch, date, request, response,time ));
0646                     }
0647                     replace = false;
0648                 } else if (ch == '%') {
0649                     replace = true;
0650                 } else {
0651                     result.append(ch);
0652                 }
0653             }
0654         }
0655         log(result.toString(), date);
0656 
0657     }
0658 
0659 
0660     // -------------------------------------------------------- Private Methods
0661 
0662 
0663     /**
0664      * Close the currently open log file (if any)
0665      */
0666     private synchronized void close() {
0667 
0668         if (writer == null)
0669             return;
0670         writer.flush();
0671         writer.close();
0672         writer = null;
0673         dateStamp = "";
0674 
0675     }
0676 
0677 
0678     /**
0679      * Log the specified message to the log file, switching files if the date
0680      * has changed since the previous log call.
0681      *
0682      * @param message Message to be logged
0683      * @param date the current Date object (so this method doesn't need to
0684      *        create a new one)
0685      */
0686     public void log(String message, Date date) {
0687 
0688         if (rotatable){
0689             // Only do a logfile switch check once a second, max.
0690             long systime = System.currentTimeMillis();
0691             if ((systime - rotationLastChecked) > 1000) {
0692 
0693                 // We need a new currentDate
0694                 currentDate = new Date(systime);
0695                 rotationLastChecked = systime;
0696 
0697                 // Check for a change of date
0698                 String tsDate = dateFormatter.format(currentDate);
0699 
0700                 // If the date has changed, switch log files
0701                 if (!dateStamp.equals(tsDate)) {
0702                     synchronized (this) {
0703                         if (!dateStamp.equals(tsDate)) {
0704                             close();
0705                             dateStamp = tsDate;
0706                             open();
0707                         }
0708                     }
0709                 }
0710 
0711             }
0712         }
0713 
0714         // Log this message
0715         if (writer != null) {
0716             writer.println(message);
0717         }
0718 
0719     }
0720 
0721 
0722     /**
0723      * Return the month abbreviation for the specified month, which must
0724      * be a two-digit String.
0725      *
0726      * @param month Month number ("01" .. "12").
0727      */
0728     private String lookup(String month) {
0729 
0730         int index;
0731         try {
0732             index = Integer.parseInt(month) - 1;
0733         } catch (Throwable t) {
0734             index = 0;  // Can not happen, in theory
0735         }
0736         return (months[index]);
0737 
0738     }
0739 
0740 
0741     /**
0742      * Open the new log file for the date specified by <code>dateStamp</code>.
0743      */
0744     private synchronized void open() {
0745 
0746         // Create the directory if necessary
0747         File dir = new File(directory);
0748         if (!dir.isAbsolute())
0749             dir = new File(System.getProperty("catalina.base"), directory);
0750         dir.mkdirs();
0751 
0752         // Open the current log file
0753         try {
0754             String pathname;
0755             // If no rotate - no need for dateStamp in fileName
0756             if (rotatable){
0757                 pathname = dir.getAbsolutePath() + File.separator +
0758                             prefix + dateStamp + suffix;
0759             } else {
0760                 pathname = dir.getAbsolutePath() + File.separator +
0761                             prefix + suffix;
0762             }
0763             writer = new PrintWriter(new FileWriter(pathname, true), true);
0764         } catch (IOException e) {
0765             writer = null;
0766         }
0767 
0768     }
0769 
0770 
0771     /**
0772      * Return the replacement text for the specified pattern character.
0773      *
0774      * @param pattern Pattern character identifying the desired text
0775      * @param date the current Date so that this method doesn't need to
0776      *        create one
0777      * @param request Request being processed
0778      * @param response Response being processed
0779      */
0780     private String replace(char pattern, Date date, Request request,
0781                            Response response, long time) {
0782 
0783         String value = null;
0784 
0785         if (pattern == 'a') {
0786             value = request.getRemoteAddr();
0787         } else if (pattern == 'A') {
0788             try {
0789                 value = InetAddress.getLocalHost().getHostAddress();
0790             } catch(Throwable e){
0791                 value = "127.0.0.1";
0792             }
0793         } else if (pattern == 'b') {
0794             int length = response.getContentCount();
0795             if (length <= 0)
0796                 value = "-";
0797             else
0798                 value = "" + length;
0799         } else if (pattern == 'B') {
0800             value = "" + response.getContentLength();
0801         } else if (pattern == 'h') {
0802             value = request.getRemoteHost();
0803         } else if (pattern == 'H') {
0804             value = request.getProtocol();
0805         } else if (pattern == 'l') {
0806             value = "-";
0807         } else if (pattern == 'm') {
0808             if (request != null)
0809                 value = request.getMethod();
0810             else
0811                 value = "";
0812         } else if (pattern == 'p') {
0813             value = "" + request.getServerPort();
0814         } else if (pattern == 'D') {
0815                     value = "" + time;
0816         } else if (pattern == 'q') {
0817             String query = null;
0818             if (request != null)
0819                 query = request.getQueryString();
0820             if (query != null)
0821                 value = "?" + query;
0822             else
0823                 value = "";
0824         } else if (pattern == 'r') {
0825             StringBuffer sb = new StringBuffer();
0826             if (request != null) {
0827                 sb.append(request.getMethod());
0828                 sb.append(space);
0829                 sb.append(request.getRequestURI());
0830                 if (request.getQueryString() != null) {
0831                     sb.append('?');
0832                     sb.append(request.getQueryString());
0833                 }
0834                 sb.append(space);
0835                 sb.append(request.getProtocol());
0836             } else {
0837                 sb.append("- - ");
0838                 sb.append(request.getProtocol());
0839             }
0840             value = sb.toString();
0841         } else if (pattern == 'S') {
0842             if (request != null)
0843                 if (request.getSession(false) != null)
0844                     value = request.getSession(false).getId();
0845                 else value = "-";
0846             else
0847                 value = "-";
0848         } else if (pattern == 's') {
0849             if (response != null)
0850                 value = "" + response.getStatus();
0851             else
0852                 value = "-";
0853         } else if (pattern == 't') {
0854             StringBuffer temp = new StringBuffer("[");
0855             temp.append(dayFormatter.format(date));             // Day
0856             temp.append('/');
0857             temp.append(lookup(monthFormatter.format(date)));   // Month
0858             temp.append('/');
0859             temp.append(yearFormatter.format(date));            // Year
0860             temp.append(':');
0861             temp.append(timeFormatter.format(date));            // Time
0862             temp.append(' ');
0863             temp.append(timeZone);                              // Timezone
0864             temp.append(']');
0865             value = temp.toString();
0866         } else if (pattern == 'T') {
0867             value = timeTakenFormatter.format(time/1000d);
Rate0868         } else if (pattern == 'u') {
0869             if (request != null)
0870                 value = request.getRemoteUser();
0871             if (value == null)
0872                 value = "-";
0873         } else if (pattern == 'U') {
0874             if (request != null)
0875                 value = request.getRequestURI();
0876             else
0877                 value = "-";
0878         } else if (pattern == 'v') {
0879             value = request.getServerName();
0880         } else {
0881             value = "???" + pattern + "???";
0882         }
0883 
0884         if (value == null)
0885             return ("");
0886         else
0887             return (value);
0888 
0889     }
0890 
0891 
0892     /**
0893      * Return the replacement text for the specified "header/parameter".
0894      *
0895      * @param header The header/parameter to get
0896      * @param type Where to get it from i=input,c=cookie,r=ServletRequest,s=Session
0897      * @param request Request being processed
0898      * @param response Response being processed
0899      */
0900     private String replace(String header, char type, Request request,
0901                            Response response) {
0902 
0903         Object value = null;
0904 
0905         switch (type) {
0906             case 'i':
0907                 if (null != request)
0908                     value = request.getHeader(header);
0909                 else
0910                     value= "??";
0911                 break;
0912 /*
0913             // Someone please make me work
0914             case 'o':
0915                 break;
0916 */
0917             case 'c':
0918                  Cookie[] c = request.getCookies();
0919                  for (int i=0; c != null && i < c.length; i++){
0920                      if (header.equals(c[i].getName())){
0921                          value = c[i].getValue();
0922                          break;
0923                      }
0924                  }
0925                 break;
0926             case 'r':
0927                 if (null != request)
0928                     value = request.getAttribute(header);
0929                 else
0930                     value= "??";
0931                 break;
0932             case 's':
0933                 if (null != request) {
0934                     HttpSession sess = request.getSession(false);
0935                     if (null != sess)
0936                         value = sess.getAttribute(header);
0937                 }
0938                break;
0939             default:
0940                 value = "???";
0941         }
0942 
0943         /* try catch in case toString() barfs */
0944         try {
0945             if (value!=null)
0946                 if (value instanceof String)
0947                     return (String)value;
0948                 else
0949                     return value.toString();
0950             else
0951                return "-";
0952         } catch(Throwable e) {
0953             return "-";
0954         }
0955     }
0956 
0957 
0958     /**
0959      * This method returns a Date object that is accurate to within one
0960      * second.  If a thread calls this method to get a Date and it's been
0961      * less than 1 second since a new Date was created, this method
0962      * simply gives out the same Date again so that the system doesn't
0963      * spend time creating Date objects unnecessarily.
0964      *
0965      * @return Date
0966      */
0967     private Date getDate() {
0968         if(currentDate == null) {
0969         currentDate = new Date();
0970         } else {
0971           // Only create a new Date once per second, max.
0972           long systime = System.currentTimeMillis();
0973           if ((systime - currentDate.getTime()) > 1000) {
0974               currentDate = new Date(systime);
0975           }
0976     }
0977 
0978         return currentDate;
0979     }
0980 
0981 
0982     private String calculateTimeZoneOffset(long offset) {
0983         StringBuffer tz = new StringBuffer();
0984         if ((offset<0))  {
0985             tz.append("-");
0986             offset = -offset;
0987         } else {
0988             tz.append("+");
0989         }
0990 
0991         long hourOffset = offset/(1000*60*60);
0992         long minuteOffset = (offset/(1000*60)) % 60;
0993 
0994         if (hourOffset<10)
0995             tz.append("0");
0996         tz.append(hourOffset);
0997 
0998         if (minuteOffset<10)
0999             tz.append("0");
1000         tz.append(minuteOffset);
1001 
1002         return tz.toString();
1003     }
1004 
1005 
1006     // ------------------------------------------------------ Lifecycle Methods
1007 
1008 
1009     /**
1010      * Add a lifecycle event listener to this component.
1011      *
1012      * @param listener The listener to add
1013      */
1014     public void addLifecycleListener(LifecycleListener listener) {
1015 
1016         lifecycle.addLifecycleListener(listener);
1017 
1018     }
1019 
1020 
1021     /**
1022      * Get the lifecycle listeners associated with this lifecycle. If this
1023      * Lifecycle has no listeners registered, a zero-length array is returned.
1024      */
1025     public LifecycleListener[] findLifecycleListeners() {
1026 
1027         return lifecycle.findLifecycleListeners();
1028 
1029     }
1030 
1031 
1032     /**
1033      * Remove a lifecycle event listener from this component.
1034      *
1035      * @param listener The listener to add
1036      */
1037     public void removeLifecycleListener(LifecycleListener listener) {
1038 
1039         lifecycle.removeLifecycleListener(listener);
1040 
1041     }
1042 
1043 
1044     /**
1045      * Prepare for the beginning of active use of the public methods of this
1046      * component.  This method should be called after <code>configure()</code>,
1047      * and before any of the public methods of the component are utilized.
1048      *
1049      * @exception LifecycleException if this component detects a fatal error
1050      *  that prevents this component from being used
1051      */
1052     public void start() throws LifecycleException {
1053 
1054         // Validate and update our current component state
1055         if (started)
1056             throw new LifecycleException
1057                 (sm.getString("accessLogValve.alreadyStarted"));
1058         lifecycle.fireLifecycleEvent(START_EVENT, null);
1059         started = true;
1060 
1061         // Initialize the timeZone, Date formatters, and currentDate
1062         TimeZone tz = TimeZone.getDefault();
1063         timeZone = calculateTimeZoneOffset(tz.getRawOffset());
1064 
1065         if (fileDateFormat==null || fileDateFormat.length()==0)
1066             fileDateFormat = "yyyy-MM-dd";
1067         dateFormatter = new SimpleDateFormat(fileDateFormat);
1068         dateFormatter.setTimeZone(tz);
1069         dayFormatter = new SimpleDateFormat("dd");
1070         dayFormatter.setTimeZone(tz);
1071         monthFormatter = new SimpleDateFormat("MM");
1072         monthFormatter.setTimeZone(tz);
1073         yearFormatter = new SimpleDateFormat("yyyy");
1074         yearFormatter.setTimeZone(tz);
1075         timeFormatter = new SimpleDateFormat("HH:mm:ss");
1076         timeFormatter.setTimeZone(tz);
1077         currentDate = new Date();
1078         dateStamp = dateFormatter.format(currentDate);
1079         timeTakenFormatter = new DecimalFormat("0.000");
1080 
1081         open();
1082 
1083     }
1084 
1085 
1086     /**
1087      * Gracefully terminate the active use of the public methods of this
1088      * component.  This method should be the last one called on a given
1089      * instance of this component.
1090      *
1091      * @exception LifecycleException if this component detects a fatal error
1092      *  that needs to be reported
1093      */
1094     public void stop() throws LifecycleException {
1095 
1096         // Validate and update our current component state
1097         if (!started)
1098             throw new LifecycleException
1099                 (sm.getString("accessLogValve.notStarted"));
1100         lifecycle.fireLifecycleEvent(STOP_EVENT, null);
1101         started = false;
1102 
1103         close();
1104 
1105     }
1106 }

            
All Examples in File:
Example
Line
Rating (found
useful by...)
551 0% of 0
868 0% of 0