send the stats page out in chunks (more mem efficient, blah blah blah)

This commit is contained in:
jrandom
2004-07-10 01:39:54 +00:00
committed by zzz
parent ab99122211
commit b648fa2b70

View File

@ -29,183 +29,180 @@ public class StatsGenerator {
_log = context.logManager().getLog(StatsGenerator.class); _log = context.logManager().getLog(StatsGenerator.class);
} }
public String generateStatsPage() {
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
try {
generateStatsPage(baos);
} catch (IOException ioe) {
_log.error("Error generating stats", ioe);
}
return new String(baos.toByteArray());
}
public void generateStatsPage(OutputStream out) throws IOException { public void generateStatsPage(OutputStream out) throws IOException {
PrintWriter pw = new PrintWriter(out); StringBuffer buf = new StringBuffer(16*1024);
pw.println("<html><head><title>I2P Router Stats</title></head><body>"); buf.append("<html><head><title>I2P Router Stats</title></head><body>");
pw.println("<h1>Router statistics</h1>"); buf.append("<h1>Router statistics</h1>");
pw.println("<i><a href=\"/routerConsole.html\">console</a> | <a href=\"/routerStats.html\">stats</a></i><hr />"); buf.append("<i><a href=\"/routerConsole.html\">console</a> | <a href=\"/routerStats.html\">stats</a></i><hr />");
buf.append("<form action=\"/routerStats.html\">");
buf.append("<select name=\"go\" onChange='location.href=this.value'>");
out.write(buf.toString().getBytes());
buf.setLength(0);
Map groups = _context.statManager().getStatsByGroup(); Map groups = _context.statManager().getStatsByGroup();
pw.println("<form action=\"/routerStats.html\">");
pw.println("<select name=\"go\" onChange='location.href=this.value'>");
for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) { for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) {
String group = (String)iter.next(); String group = (String)iter.next();
Set stats = (Set)groups.get(group); Set stats = (Set)groups.get(group);
pw.print("<option value=\"/routerStats.html#"); buf.append("<option value=\"/routerStats.html#").append(group).append("\">");
pw.print(group); buf.append(group).append("</option>\n");
pw.print("\">");
pw.print(group);
pw.println("</option>\n");
for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) { for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) {
String stat = (String)statIter.next(); String stat = (String)statIter.next();
pw.print("<option value=\"/routerStats.html#"); buf.append("<option value=\"/routerStats.html#");
pw.print(stat); buf.append(stat);
pw.print("\">..."); buf.append("\">...");
pw.print(stat); buf.append(stat);
pw.println("</option>\n"); buf.append("</option>\n");
} }
out.write(buf.toString().getBytes());
buf.setLength(0);
} }
pw.println("</select>"); buf.append("</select>");
pw.println("</form>"); buf.append("</form>");
pw.print("Statistics gathered during this router's uptime ("); buf.append("Statistics gathered during this router's uptime (");
long uptime = _context.router().getUptime(); long uptime = _context.router().getUptime();
pw.print(DataHelper.formatDuration(uptime)); buf.append(DataHelper.formatDuration(uptime));
pw.println("). The data gathered is quantized over a 1 minute period, so should just be used as an estimate<p />"); buf.append("). The data gathered is quantized over a 1 minute period, so should just be used as an estimate<p />");
out.write(buf.toString().getBytes());
buf.setLength(0);
for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) { for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) {
String group = (String)iter.next(); String group = (String)iter.next();
Set stats = (Set)groups.get(group); Set stats = (Set)groups.get(group);
pw.print("<h2><a name=\""); buf.append("<h2><a name=\"");
pw.print(group); buf.append(group);
pw.print("\">"); buf.append("\">");
pw.print(group); buf.append(group);
pw.println("</a></h2>"); buf.append("</a></h2>");
pw.println("<ul>"); buf.append("<ul>");
out.write(buf.toString().getBytes());
buf.setLength(0);
for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) { for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) {
String stat = (String)statIter.next(); String stat = (String)statIter.next();
pw.print("<li><b><a name=\""); buf.append("<li><b><a name=\"");
pw.print(stat); buf.append(stat);
pw.print("\">"); buf.append("\">");
pw.print(stat); buf.append(stat);
pw.println("</a></b><br />"); buf.append("</a></b><br />");
if (_context.statManager().isFrequency(stat)) if (_context.statManager().isFrequency(stat))
renderFrequency(stat, pw); renderFrequency(stat, buf);
else else
renderRate(stat, pw); renderRate(stat, buf);
out.write(buf.toString().getBytes());
buf.setLength(0);
} }
pw.println("</ul><hr />"); out.write("</ul><hr />".getBytes());
} }
pw.println("</body></html>"); out.write("</body></html>".getBytes());
pw.flush();
} }
private void renderFrequency(String name, PrintWriter pw) throws IOException { private void renderFrequency(String name, StringBuffer buf) {
FrequencyStat freq = _context.statManager().getFrequency(name); FrequencyStat freq = _context.statManager().getFrequency(name);
pw.print("<i>"); buf.append("<i>");
pw.print(freq.getDescription()); buf.append(freq.getDescription());
pw.println("</i><br />"); buf.append("</i><br />");
long periods[] = freq.getPeriods(); long periods[] = freq.getPeriods();
Arrays.sort(periods); Arrays.sort(periods);
for (int i = 0; i < periods.length; i++) { for (int i = 0; i < periods.length; i++) {
renderPeriod(pw, periods[i], "frequency"); renderPeriod(buf, periods[i], "frequency");
Frequency curFreq = freq.getFrequency(periods[i]); Frequency curFreq = freq.getFrequency(periods[i]);
pw.print(" <i>avg per period:</i> ("); buf.append(" <i>avg per period:</i> (");
pw.print(num(curFreq.getAverageEventsPerPeriod())); buf.append(num(curFreq.getAverageEventsPerPeriod()));
pw.print(", max "); buf.append(", max ");
pw.print(num(curFreq.getMaxAverageEventsPerPeriod())); buf.append(num(curFreq.getMaxAverageEventsPerPeriod()));
if ( (curFreq.getMaxAverageEventsPerPeriod() > 0) && (curFreq.getAverageEventsPerPeriod() > 0) ) { if ( (curFreq.getMaxAverageEventsPerPeriod() > 0) && (curFreq.getAverageEventsPerPeriod() > 0) ) {
pw.print(", current is "); buf.append(", current is ");
pw.print(pct(curFreq.getAverageEventsPerPeriod()/curFreq.getMaxAverageEventsPerPeriod())); buf.append(pct(curFreq.getAverageEventsPerPeriod()/curFreq.getMaxAverageEventsPerPeriod()));
pw.print(" of max"); buf.append(" of max");
} }
pw.print(")"); buf.append(")");
//buf.append(" <i>avg interval between updates:</i> (").append(num(curFreq.getAverageInterval())).append("ms, min "); //buf.append(" <i>avg interval between updates:</i> (").append(num(curFreq.getAverageInterval())).append("ms, min ");
//buf.append(num(curFreq.getMinAverageInterval())).append("ms)"); //buf.append(num(curFreq.getMinAverageInterval())).append("ms)");
pw.print(" <i>strict average per period:</i> "); buf.append(" <i>strict average per period:</i> ");
pw.print(num(curFreq.getStrictAverageEventsPerPeriod())); buf.append(num(curFreq.getStrictAverageEventsPerPeriod()));
pw.print(" events (averaged "); buf.append(" events (averaged ");
pw.print(" using the lifetime of "); buf.append(" using the lifetime of ");
pw.print(num(curFreq.getEventCount())); buf.append(num(curFreq.getEventCount()));
pw.print(" events)"); buf.append(" events)");
pw.println("<br />"); buf.append("<br />");
} }
pw.println("<br />"); buf.append("<br />");
} }
private void renderRate(String name, PrintWriter pw) throws IOException { private void renderRate(String name, StringBuffer buf) {
RateStat rate = _context.statManager().getRate(name); RateStat rate = _context.statManager().getRate(name);
pw.print("<i>"); buf.append("<i>");
pw.print(rate.getDescription()); buf.append(rate.getDescription());
pw.println("</i><br />"); buf.append("</i><br />");
long periods[] = rate.getPeriods(); long periods[] = rate.getPeriods();
Arrays.sort(periods); Arrays.sort(periods);
pw.println("<ul>"); buf.append("<ul>");
for (int i = 0; i < periods.length; i++) { for (int i = 0; i < periods.length; i++) {
pw.println("<li>"); buf.append("<li>");
renderPeriod(pw, periods[i], "rate"); renderPeriod(buf, periods[i], "rate");
Rate curRate = rate.getRate(periods[i]); Rate curRate = rate.getRate(periods[i]);
pw.print( "<i>avg value:</i> ("); buf.append( "<i>avg value:</i> (");
pw.print(num(curRate.getAverageValue())); buf.append(num(curRate.getAverageValue()));
pw.print(" peak "); buf.append(" peak ");
pw.print(num(curRate.getExtremeAverageValue())); buf.append(num(curRate.getExtremeAverageValue()));
pw.print(", ["); buf.append(", [");
pw.print(pct(curRate.getPercentageOfExtremeValue())); buf.append(pct(curRate.getPercentageOfExtremeValue()));
pw.print(" of max"); buf.append(" of max");
pw.print(", and "); buf.append(", and ");
pw.print(pct(curRate.getPercentageOfLifetimeValue())); buf.append(pct(curRate.getPercentageOfLifetimeValue()));
pw.print(" of lifetime average]"); buf.append(" of lifetime average]");
pw.print(")"); buf.append(")");
pw.print(" <i>highest total period value:</i> ("); buf.append(" <i>highest total period value:</i> (");
pw.print(num(curRate.getExtremeTotalValue())); buf.append(num(curRate.getExtremeTotalValue()));
pw.print(")"); buf.append(")");
if (curRate.getLifetimeTotalEventTime() > 0) { if (curRate.getLifetimeTotalEventTime() > 0) {
pw.print(" <i>saturation:</i> ("); buf.append(" <i>saturation:</i> (");
pw.print(pct(curRate.getLastEventSaturation())); buf.append(pct(curRate.getLastEventSaturation()));
pw.print(")"); buf.append(")");
pw.print(" <i>saturated limit:</i> ("); buf.append(" <i>saturated limit:</i> (");
pw.print(num(curRate.getLastSaturationLimit())); buf.append(num(curRate.getLastSaturationLimit()));
pw.print(")"); buf.append(")");
pw.print(" <i>peak saturation:</i> ("); buf.append(" <i>peak saturation:</i> (");
pw.print(pct(curRate.getExtremeEventSaturation())); buf.append(pct(curRate.getExtremeEventSaturation()));
pw.print(")"); buf.append(")");
pw.print(" <i>peak saturated limit:</i> ("); buf.append(" <i>peak saturated limit:</i> (");
pw.print(num(curRate.getExtremeSaturationLimit())); buf.append(num(curRate.getExtremeSaturationLimit()));
pw.print(")"); buf.append(")");
} }
pw.print(" <i>events per period:</i> "); buf.append(" <i>events per period:</i> ");
pw.print(num(curRate.getLastEventCount())); buf.append(num(curRate.getLastEventCount()));
long numPeriods = curRate.getLifetimePeriods(); long numPeriods = curRate.getLifetimePeriods();
if (numPeriods > 0) { if (numPeriods > 0) {
double avgFrequency = curRate.getLifetimeEventCount() / (double)numPeriods; double avgFrequency = curRate.getLifetimeEventCount() / (double)numPeriods;
double peakFrequency = curRate.getExtremeEventCount(); double peakFrequency = curRate.getExtremeEventCount();
pw.print(" (lifetime average: "); buf.append(" (lifetime average: ");
pw.print(num(avgFrequency)); buf.append(num(avgFrequency));
pw.print(", peak average: "); buf.append(", peak average: ");
pw.print(num(curRate.getExtremeEventCount())); buf.append(num(curRate.getExtremeEventCount()));
pw.println(")"); buf.append(")");
} }
pw.print("</li>"); buf.append("</li>");
if (i + 1 == periods.length) { if (i + 1 == periods.length) {
// last one, so lets display the strict average // last one, so lets display the strict average
pw.print("<li><b>lifetime average value:</b> "); buf.append("<li><b>lifetime average value:</b> ");
pw.print(num(curRate.getLifetimeAverageValue())); buf.append(num(curRate.getLifetimeAverageValue()));
pw.print(" over "); buf.append(" over ");
pw.print(num(curRate.getLifetimeEventCount())); buf.append(num(curRate.getLifetimeEventCount()));
pw.println(" events<br /></li>"); buf.append(" events<br /></li>");
} }
} }
pw.print("</ul>"); buf.append("</ul>");
pw.println("<br />"); buf.append("<br />");
} }
private static void renderPeriod(PrintWriter pw, long period, String name) throws IOException { private static void renderPeriod(StringBuffer buf, long period, String name) {
pw.print("<b>"); buf.append("<b>");
pw.print(DataHelper.formatDuration(period)); buf.append(DataHelper.formatDuration(period));
pw.print(" "); buf.append(" ");
pw.print(name); buf.append(name);
pw.print(":</b> "); buf.append(":</b> ");
} }
private final static DecimalFormat _fmt = new DecimalFormat("###,##0.00"); private final static DecimalFormat _fmt = new DecimalFormat("###,##0.00");