001: package com.jamonapi.http;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.Iterator;
006:
007: /**
008: *
009: * ?test - use ms. units for otehr methods like response.getStatus().value.ms
010: * webapp
011: - documentation adn sample xml
012: - check resultsetconverter to work with new bufferlistener
013: * - comment any method that returns an Object and takes no args can be passed.
014:
015: */
016:
017: /** Base class that monitors a httpServletRequest, and HttpServletResponse by returning an HttpMonRequest object per page request. Although this
018: * class can be used directly it will more often be used transparently by classes such as JAMonTomcat55Valve, JAMonServletFilter and JAMonJettyHandler.
019: * To get a list of many possible (though not all) HttpServletRequest and HttpServletResponse labels pass 'demo' to the valve, handler or servlet filter.
020: * You can also see these same possibiliteis by calling HttpMonFactory.getDemoLabels(). Note jetty and tomcat handler and valve respectively
021: * are based on objects that inherit from HttpServletRequest and HttpServletResponse respectively and all methods that these subclasses
022: * implement are available too.
023: *
024: * <br> representative values returned from response methods
025: * <br> response.getBufferSize()=8192
026: <br> response.getCharacterEncoding()=utf-8
027: <br> response.getContentCount()=985
028: <br> response.getContentType()=text/html;charset=utf-8
029: <br> response.getLocale()=en_US
030:
031: <br><br>representative values returned from request methods
032: <br> request.getAuthType()=null
033: <br> request.getCharacterEncoding()=null
034: <br> request.getContentLength()=-1
035: <br> request.getCharacterEncoding()=null
036: <br> request.getContentType()=null
037: <br> request.getContextPath()=/jamon
038: <br> request.getLocalAddr()=127.0.0.1
039: <br> request.getLocale()=en_US
040: <br> request.getLocalName()=localhost
041: <br> request.getLocalPort()=8080
042: <br> request.getMethod()=GET
043: <br> request.getPathInfo()=null
044: <br> request.getPathTranslated()=null
045: <br> request.getProtocol()=HTTP/1.1
046: <br> request.getQueryString()=name=steve%20souza&id=9898
047: <br> request.getRemoteAddr()=127.0.0.1
048: <br> request.getRemoteHost()=127.0.0.1
049: <br> request.getRemotePort()=1454
050: <br> request.getRemoteUser()=null
051: <br> request.getRequestedSessionId()=670BFE2B4A7C7C77D9825EFA753D2058
052: <br> request.getRequestURI()=/jamon/ZZZZ
053: <br> request.getRequestURL()=http://localhost:8080/jamon/ZZZZ
054: <br> request.getScheme()=http
055: <br> request.getServerName()=localhost
056: <br> request.getServerPort()=8080
057: <br> request.getServletPath()=/ZZZZ
058: <br> request.getUserPrincipal()=null
059: <br> request.isRequestedSessionIdFromCookie()=true
060: <br> request.isRequestedSessionIdFromURL()=false
061: <br> request.isRequestedSessionIdValid()=false
062: <br> request.isSecure()=false
063:
064: *
065: * @author steve souza
066: */
067: public class HttpMonFactory implements HttpMonManage {
068:
069: private static final String DEFAULT_SUMMARY = "request.getRequestURI().ms as allPages, request.getRequestURI().value.ms as page";
070: private String jamonSummaryLabels = "default";// will do the above monitors if the word default is used in this variable.
071: private Collection httpMonItemsHolder = new ArrayList();// Holds HttpMonItems
072: private boolean ignoreHttpParams = true;// ignore http params if getRequestURI, or getRequestURL are called. This done to primarily to prevent
073: // jsessionid from becoming part of a jamon label. By default params are removed (i.e. true)
074: private String labelPrefix; // prefix used for jamon labels
075: private boolean enabled = true; //Enable/Disable httpMonitoring. By default it is on
076: private int numTimeMons = 0;// The Number of monitors that are time based ones.
077: // The size value will not allow any more http stats to be put into jamon if the total number of jamon entries exceeds 5000 entries.
078: // This value may be changed to anything. Note jamon entries can still be added via standard jamon calls (might want to add this feature
079: // there too). This is to prevent a buffer overflow should someone keep submitting invalid pages when a record is created for each page.
080: private int size = 5000;
081: private static final HttpMon NULL_HTTP_MON = new HttpMonNull();// used when monitoring is disabled.
082:
083: /** Create an HttpMonFactory by passing in text that occurs at the beginning of all jamon labels. ex com.jamonapi.http.JAMonTomcatValve */
084: public HttpMonFactory(String labelPrefix) {
085: this .labelPrefix = labelPrefix;
086: }
087:
088: /** Pass a series of things (HttpServletRequest/HttpServletResponse methods) to monitor. If the word 'default' is passed then the default
089: * values will be used. If 'demo' is passed you will see a list of possibilities (This should not be done in production as too much data would be
090: * generated). You can add to the default by doing passing "default, request.getStatus().httpStatus". Each time this method is called any previously
091: * set items that were being monitored will not longer be monitored. See http://www.jamonapi.com for more examples.
092: */
093: public void setSummaryLabels(String jamonSummaryLabels) {
094: this .jamonSummaryLabels = "";
095: this .httpMonItemsHolder = new ArrayList();
096: this .numTimeMons = 0;
097:
098: if (jamonSummaryLabels == null)
099: return;
100:
101: // replace the word 'demo' with a good sampling of possibilities
102: jamonSummaryLabels = jamonSummaryLabels.replaceAll("(?i)demo",
103: getDemoLabels());
104:
105: // replace string 'default' with the actual default values
106: jamonSummaryLabels = replaceDefault(jamonSummaryLabels,
107: DEFAULT_SUMMARY);
108:
109: // tokenize the string and add each of the HttpMonItems
110: String[] summaryLabelsArr = split(jamonSummaryLabels);
111: for (int i = 0; i < summaryLabelsArr.length; i++) {
112: addSummaryLabel(summaryLabelsArr[i]);
113: }
114:
115: }
116:
117: public static String getDemoLabels() {
118:
119: String demoStr = "";
120:
121: // response methods
122: demoStr += getDemoLabel("response.getBufferSize()", "bytes");
123: demoStr += getDemoLabel("response.getCharacterEncoding()",
124: "charEncoding");
125: demoStr += getDemoLabel("response.getContentCount()", "bytes");
126: demoStr += getDemoLabel("response.getContentType()",
127: "contentType");
128: demoStr += getDemoLabel("response.getLocale()", "locale");
129: demoStr += getDemoLabel("request.getAuthType()", "authType");
130:
131: demoStr += getDemoLabel("request.getCharacterEncoding()",
132: "charEncoding");
133: demoStr += getDemoLabel("request.getContentLength()", "bytes");
134: demoStr += getDemoLabel("request.getContentType()",
135: "contentType");
136: demoStr += getDemoLabel("request.getContextPath()", "path");
137: demoStr += "request.getContextPath().value.ms, ";
138: demoStr += getDemoLabel("request.getLocalAddr()", "ip");
139: demoStr += getDemoLabel("request.getLocale()", "locale");
140: demoStr += getDemoLabel("request.getLocalName()", "localName");
141: demoStr += getDemoLabel("request.getLocalPort()", "port");
142: demoStr += getDemoLabel("request.getMethod()", "httpMethod");
143: demoStr += getDemoLabel("request.getPathInfo()", "path");
144: demoStr += getDemoLabel("request.getPathTranslated()", "path");
145: demoStr += getDemoLabel("request.getProtocol()", "protocol");
146: demoStr += getDemoLabel("request.getQueryString()", "queryStr");
147: demoStr += getDemoLabel("request.getRemoteAddr()", "ip");
148: demoStr += getDemoLabel("request.getRemoteHost()", "ip");
149: demoStr += getDemoLabel("request.getRemotePort()", "port");
150: demoStr += getDemoLabel("request.getRemoteUser()", "user");
151: demoStr += getDemoLabel("request.getRequestedSessionId()",
152: "sessionid");
153: demoStr += getDemoLabel("request.getRequestURI()", "ms");
154: demoStr += getDemoLabel("request.getRequestURL()", "ms");
155: demoStr += getDemoLabel("request.getScheme()", "scheme");
156: demoStr += getDemoLabel("request.getServerName()", "serverName");
157: demoStr += getDemoLabel("request.getServerPort()", "port");
158: demoStr += getDemoLabel("request.getServletPath()", "path");
159: demoStr += getDemoLabel("request.getUserPrincipal()", "user");
160: demoStr += getDemoLabel(
161: "request.isRequestedSessionIdFromCookie()",
162: "sessionCookie");
163: demoStr += getDemoLabel("request.isRequestedSessionIdValid()",
164: "sessionValid");
165: demoStr += getDemoLabel("request.isSecure()", "secure");
166: demoStr += "request.getScheme().ms as schemeAlias";
167:
168: return demoStr;
169:
170: }
171:
172: private static String getDemoLabel(String label, String units) {
173: String str = label + "." + units;// response.getBufferSize().bytes
174: str += ", " + label + ".value." + units;
175: str += ", " + label + ".contextpath.value." + units;
176: str += ", " + label + ".value.contextpath." + units;
177: str += ", " + label + ".value.url." + units + ",";
178: return str;
179:
180: }
181:
182: // if passed summaryLabel has 'default' in it replace it with defaultString and then
183: // call this classes setSummaryLabels method. This allows each implementing class to have
184: // different defaults.
185: public void setSummaryLabels(String summaryLabel,
186: String defaultString) {
187: summaryLabel = replaceDefault(summaryLabel, defaultString);
188: setSummaryLabels(summaryLabel);
189: }
190:
191: // replace case insensitive 'default' string with passed in string.
192: static String replaceDefault(String summaryLabel,
193: String defaultString) {
194: return summaryLabel.replaceAll("(?i)default", defaultString);
195: }
196:
197: /** Pass a String that has an HttpServletRequest/HttpServletResponse method such as response.getStatus() and then this class
198: * will monitor that method call.
199: */
200: public void addSummaryLabel(String jamonSummaryLabel) {
201: if (httpMonItemsHolder != null) {
202: HttpMonItem monItem = createHttpMonItem(jamonSummaryLabel
203: .trim());
204: httpMonItemsHolder.add(monItem);
205: // concatenate each individual summary label to build a bigger string. i.e response.getStatus(), request.getRequestURI()
206: // Put a comma before every label added but the first.
207: if (!"".equals(jamonSummaryLabels)) {
208: jamonSummaryLabels += ", ";
209: }
210:
211: jamonSummaryLabels += jamonSummaryLabel;
212: if (monItem.isTimeMon())// track how many time monitors there are
213: numTimeMons++;
214: }
215: }
216:
217: // Return the number of HttpMonItems that are being monitored for each request
218: int getNumRows() {
219: return httpMonItemsHolder.size();
220: }
221:
222: // return the number of time monitors (ms.)
223: int getNumTimeMons() {
224: return numTimeMons;
225: }
226:
227: // allow iteration of HttpMonItems. Used to start/stop all monitors.
228: Iterator iter() {
229: return httpMonItemsHolder.iterator();
230: }
231:
232: /** Get the passed in summaryLabels. */
233: public String getSummaryLabels() {
234: return jamonSummaryLabels;
235: }
236:
237: /** Determine if http params are ignored when creating a jamon label for request.getRequestURI(), and request.getRequestURL(). This is important
238: * for jsessionid can make every label passed to jamon nonunique if not enabled. By default this value is true (ignore params).
239: */
240: public boolean getIgnoreHttpParams() {
241: return ignoreHttpParams;
242: }
243:
244: /** Set if http params are ignored when creating a jamon label for request.getRequestURI(), and request.getRequestURL(). This is important
245: * for jsessionid can make every label passed to jamon nonunique if not enabled. By default this value is true (ignore params).
246: */
247: public void setIgnoreHttpParams(boolean ignoreHttpParams) {
248: this .ignoreHttpParams = ignoreHttpParams;
249:
250: }
251:
252: /** Enable/disable http monitoring */
253: public void setEnabled(boolean enable) {
254: this .enabled = enable;
255:
256: }
257:
258: /** Determin if http monitoring is enabled */
259: public boolean getEnabled() {
260: return enabled;
261: }
262:
263: /** Get the max number of possible HttpMonitors. By default this is 5000 */
264: public int getSize() {
265: return size;
266: }
267:
268: /** Set the max number of possible HttpMonitors. By default this is 5000. A value <=0 means there is no limit on the number
269: * of jamon records that can be creating due to monitoring. */
270: public void setSize(int size) {
271: this .size = size;
272: }
273:
274: public String getLabelPrefix() {
275: return labelPrefix;
276: }
277:
278: private String[] split(String str) {
279: return (str == null) ? null : str.split(",");
280: }
281:
282: /* Note request will probably implement HttpServletRequest and response HttpServletResponse though this is not strictly required. This method is
283: * called to monitor the request. usually via another class like the jamon tomcat valve.
284: *
285: */
286:
287: public HttpMon getMon(Object request, Object response) {
288: if (!enabled || jamonSummaryLabels == null)
289: return NULL_HTTP_MON;
290: else
291: return new HttpMonRequest(request, response, this );
292:
293: }
294:
295: /* Method called to start monitoring a request.
296: *
297: */
298:
299: public HttpMon start(Object request, Object response) {
300: return getMon(request, response).start();
301: }
302:
303: /* can be overridden in this package to create a different type of httpMonItem (jetty classes do this). If it is required in the future
304: * access could change to protected for this method.
305: */
306: HttpMonItem createHttpMonItem(String label) {
307: return new HttpMonItem(label, this );
308:
309: }
310:
311: /** Simple test code */
312: public static void main(String[] argas) {
313: String str = "hello world, dEfault, request.getRequestURI()";
314: System.out.println(str.replaceAll("(?i)default",
315: "steven, thomas, souza"));
316: String[] strArr = str.split("(?i)default *,");
317: for (int i = 0; i < strArr.length; i++)
318: System.out.println(strArr[i]);
319:
320: System.out.println(getDemoLabels());
321:
322: }
323:
324: }
|