package net.i2p.router.admin; import java.io.IOException; import java.io.Writer; import java.text.DecimalFormat; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.Set; import net.i2p.data.DataHelper; import net.i2p.router.RouterContext; import net.i2p.stat.Frequency; import net.i2p.stat.FrequencyStat; import net.i2p.stat.Rate; import net.i2p.stat.RateStat; import net.i2p.util.Log; /** * Dump the stats to the web admin interface */ public class StatsGenerator { private Log _log; private RouterContext _context; public StatsGenerator(RouterContext context) { _context = context; _log = context.logManager().getLog(StatsGenerator.class); } public void generateStatsPage(Writer out) throws IOException { StringBuffer buf = new StringBuffer(16*1024); buf.append("

Router statistics


"); buf.append("
"); buf.append(" "); buf.append("
"); buf.append("Statistics gathered during this router's uptime ("); long uptime = _context.router().getUptime(); buf.append(DataHelper.formatDuration(uptime)); buf.append("). The data gathered is quantized over a 1 minute period, so should just be used as an estimate

"); out.write(buf.toString()); buf.setLength(0); for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) { String group = (String)iter.next(); Set stats = (Set)groups.get(group); buf.append("

"); buf.append(group); buf.append("

"); buf.append("
"); } out.flush(); } private void renderFrequency(String name, StringBuffer buf) { FrequencyStat freq = _context.statManager().getFrequency(name); buf.append(""); buf.append(freq.getDescription()); buf.append("
"); long periods[] = freq.getPeriods(); Arrays.sort(periods); for (int i = 0; i < periods.length; i++) { renderPeriod(buf, periods[i], "frequency"); Frequency curFreq = freq.getFrequency(periods[i]); buf.append(" avg per period: ("); buf.append(num(curFreq.getAverageEventsPerPeriod())); buf.append(", max "); buf.append(num(curFreq.getMaxAverageEventsPerPeriod())); if ( (curFreq.getMaxAverageEventsPerPeriod() > 0) && (curFreq.getAverageEventsPerPeriod() > 0) ) { buf.append(", current is "); buf.append(pct(curFreq.getAverageEventsPerPeriod()/curFreq.getMaxAverageEventsPerPeriod())); buf.append(" of max"); } buf.append(")"); //buf.append(" avg interval between updates: (").append(num(curFreq.getAverageInterval())).append("ms, min "); //buf.append(num(curFreq.getMinAverageInterval())).append("ms)"); buf.append(" strict average per period: "); buf.append(num(curFreq.getStrictAverageEventsPerPeriod())); buf.append(" events (averaged "); buf.append(" using the lifetime of "); buf.append(curFreq.getEventCount()); buf.append(" events)"); buf.append("
"); } buf.append("
"); } private void renderRate(String name, StringBuffer buf) { RateStat rate = _context.statManager().getRate(name); buf.append(""); buf.append(rate.getDescription()); buf.append("
"); long periods[] = rate.getPeriods(); Arrays.sort(periods); buf.append(""); buf.append("
"); } private static void renderPeriod(StringBuffer buf, long period, String name) { buf.append(""); buf.append(DataHelper.formatDuration(period)); buf.append(" "); buf.append(name); buf.append(": "); } private final static DecimalFormat _fmt = new DecimalFormat("###,##0.00"); private final static String num(double num) { synchronized (_fmt) { return _fmt.format(num); } } private final static DecimalFormat _pct = new DecimalFormat("#0.00%"); private final static String pct(double num) { synchronized (_pct) { return _pct.format(num); } } }