001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.cluster.tcp;
018:
019: import java.io.IOException;
020: import java.util.ArrayList;
021: import java.util.Enumeration;
022: import java.util.Iterator;
023: import javax.servlet.ServletException;
024: import javax.servlet.ServletRequest;
025: import javax.servlet.ServletResponse;
026: import javax.servlet.http.Cookie;
027: import javax.servlet.http.HttpSession;
028: import javax.servlet.http.HttpServletRequest;
029: import javax.servlet.http.HttpServletResponse;
030: import org.apache.catalina.Container;
031: import org.apache.catalina.HttpRequest;
032: import org.apache.catalina.HttpResponse;
033: import org.apache.catalina.Logger;
034: import org.apache.catalina.Request;
035: import org.apache.catalina.Response;
036: import org.apache.catalina.Valve;
037: import org.apache.catalina.ValveContext;
038: import org.apache.catalina.util.StringManager;
039: import org.apache.catalina.valves.*;
040: import org.apache.catalina.cluster.SessionMessage;
041: import org.apache.catalina.cluster.CatalinaCluster;
042: import org.apache.catalina.cluster.ClusterSession;
043: import org.apache.catalina.cluster.ClusterManager;
044:
045: /**
046: * <p>Implementation of a Valve that logs interesting contents from the
047: * specified Request (before processing) and the corresponding Response
048: * (after processing). It is especially useful in debugging problems
049: * related to headers and cookies.</p>
050: *
051: * <p>This Valve may be attached to any Container, depending on the granularity
052: * of the logging you wish to perform.</p>
053: *
054: * @author Craig R. McClanahan
055: * @version $Revision: 1.13 $ $Date: 2004/06/08 20:23:55 $
056: */
057:
058: public class ReplicationValve extends ValveBase {
059: private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
060: .getLog(ReplicationValve.class);
061:
062: // ----------------------------------------------------- Instance Variables
063:
064: /**
065: * The descriptive information related to this implementation.
066: */
067: private static final String info = "org.apache.catalina.cluster.tcp.ReplicationValve/1.0";
068:
069: /**
070: * The StringManager for this package.
071: */
072: protected static StringManager sm = StringManager
073: .getManager(Constants.Package);
074:
075: /**
076: * holds file endings to not call for like images and others
077: */
078: protected java.util.regex.Pattern[] reqFilters = new java.util.regex.Pattern[0];
079:
080: protected int debug = 0;
081:
082: // ------------------------------------------------------------- Properties
083:
084: public ReplicationValve() {
085: }
086:
087: /**
088: * Return descriptive information about this Valve implementation.
089: */
090: public String getInfo() {
091:
092: return (info);
093:
094: }
095:
096: // --------------------------------------------------------- Public Methods
097: protected static long totalRequestTime = 0;
098: protected static long totalSendTime = 0;
099: protected static long nrOfRequests = 0;
100: protected static long lastSendTime = 0;
101:
102: protected static synchronized void addClusterSendTime(
103: long requestTime, long clusterTime) {
104: totalSendTime += clusterTime;
105: totalRequestTime += requestTime;
106: nrOfRequests++;
107: if ((nrOfRequests % 100) == 0) {
108: log.info("Average request time="
109: + (totalRequestTime / nrOfRequests) + " ms for "
110: + "Cluster overhead time="
111: + (totalSendTime / nrOfRequests) + " ms for "
112: + nrOfRequests + " requests (Request="
113: + totalRequestTime + "ms Cluster=" + totalSendTime
114: + "ms).");
115: lastSendTime = System.currentTimeMillis();
116: }//end if
117: }
118:
119: /**
120: * Log the interesting request parameters, invoke the next Valve in the
121: * sequence, and log the interesting response parameters.
122: *
123: * @param request The servlet request to be processed
124: * @param response The servlet response to be created
125: * @param context The valve context used to invoke the next valve
126: * in the current processing pipeline
127: *
128: * @exception IOException if an input/output error occurs
129: * @exception ServletException if a servlet error occurs
130: */
131: public void invoke(Request request, Response response,
132: ValveContext context) throws IOException, ServletException {
133: long totalstart = System.currentTimeMillis();
134: //this happens before the request
135: //long _debugstart = System.currentTimeMillis();
136: context.invokeNext(request, response);
137: //System.out.println("[DEBUG] Regular invoke took="+(System.currentTimeMillis()-_debugstart)+" ms.");
138: //this happens after the request
139: try {
140: long start = System.currentTimeMillis();
141: HttpRequest hrequest = (HttpRequest) request;
142: HttpServletRequest hreq = (HttpServletRequest) hrequest
143: .getRequest();
144: HttpSession session = hreq.getSession(false);
145:
146: if (!(request.getContext().getManager() instanceof ClusterManager))
147: return;
148:
149: ClusterManager manager = (ClusterManager) request
150: .getContext().getManager();
151: CatalinaCluster cluster = (CatalinaCluster) getContainer()
152: .getCluster();
153: if (cluster == null) {
154: log.warn("No cluster configured for this request.");
155: return;
156: }
157: //first check for session invalidations
158: String[] invalidIds = manager.getInvalidatedSessions();
159: if (invalidIds.length > 0) {
160: for (int i = 0; i < invalidIds.length; i++) {
161: try {
162: SessionMessage imsg = manager
163: .requestCompleted(invalidIds[i]);
164: if (imsg != null)
165: cluster.send(imsg);
166: } catch (Exception x) {
167: log
168: .error(
169: "Unable to send session invalid message over cluster.",
170: x);
171: }
172: }
173: }
174:
175: String id = null;
176: if (session != null)
177: id = session.getId();
178: else
179: return;
180:
181: if (id == null)
182: return;
183:
184: if ((request.getContext().getManager() == null)
185: || (!(request.getContext().getManager() instanceof ClusterManager)))
186: return;
187:
188: String uri = hrequest.getDecodedRequestURI();
189: boolean filterfound = false;
190:
191: for (int i = 0; (i < reqFilters.length) && (!filterfound); i++) {
192: java.util.regex.Matcher matcher = reqFilters[i]
193: .matcher(uri);
194: filterfound = matcher.matches();
195: }//for
196: if (filterfound)
197: return;
198:
199: log.debug("Invoking replication request on " + uri);
200:
201: SessionMessage msg = manager.requestCompleted(id);
202:
203: if (msg == null)
204: return;
205:
206: cluster.send(msg);
207: long stop = System.currentTimeMillis();
208: addClusterSendTime(stop - totalstart, stop - start);
209:
210: } catch (Exception x) {
211: log.error("Unable to perform replication request.", x);
212: }
213: }
214:
215: /**
216: * Return a String rendering of this object.
217: */
218: public String toString() {
219:
220: StringBuffer sb = new StringBuffer("ReplicationValve[");
221: if (container != null)
222: sb.append(container.getName());
223: sb.append("]");
224: return (sb.toString());
225:
226: }
227:
228: public void setFilter(String filter) {
229: log.debug("Loading request filters=" + filter);
230: java.util.StringTokenizer t = new java.util.StringTokenizer(
231: filter, ";");
232: this .reqFilters = new java.util.regex.Pattern[t.countTokens()];
233: int i = 0;
234: while (t.hasMoreTokens()) {
235: String s = t.nextToken();
236: log.debug("Request filter=" + s);
237: try {
238: reqFilters[i++] = java.util.regex.Pattern.compile(s);
239: } catch (Exception x) {
240: log.error("Unable to compile filter " + s, x);
241: }
242: }
243: }
244:
245: public void setDebug(int debug) {
246: this .debug = debug;
247: }
248:
249: // ------------------------------------------------------ Protected Methods
250:
251: }
|