KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > server > logging > stats > ErrorStatistics


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * ErrorStatistics.java
26  * $Id: ErrorStatistics.java,v 1.10 2006/03/08 00:30:19 kx125475 Exp $
27  * $Date: 2006/03/08 00:30:19 $
28  * $Revision: 1.10 $
29  */

30
31 package com.sun.enterprise.server.logging.stats;
32
33 import java.util.Map JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.ArrayList JavaDoc;
37 import java.util.logging.Level JavaDoc;
38 import java.util.logging.Logger JavaDoc;
39 import java.util.logging.LogRecord JavaDoc;
40
41 import com.sun.logging.LogDomains;
42 import com.sun.appserv.management.ext.logging.LogAnalyzer;
43
44 /**
45  * This keeps track of the error statistics (log levels SEVERE and WARNING).
46  *
47  * @author Ram Jeyaraman
48  */

49 public class ErrorStatistics {
50     
51     // Static constants, classes and methods
52

53     private static final int MIN_INTERVALS = 5;
54     private static final int MAX_INTERVALS = 500;
55     private static final long DEFAULT_INTERVAL = 3600*1000; // (1 hour) msecs
56

57     private static final ErrorStatistics singleton = new ErrorStatistics();
58     
59     public static ErrorStatistics singleton() {
60         return singleton;
61     }
62     
63     public static void registerStartupTime() {
64         singleton(); // Loads the class which sets up the startup time.
65
}
66     
67     private static class ErrorCount {
68         
69         private int severeCount;
70         private int warningCount;
71         
72         void setSevereCount(int count) {
73             this.severeCount = count;
74         }
75         
76         int getSevereCount() {
77             return this.severeCount;
78         }
79         
80         void setWarningCount(int count) {
81             this.warningCount = count;
82         }
83         
84         int getWarningCount() {
85             return this.warningCount;
86         }
87     }
88     
89     // Instance variables and methods
90

91     private long interval;
92     private int numOfIntervals;
93     private long startTimeStamp;
94     private HashMap JavaDoc<Long JavaDoc,HashMap JavaDoc<String JavaDoc,ErrorCount>> intervalMap;
95     
96     ErrorStatistics() {
97         interval = DEFAULT_INTERVAL;
98         numOfIntervals = MIN_INTERVALS;
99         intervalMap = new HashMap JavaDoc<Long JavaDoc,HashMap JavaDoc<String JavaDoc,ErrorCount>>();
100         startTimeStamp = System.currentTimeMillis();
101     }
102
103     /**
104      * Get the number of intevals, for which error statistics is maintained.
105      *
106      * @return number of intervals.
107      */

108     public int getNumOfIntervals() {
109         return numOfIntervals;
110     }
111     
112     /**
113      * Set the number of time intervals, for which statistics will be
114      * maintained in memory. For example, if the interval is 1 hour, and
115      * number of intervals is 10, statistics will be maintained for the most
116      * recent 10 hours.
117      */

118     public void setNumOfIntervals(int intervals) {
119         if ((intervals < MIN_INTERVALS) || (intervals > MAX_INTERVALS)) {
120             throw new IllegalArgumentException JavaDoc(
121                     "Number of intervals must be between " + MIN_INTERVALS +
122                     " and " + MAX_INTERVALS);
123         }
124         numOfIntervals = intervals;
125     }
126     
127     /**
128      * Set interval duration. The interval is the duration, in milli seconds,
129      * between consecutive time samples. For example, if the interval is 1 hour,
130      * statistical data collected over time, will be organized by the hour.
131      */

132     public void setIntervalDuration(long interval) {
133         this.interval = interval;
134     }
135     
136     /**
137      * Get the interval duration.
138      *
139      * @return interval duration, in millsecs.
140      */

141     public long getIntervalDuration() {
142         return this.interval;
143     }
144     
145     /**
146      * This method is not synchronized. The caller must ensure that
147      * this method is not used in a concurrent fashion. Currently,
148      * the only caller is publish() method of FileandSyslogHandler.
149      */

150     public void updateStatistics(LogRecord JavaDoc record) {
151         
152         // Get information from log record.
153

154         long logTimeStamp = record.getMillis();
155         String JavaDoc logModuleId = record.getLoggerName();
156         if (logModuleId == null) {
157             Logger JavaDoc logger = LogDomains.getLogger(LogDomains.CORE_LOGGER);
158             logger.log(
159                     Level.WARNING, "Update error statistics failed",
160                     (new Throwable JavaDoc("Logger name is null.")).fillInStackTrace());
161             return;
162         }
163         Level JavaDoc logLevel = record.getLevel();
164         
165         // Sanity check.
166
/*
167         boolean isAnErrorRecord =
168             logLevel.equals(Level.SEVERE) || logLevel.equals(Level.WARNING);
169         if (!isAnErrorRecord) {
170             return; // no op.
171         }
172         */

173         // Calculate the timestamp bucket for the log record.
174

175         long hoursElapsed = (logTimeStamp-startTimeStamp)/interval;
176         long timeStamp = startTimeStamp + hoursElapsed*interval;
177         /*
178         System.out.println((new java.text.SimpleDateFormat("HH:mm:ss")).
179                                 format(new java.util.Date(timeStamp)));
180         */

181         
182         // Update the error statistics.
183

184         HashMap JavaDoc<String JavaDoc,ErrorCount> moduleMap = intervalMap.get(timeStamp);
185         if (moduleMap == null) {
186             moduleMap = new HashMap JavaDoc<String JavaDoc,ErrorCount>();
187             trimHourMap(timeStamp); // removes stale entries
188
intervalMap.put(Long.valueOf(timeStamp), moduleMap);
189         }
190         
191         ErrorCount errorCount = moduleMap.get(logModuleId);
192         if (errorCount == null) {
193             errorCount = new ErrorCount();
194             moduleMap.put(logModuleId, errorCount);
195         }
196
197         if (logLevel.equals(Level.SEVERE)) {
198             errorCount.setSevereCount(errorCount.getSevereCount()+1);
199         } else { // Level == WARNING
200
errorCount.setWarningCount(errorCount.getWarningCount()+1);
201         }
202     }
203     
204     private void trimHourMap(long refTimeStamp) {
205         Long JavaDoc[] timeStamps = intervalMap.keySet().toArray(new Long JavaDoc[0]);
206         for (int i = 0; i < timeStamps.length; i++) {
207             long timeStamp = timeStamps[i];
208             if ((refTimeStamp-timeStamp) >= interval*numOfIntervals) {
209                 intervalMap.remove(timeStamp);
210             }
211         }
212     }
213     
214     // Methods for Log MBean.
215

216     /**
217      * @return a list of Map objects. Each map object contains
218      * the tuple [TimeStamp, SevereCount, WarningCount].
219      */

220     public List JavaDoc<Map JavaDoc<String JavaDoc,Object JavaDoc>> getErrorInformation() {
221         
222         // Calculate the most recent timestamp bucket.
223

224         long intervalsElapsed =
225                 (System.currentTimeMillis()-startTimeStamp)/interval;
226         long recentTimeStamp = startTimeStamp + (intervalsElapsed*interval);
227         
228         // Gather the information for the past numOfIntervals.
229

230         List JavaDoc<Map JavaDoc<String JavaDoc,Object JavaDoc>> results =
231                 new ArrayList JavaDoc<Map JavaDoc<String JavaDoc,Object JavaDoc>>();
232         for (int i = 0; i < numOfIntervals; i++) {
233             long timeStamp = recentTimeStamp - interval*i;
234             HashMap JavaDoc<String JavaDoc,ErrorCount> moduleMap = intervalMap.get(timeStamp);
235             int severeCount = 0, warningCount = 0;
236             if (timeStamp<startTimeStamp) {
237                 severeCount = -1;
238                 warningCount = -1;
239             }
240             if (moduleMap != null) {
241                 for (ErrorCount error : moduleMap.values()) {
242                     severeCount += error.getSevereCount();
243                     warningCount += error.getWarningCount();
244                 }
245             }
246             HashMap JavaDoc<String JavaDoc,Object JavaDoc> entry = new HashMap JavaDoc<String JavaDoc,Object JavaDoc>();
247             entry.put(LogAnalyzer.TIMESTAMP_KEY, timeStamp);
248             entry.put(LogAnalyzer.SEVERE_COUNT_KEY, severeCount);
249             entry.put(LogAnalyzer.WARNING_COUNT_KEY, warningCount);
250             results.add(entry);
251         }
252         
253         return results;
254     }
255        
256     /**
257      * @return a map. The key is module id (String) and the value is
258      * error count (Integer) for the specific module.
259      */

260     public Map JavaDoc<String JavaDoc,Integer JavaDoc> getErrorDistribution(
261             long timeStamp, Level JavaDoc level) {
262                 
263         // Sanity check.
264

265         if (!(level.equals(Level.SEVERE) || level.equals(Level.WARNING))) {
266             throw new IllegalArgumentException JavaDoc("Log level: " + level);
267         }
268         
269         // Gather the information.
270

271         HashMap JavaDoc<String JavaDoc,ErrorCount> moduleMap = intervalMap.get(timeStamp);
272         if (moduleMap == null) {
273             return null;
274         }
275         
276         Map JavaDoc<String JavaDoc,Integer JavaDoc> results = new HashMap JavaDoc<String JavaDoc,Integer JavaDoc>();
277         for (String JavaDoc moduleId : moduleMap.keySet()) {
278             ErrorCount errorCount = moduleMap.get(moduleId);
279             if (level.equals(Level.SEVERE)) {
280                 results.put(moduleId, errorCount.getSevereCount());
281             } else { // Level == WARNING
282
results.put(moduleId, errorCount.getWarningCount());
283             }
284         }
285         
286         return results;
287     }
288     
289     // Unit test
290

291     public static void main(String JavaDoc[] args) {
292
293         // Create log records
294

295         LogRecord JavaDoc srecord = new LogRecord JavaDoc(Level.SEVERE, "severe record");
296         srecord.setMillis(System.currentTimeMillis());
297         srecord.setLoggerName("com.wombat.smodule");
298         
299         LogRecord JavaDoc wrecord = new LogRecord JavaDoc(Level.WARNING, "warning record");
300         wrecord.setMillis(System.currentTimeMillis());
301         wrecord.setLoggerName("com.wombat.wmodule");
302         
303         // Update error statistics
304

305         java.text.SimpleDateFormat JavaDoc sdf =
306                 new java.text.SimpleDateFormat JavaDoc("HH:mm:ss");
307         
308         ErrorStatistics stats = new ErrorStatistics();
309         long interval = 1000; // 1 second.
310
stats.setIntervalDuration(interval);
311         for (int i = 0; i < 10; i++) {
312             try {
313                 Thread.sleep(interval);
314             } catch (InterruptedException JavaDoc e) {}
315             for (int j = 0; j < 2; j++) {
316                 srecord.setMillis(System.currentTimeMillis());
317                 stats.updateStatistics(srecord);
318                 wrecord.setMillis(System.currentTimeMillis());
319                 stats.updateStatistics(wrecord);
320             }
321             System.out.printf("Interval(%1$s): %2$s\n", i,
322                 sdf.format(new java.util.Date JavaDoc(System.currentTimeMillis())));
323         }
324         
325         // Query error statistics
326

327         System.out.println("\nTimeStamp\tSevere\tWarning");
328         System.out.println("--------------------------------");
329         List JavaDoc<Map JavaDoc<String JavaDoc,Object JavaDoc>> list = stats.getErrorInformation();
330         for (Map JavaDoc<String JavaDoc,Object JavaDoc> item : list) {
331             long timeStamp = (Long JavaDoc) item.get(LogAnalyzer.TIMESTAMP_KEY);
332             int severeCount = (Integer JavaDoc) item.get(LogAnalyzer.SEVERE_COUNT_KEY);
333             int warningCount =
334                     (Integer JavaDoc) item.get(LogAnalyzer.WARNING_COUNT_KEY);
335             System.out.printf("%1$s\t%2$s\t%3$s\n",
336                               sdf.format(new java.util.Date JavaDoc(timeStamp)),
337                               severeCount, warningCount);
338         }
339         
340         for (Map JavaDoc<String JavaDoc,Object JavaDoc> item : list) {
341             long timeStamp = (Long JavaDoc) item.get(LogAnalyzer.TIMESTAMP_KEY);
342             Map JavaDoc<String JavaDoc,Integer JavaDoc> map =
343                     stats.getErrorDistribution(timeStamp, Level.SEVERE);
344             System.out.printf("\nModuleId\tLevel.SEVERE\t(%1$s)\n",
345                               sdf.format(new java.util.Date JavaDoc(timeStamp)));
346             System.out.println("------------------------------------------");
347             for (String JavaDoc moduleId : map.keySet()) {
348                 System.out.printf("%1$s\t%2$s\n", moduleId, map.get(moduleId));
349             }
350             map = stats.getErrorDistribution(timeStamp, Level.WARNING);
351             System.out.printf("\nModuleId\tLevel.WARNING\t(%1$s)\n",
352                               sdf.format(new java.util.Date JavaDoc(timeStamp)));
353             System.out.println("------------------------------------------");
354             for (String JavaDoc moduleId : map.keySet()) {
355                 System.out.printf("%1$s\t%2$s\n", moduleId, map.get(moduleId));
356             }
357         }
358     }
359 }
360
Popular Tags