001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: // Copyright (C) 1999 - 2002, Salmon LLC
004: //
005: // This program is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU General Public License version 2
007: // as published by the Free Software Foundation;
008: //
009: // This program is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: // GNU General Public License for more details.
013: //
014: // You should have received a copy of the GNU General Public License
015: // along with this program; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: // For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020: package com.salmonllc.scheduler;
021:
022: /////////////////////////
023: //$Archive: /JADE/SourceCode/com/salmonllc/scheduler/PerformanceLogger.java $
024: //$Author: Dan $
025: //$Revision: 5 $
026: //$Modtime: 10/30/02 2:38p $
027: /////////////////////////
028:
029: import java.util.*;
030: import java.io.*;
031: import com.salmonllc.jsp.*;
032: import com.salmonllc.util.*;
033: import com.salmonllc.properties.*;
034:
035: /**
036: * This scheduled object is used to log performance metrics on the server to a log file.
037: */
038: public class PerformanceLogger implements ScheduledObject {
039:
040: static int _lastPageHits = 0;
041: static long _lastHitTime = 0;
042: static long _lastFreeMemory = 0;
043: static long _lastTotalMemory = 0;
044: static long _lastRunTime = 0;
045:
046: private String formatDuration(long duration) {
047: java.text.DecimalFormat df = new java.text.DecimalFormat("00");
048: long sec = duration / 1000;
049: long min = sec / 60;
050: long hours = min / 60;
051: min = min - (hours * 60);
052: sec = sec - ((hours * 3600) + (min * 60));
053: StringBuffer ret = new StringBuffer();
054:
055: if (hours > 0) {
056: ret.append(df.format(hours));
057: ret.append(":");
058: }
059:
060: ret.append(df.format(min));
061: ret.append(":");
062: ret.append(df.format(sec));
063:
064: return ret.toString();
065: }
066:
067: public void scheduleReached(ScheduleReachedEvent e) {
068:
069: try {
070: Props p = Props.getSystemProps();
071: String logFile = p.getProperty("PerformanceLogFile");
072: if (logFile == null) {
073: MessageLog
074: .writeInfoMessage(
075: "Could not find property \"PerformanceLogFile\" in system.properties file.",
076: this );
077: return;
078: } else {
079: MessageLog.writeInfoMessage(
080: "Logging performance metrics to " + logFile,
081: this );
082: }
083:
084: long now = System.currentTimeMillis();
085: long serverRunTime = now - JspServlet.getFirstPageHitTime();
086: int pageHits = JspServlet.getPageHits();
087: long hitTime = JspServlet.getTotalHitTime();
088: long freeMemory = Runtime.getRuntime().freeMemory();
089: long totalMemory = Runtime.getRuntime().totalMemory();
090:
091: double avgHits = 0;
092: if (serverRunTime > 0)
093: avgHits = (((pageHits * 1.0) / serverRunTime));
094:
095: double avgResponseTime = 0;
096: if (pageHits > 0)
097: avgResponseTime = ((hitTime * 1.0) / pageHits);
098:
099: int pageHitsDelta = 0;
100: long hitTimeDelta = 0;
101: long freeMemoryDelta = 0;
102: long totalMemoryDelta = 0;
103: long serverRunTimeDelta = 0;
104: double avgHitsPeriod = 0;
105: double avgResponseTimePeriod = 0;
106:
107: if (_lastHitTime > 0) {
108: pageHitsDelta = pageHits - _lastPageHits;
109: hitTimeDelta = hitTime - _lastHitTime;
110: freeMemoryDelta = freeMemory - _lastFreeMemory;
111: totalMemoryDelta = totalMemory - _lastTotalMemory;
112: serverRunTimeDelta = now - _lastRunTime;
113: avgHitsPeriod = (((pageHitsDelta * 1.0) / serverRunTimeDelta));
114: if (pageHitsDelta > 0)
115: avgResponseTimePeriod = ((hitTimeDelta * 1.0) / pageHitsDelta);
116: else
117: avgResponseTimePeriod = 0;
118: }
119:
120: _lastFreeMemory = freeMemory;
121: _lastHitTime = hitTime;
122: _lastPageHits = pageHits;
123: _lastRunTime = now;
124: _lastTotalMemory = totalMemory;
125:
126: File f = new File(logFile);
127: FileOutputStream out = null;
128: boolean printHeadings = false;
129: if (f.exists())
130: out = new FileOutputStream(logFile, true);
131: else {
132: out = new FileOutputStream(f);
133: printHeadings = true;
134: }
135:
136: java.text.DecimalFormat df = new java.text.DecimalFormat(
137: "########0.00000");
138: java.text.SimpleDateFormat dtf = new java.text.SimpleDateFormat(
139: "MM/dd/yyyy hh:mm a");
140: PrintWriter pw = new PrintWriter(
141: new OutputStreamWriter(out));
142:
143: if (printHeadings)
144: pw
145: .println("Time\tServer Run Time (sec)\tTotal Page Hits\tTotal Page Hit Time(Seconds)\tFree Memory (kbs)\tTotal Memory (kbs)\tAverage Hits Per Second\tAverage Response Time (seconds)\tPeriod Length (hrs:min:sec)\tPage Hit For Period\tTotal Page Hits Time for Period (seconds)\tFree Memory Delta (kbs)\tTotal Memory Delta (kbs)\tAverage Hits Per Second For Period\tAverage Response Time For Period (seconds)");
146:
147: //Time
148: Date d = new Date(now);
149: pw.print(dtf.format(d));
150: pw.print('\t');
151:
152: //Server run time
153:
154: pw.print(new Long(serverRunTime / 1000));
155: pw.print('\t');
156:
157: //Page Hits
158: Integer i = new Integer(pageHits);
159: pw.print(i.toString());
160: pw.print('\t');
161:
162: //Page Hit Time
163: pw.print(df.format(hitTime / 1000D));
164: pw.print('\t');
165:
166: //Free Memory
167: Long l = new Long(freeMemory / 1000);
168: pw.print(l.toString());
169: pw.print('\t');
170:
171: //Total Memory
172: l = new Long(totalMemory / 1000);
173: pw.print(l.toString());
174: pw.print('\t');
175:
176: //Avg Hits per second
177: pw.print(df.format(avgHits * 1000));
178: pw.print('\t');
179:
180: //Avg Response time
181: pw.print(df.format(avgResponseTime / 1000D));
182: pw.print('\t');
183:
184: //Period Length
185: pw.print(formatDuration(serverRunTimeDelta));
186: pw.print('\t');
187:
188: //Page Hits Delta
189: i = new Integer(pageHitsDelta);
190: pw.print(i.toString());
191: pw.print('\t');
192:
193: //Page Hit Time Delta
194: pw.print(df.format(hitTimeDelta / 1000D));
195: pw.print('\t');
196:
197: //Free Memory Delta
198: l = new Long(freeMemoryDelta / 1000);
199: pw.print(l.toString());
200: pw.print('\t');
201:
202: //Total Memory Delta
203: l = new Long(totalMemoryDelta / 1000);
204: pw.print(l.toString());
205: pw.print('\t');
206:
207: //Avg Hits per second for period
208: pw.print(df.format(avgHitsPeriod * 1000));
209: pw.print('\t');
210:
211: //Avg Response time for period
212: pw.print(df.format(avgResponseTimePeriod / 1000D));
213: pw.print('\t');
214:
215: //next line
216: pw.println();
217:
218: pw.close();
219: out.close();
220: } catch (Exception ex) {
221: MessageLog.writeErrorMessage(
222: "PerformanceLogger.scheduleReached", ex, this);
223: }
224:
225: }
226: }
|