001: // httpdStatistics.java
002: // $Id: httpdStatistics.java,v 1.10 2003/02/25 17:51:43 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigsaw.http;
007:
008: import java.net.URL;
009:
010: // FIXME
011:
012: import org.w3c.jigsaw.http.socket.SocketClientFactory;
013: import org.w3c.jigsaw.http.socket.SocketClientFactoryStats;
014:
015: /**
016: * This class maintains server wide statistics about hits.
017: * This class should probably be coded as a resource itself, and made
018: * accessible through a specific HTTPResource. I am just having fun
019: * for the time being.
020: */
021:
022: public class httpdStatistics {
023: protected httpd server = null;
024:
025: /**
026: * The min processing time in ms.
027: */
028: protected long r_min = Long.MAX_VALUE;
029: /**
030: * The min processing time in ms for dynamic content
031: */
032: protected long rd_min = Long.MAX_VALUE;
033: /**
034: * The URL that has been processed the fastest.
035: */
036: protected URL u_min = null;
037: /**
038: * The URL that has been processed the fastest for dynamic content
039: */
040: protected URL ud_min = null;
041: /**
042: * The maximum processing time in ms.
043: */
044: protected long r_max = 0;
045: /**
046: * The maximum processing time in ms for dynamic content
047: */
048: protected long rd_max = 0;
049: /**
050: * The URL that has been processed the slowest.
051: */
052: protected URL u_max = null;
053: /**
054: * The URL that has been processed the slowest for dynamic content
055: */
056: protected URL ud_max = null;
057: /**
058: * The total number of hits.
059: */
060: protected long t_hits = 0;
061: /**
062: * The total number of hits for dynamic content
063: */
064: protected long td_hits = 0;
065: /**
066: * The total number of emited bytes.
067: */
068: protected long t_bytes = 0;
069: /**
070: * The total number of emited bytes for dynamic content
071: */
072: protected long td_bytes = 0;
073: /**
074: * The total time spent in processing requests in ms.
075: */
076: protected long t_req = 0;
077: /**
078: * The total time spent in processing requests in ms for dynamic content
079: */
080: protected long td_req = 0;
081: /**
082: * The date at which the server was started (ms since Java epoch).
083: */
084: protected long start_time = 0;
085:
086: // FIXME temporary hack
087: protected SocketClientFactoryStats factoryStats = null;
088: protected boolean init = false;
089:
090: /**
091: * Update the current statistics with the given request.
092: * @param client The client that processed the request.
093: * @param request The request that has been processed.
094: * @param nbytes The number of emited bytes in reply's body.
095: * @param duration The processing time of the request.
096: */
097:
098: protected synchronized void updateStatistics(Client client,
099: Request request, Reply reply, int nbytes, long duration) {
100: if (reply.isDynamic()) {
101: if (duration > rd_max) {
102: rd_max = duration;
103: ud_max = request.getURL();
104: }
105: if (duration < rd_min) {
106: rd_min = duration;
107: ud_min = request.getURL();
108: }
109: td_req += duration;
110: td_bytes += nbytes;
111: td_hits++;
112: } else {
113: if (duration > r_max) {
114: r_max = duration;
115: u_max = request.getURL();
116: }
117: if (duration < r_min) {
118: r_min = duration;
119: u_min = request.getURL();
120: }
121: t_req += duration;
122: t_bytes += nbytes;
123: t_hits++;
124: }
125: }
126:
127: /**
128: * Get the current server load.
129: * @return A number between <strong>1</strong> and <strong>4</strong>.
130: */
131:
132: public int getServerLoad() {
133: if (!init) {
134: initFactoryStats();
135: }
136: if (factoryStats != null) {
137: return factoryStats.getLoadAverage();
138: }
139: // return server.pool.loadavg;
140: return -1;
141: }
142:
143: /**
144: * Get the number of free threads in the server.
145: * @return The number of threads ready to server client requests.
146: */
147:
148: public int getFreeThreadCount() {
149: if (!init) {
150: initFactoryStats();
151: }
152: if (factoryStats != null) {
153: return factoryStats.getFreeConnectionsCount();
154: }
155: // return server.pool.freeCount;
156: return -1;
157: }
158:
159: /**
160: * Get the number of idle threads in the server.
161: * Idle threads are the threads ready to accept more requests on a given
162: * connection.
163: * @return The number of idle threads.
164: */
165:
166: public int getIdleThreadCount() {
167: if (!init) {
168: initFactoryStats();
169: }
170: if (factoryStats != null) {
171: return factoryStats.getIdleConnectionsCount();
172: }
173: // return server.pool.idleCount;
174: return -1;
175: }
176:
177: /**
178: * Get the total number of client threads.
179: * @return The total number of created threads.
180: */
181:
182: public int getTotalThreadCount() {
183: if (!init) {
184: initFactoryStats();
185: }
186: if (factoryStats != null) {
187: return factoryStats.getClientCount();
188: }
189: // return server.pool.clientCount;
190: return -1;
191: }
192:
193: /**
194: * Get the total number of hits.
195: * @return The total number of processed requests since the server is up.
196: */
197:
198: public long getHitCount() {
199: return (t_hits + td_hits);
200: }
201:
202: /**
203: * Get the total number of hits for dynamic content.
204: * @return The total number of processed requests since the server is up.
205: */
206:
207: public long getDynamicHitCount() {
208: return td_hits;
209: }
210:
211: /**
212: * Get the total number of hits for static content.
213: * @return The total number of processed requests since the server is up.
214: */
215:
216: public long getStaticHitCount() {
217: return t_hits;
218: }
219:
220: /**
221: * Get the mean request processing time.
222: * @return The average time to process a request.
223: */
224:
225: public long getMeanRequestTime() {
226: return ((t_hits + td_hits) > 0) ? (t_req + td_req)
227: / (t_hits + td_hits) : -1;
228: }
229:
230: /**
231: * Get the mean request processing time for dynamic content
232: * @return The average time to process a request.
233: */
234:
235: public long getMeanDynamicRequestTime() {
236: return (td_hits > 0) ? (td_req / td_hits) : -1;
237: }
238:
239: /**
240: * Get the mean request processing time.
241: * @return The average time to process a request.
242: */
243:
244: public long getMeanStaticRequestTime() {
245: return (t_hits > 0) ? (t_req / t_hits) : -1;
246: }
247:
248: /**
249: * Get the max request processing time.
250: * @return A long giving the maximum duration for a request.
251: */
252:
253: public long getMaxRequestTime() {
254: return Math.max(r_max, rd_max);
255: }
256:
257: /**
258: * Get the max request processing time for dynamic content
259: * @return A long giving the maximum duration for a request.
260: */
261:
262: public long getMaxDynamicRequestTime() {
263: return rd_max;
264: }
265:
266: /**
267: * Get the max request processing time for static content
268: * @return A long giving the maximum duration for a request.
269: */
270:
271: public long getMaxStaticRequestTime() {
272: return r_max;
273: }
274:
275: /**
276: * Get the URL of the request that took the longest time to be processed.
277: * @return A String giving the URL of the corresponding request, or
278: * <strong>null</strong> if no request has been processed yet.
279: */
280:
281: public URL getMaxRequestURL() {
282: return (r_max > rd_max) ? u_max : ud_max;
283: }
284:
285: /**
286: * Get the min request processing time.
287: * @return A long giving the minimum request processing time.
288: */
289:
290: public long getMinRequestTime() {
291: return Math.min(r_min, rd_min);
292: }
293:
294: /**
295: * Get the min request processing time for dynamic content
296: * @return A long giving the minimum request processing time.
297: */
298:
299: public long getMinDynamicRequestTime() {
300: return rd_min;
301: }
302:
303: /**
304: * Get the min request processing time.
305: * @return A long giving the minimum request processing time.
306: */
307:
308: public long getMinStaticRequestTime() {
309: return r_min;
310: }
311:
312: /**
313: * Get the URL of the request that took the smallest time to be processed.
314: * @return A String giving the URL of the corresponding request, or
315: * <strong>null</strong> if no request has been processed yet.
316: */
317:
318: public URL getMinRequestURL() {
319: return (r_min < rd_min) ? u_min : ud_min;
320: }
321:
322: /**
323: * Get the total number of bytes emited.
324: * @return A long giving the total number of bytes emited by the server.
325: * This count that not include the reply's header, but only the reply's
326: * body (or <em>entity</em> size).
327: */
328:
329: public long getEmittedBytes() {
330: return t_bytes + td_bytes;
331: }
332:
333: /**
334: * Get the time at which the server was started.
335: * @return A number of milliseconds since java epoch, giving the date
336: * at which the server started.
337: */
338:
339: public long getStartTime() {
340: return start_time;
341: }
342:
343: /**
344: * As we can't start the after the server socket (client factory)
345: * we have to create when requested, which is always after the creation
346: * of the whole server..
347: */
348: private void initFactoryStats() {
349: if (server.factory instanceof SocketClientFactory) {
350: SocketClientFactory f = (SocketClientFactory) server.factory;
351: factoryStats = new SocketClientFactoryStats(f);
352: }
353: init = true;
354: }
355:
356: httpdStatistics(httpd server) {
357: this.server = server;
358: this.start_time = System.currentTimeMillis();
359: }
360:
361: }
|