2006-04-10 jrandom
* Include a combined send/receive graph (good idea cervantes!) * Proactively drop inbound tunnel requests probabalistically as the estimated queue time approaches our limit, rather than letting them all through up to that limit.
This commit is contained in:
@ -55,6 +55,12 @@ public class GraphHelper {
|
||||
|
||||
public String getImages() {
|
||||
try {
|
||||
_out.write("<img src=\"viewstat.jsp?stat=bw.combined"
|
||||
+ "&periodCount=" + _periodCount
|
||||
+ "&width=" + _width
|
||||
+ "&height=" + _height
|
||||
+ "\" title=\"Combined bandwidth graph\" />\n");
|
||||
|
||||
List listeners = StatSummarizer.instance().getListeners();
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
SummaryListener lsnr = (SummaryListener)listeners.get(i);
|
||||
|
@ -5,18 +5,27 @@ import java.util.*;
|
||||
|
||||
import net.i2p.stat.*;
|
||||
import net.i2p.router.*;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import java.awt.Color;
|
||||
import org.jrobin.graph.RrdGraph;
|
||||
import org.jrobin.graph.RrdGraphDef;
|
||||
import org.jrobin.graph.RrdGraphDefTemplate;
|
||||
import org.jrobin.core.RrdException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class StatSummarizer implements Runnable {
|
||||
private RouterContext _context;
|
||||
private Log _log;
|
||||
/** list of SummaryListener instances */
|
||||
private List _listeners;
|
||||
private static StatSummarizer _instance;
|
||||
|
||||
public StatSummarizer() {
|
||||
_context = (RouterContext)RouterContext.listContexts().get(0); // fuck it, only summarize one per jvm
|
||||
_log = _context.logManager().getLog(getClass());
|
||||
_listeners = new ArrayList(16);
|
||||
_instance = this;
|
||||
}
|
||||
@ -128,6 +137,69 @@ public class StatSummarizer implements Runnable {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean renderRatePng(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, boolean showCredit) throws IOException {
|
||||
long end = _context.clock().now();
|
||||
if (periodCount <= 0) periodCount = SummaryListener.PERIODS;
|
||||
if (periodCount > SummaryListener.PERIODS)
|
||||
periodCount = SummaryListener.PERIODS;
|
||||
long period = 60*1000;
|
||||
long start = end - period*periodCount;
|
||||
long begin = System.currentTimeMillis();
|
||||
try {
|
||||
RrdGraphDef def = new RrdGraphDef();
|
||||
def.setTimePeriod(start/1000, end/1000);
|
||||
String title = "Bandwidth usage";
|
||||
if (!hideTitle)
|
||||
def.setTitle(title);
|
||||
String sendName = SummaryListener.createName(_context, "bw.sendRate.60000");
|
||||
String recvName = SummaryListener.createName(_context, "bw.recvRate.60000");
|
||||
def.datasource(sendName, sendName, sendName, "AVERAGE", "MEMORY");
|
||||
def.datasource(recvName, recvName, recvName, "AVERAGE", "MEMORY");
|
||||
def.area(sendName, Color.BLUE, "Outbound bytes/second");
|
||||
//def.line(sendName, Color.BLUE, "Outbound bytes/second", 3);
|
||||
//def.line(recvName, Color.RED, "Inbound bytes/second@r", 3);
|
||||
def.area(recvName, Color.RED, "Inbound bytes/second@r");
|
||||
if (!hideLegend) {
|
||||
def.gprint(sendName, "AVERAGE", "outbound average: @2@sbytes/second");
|
||||
def.gprint(sendName, "MAX", " max: @2@sbytes/second@r");
|
||||
def.gprint(recvName, "AVERAGE", "inbound average: @2bytes/second@s");
|
||||
def.gprint(recvName, "MAX", " max: @2@sbytes/second@r");
|
||||
}
|
||||
if (!showCredit)
|
||||
def.setShowSignature(false);
|
||||
if (hideLegend)
|
||||
def.setShowLegend(false);
|
||||
if (hideGrid) {
|
||||
def.setGridX(false);
|
||||
def.setGridY(false);
|
||||
}
|
||||
//System.out.println("rendering: path=" + path + " dsNames[0]=" + dsNames[0] + " dsNames[1]=" + dsNames[1] + " lsnr.getName=" + _listener.getName());
|
||||
def.setAntiAliasing(false);
|
||||
//System.out.println("Rendering: \n" + def.exportXmlTemplate());
|
||||
//System.out.println("*****************\nData: \n" + _listener.getData().dump());
|
||||
RrdGraph graph = new RrdGraph(def);
|
||||
//System.out.println("Graph created");
|
||||
byte data[] = null;
|
||||
if ( (width <= 0) || (height <= 0) )
|
||||
data = graph.getPNGBytes();
|
||||
else
|
||||
data = graph.getPNGBytes(width, height);
|
||||
long timeToPlot = System.currentTimeMillis() - begin;
|
||||
out.write(data);
|
||||
//File t = File.createTempFile("jrobinData", ".xml");
|
||||
//_listener.getData().dumpXml(new FileOutputStream(t));
|
||||
//System.out.println("plotted: " + (data != null ? data.length : 0) + " bytes in " + timeToPlot
|
||||
// ); // + ", data written to " + t.getAbsolutePath());
|
||||
return true;
|
||||
} catch (RrdException re) {
|
||||
_log.error("Error rendering", re);
|
||||
throw new IOException("Error plotting: " + re.getMessage());
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Error rendering", ioe);
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param specs statName.period,statName.period,statName.period
|
||||
* @return list of Rate objects
|
||||
|
@ -78,7 +78,7 @@ class SummaryListener implements RateSummaryListener {
|
||||
* munged version from the user/developer-visible name.
|
||||
*
|
||||
*/
|
||||
private static String createName(I2PAppContext ctx, String wanted) {
|
||||
static String createName(I2PAppContext ctx, String wanted) {
|
||||
return ctx.sha().calculateHash(DataHelper.getUTF8(wanted)).toBase64().substring(0,20);
|
||||
}
|
||||
|
||||
|
@ -9,18 +9,25 @@ if (templateFile != null) {
|
||||
net.i2p.stat.Rate rate = null;
|
||||
String stat = request.getParameter("stat");
|
||||
String period = request.getParameter("period");
|
||||
boolean fakeBw = (stat != null && ("bw.combined".equals(stat)));
|
||||
net.i2p.stat.RateStat rs = net.i2p.I2PAppContext.getGlobalContext().statManager().getRate(stat);
|
||||
if ( !rendered && (rs != null)) {
|
||||
if ( !rendered && ((rs != null) || fakeBw) ) {
|
||||
long per = -1;
|
||||
try {
|
||||
per = Long.parseLong(period);
|
||||
rate = rs.getRate(per);
|
||||
if (rate != null) {
|
||||
if (fakeBw)
|
||||
per = 60*1000;
|
||||
else
|
||||
per = Long.parseLong(period);
|
||||
if (!fakeBw)
|
||||
rate = rs.getRate(per);
|
||||
if ( (rate != null) || (fakeBw) ) {
|
||||
java.io.OutputStream cout = response.getOutputStream();
|
||||
String format = request.getParameter("format");
|
||||
if ("xml".equals(format)) {
|
||||
response.setContentType("text/xml");
|
||||
rendered = net.i2p.router.web.StatSummarizer.instance().getXML(rate, cout);
|
||||
if (!fakeBw) {
|
||||
response.setContentType("text/xml");
|
||||
rendered = net.i2p.router.web.StatSummarizer.instance().getXML(rate, cout);
|
||||
}
|
||||
} else {
|
||||
response.setContentType("image/png");
|
||||
int width = -1;
|
||||
@ -39,7 +46,10 @@ if ( !rendered && (rs != null)) {
|
||||
boolean showCredit = true;
|
||||
if (request.getParameter("showCredit") != null)
|
||||
showCredit = Boolean.valueOf(""+request.getParameter("showCredit")).booleanValue();
|
||||
rendered = net.i2p.router.web.StatSummarizer.instance().renderPng(rate, cout, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount, showCredit);
|
||||
if (fakeBw)
|
||||
rendered = net.i2p.router.web.StatSummarizer.instance().renderRatePng(cout, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount, showCredit);
|
||||
else
|
||||
rendered = net.i2p.router.web.StatSummarizer.instance().renderPng(rate, cout, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount, showCredit);
|
||||
}
|
||||
if (rendered)
|
||||
cout.close();
|
||||
|
@ -1,4 +1,10 @@
|
||||
$Id: history.txt,v 1.449 2006/04/08 01:15:45 jrandom Exp $
|
||||
$Id: history.txt,v 1.450 2006/04/08 20:14:09 jrandom Exp $
|
||||
|
||||
2006-04-10 jrandom
|
||||
* Include a combined send/receive graph (good idea cervantes!)
|
||||
* Proactively drop inbound tunnel requests probabalistically as the
|
||||
estimated queue time approaches our limit, rather than letting them all
|
||||
through up to that limit.
|
||||
|
||||
2006-04-08 jrandom
|
||||
* Stat summarization fix (removing the occational holes in the jrobin
|
||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.389 $ $Date: 2006/04/08 01:15:46 $";
|
||||
public final static String ID = "$Revision: 1.390 $ $Date: 2006/04/08 20:14:10 $";
|
||||
public final static String VERSION = "0.6.1.14";
|
||||
public final static long BUILD = 4;
|
||||
public final static long BUILD = 5;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
@ -603,7 +603,10 @@ class BuildHandler {
|
||||
_context.statManager().addRateData("tunnel.dropLoadBacklog", _inboundBuildMessages.size(), _inboundBuildMessages.size());
|
||||
} else {
|
||||
int queueTime = estimateQueueTime(_inboundBuildMessages.size());
|
||||
if (queueTime > BuildRequestor.REQUEST_TIMEOUT/2) {
|
||||
float pDrop = queueTime/(BuildRequestor.REQUEST_TIMEOUT/2);
|
||||
pDrop = pDrop * pDrop * pDrop;
|
||||
float f = _context.random().nextFloat();
|
||||
if (pDrop > f) {
|
||||
_context.statManager().addRateData("tunnel.dropLoadProactive", queueTime, _inboundBuildMessages.size());
|
||||
} else {
|
||||
_inboundBuildMessages.add(new BuildMessageState(receivedMessage, from, fromHash));
|
||||
|
Reference in New Issue
Block a user