2006-03-20 jrandom

* Fix to allow for some slack when coalescing stats
    * Workaround some oddball errors
This commit is contained in:
jrandom
2006-03-20 05:31:09 +00:00
committed by zzz
parent 1ef33906ed
commit c5ddfabfe9
14 changed files with 61 additions and 36 deletions

View File

@ -31,10 +31,10 @@ public class GraphHelper {
}
public GraphHelper() {
_periodCount = SummaryListener.PERIODS;
_periodCount = 60; // SummaryListener.PERIODS;
_showEvents = false;
_width = -1;
_height = -1;
_width = 250;
_height = 100;
_refreshDelaySeconds = 60;
}
@ -79,12 +79,12 @@ public class GraphHelper {
public String getForm() {
try {
_out.write("<form action=\"graphs.jsp\" method=\"GET\">");
_out.write("Periods: <input type=\"text\" name=\"periodCount\" value=\"" + _periodCount + "\" /><br />\n");
_out.write("Periods: <input size=\"3\" type=\"text\" name=\"periodCount\" value=\"" + _periodCount + "\" /><br />\n");
_out.write("Plot averages: <input type=\"radio\" name=\"showEvents\" value=\"false\" " + (_showEvents ? "" : "checked=\"true\" ") + " /> ");
_out.write("or plot events: <input type=\"radio\" name=\"showEvents\" value=\"true\" "+ (_showEvents ? "checked=\"true\" " : "") + " /><br />\n");
_out.write("Image sizes: width: <input size=\"4\" type=\"text\" name=\"width\" value=\"" + _width
+ "\" /> pixels, height: <input size=\"4\" type=\"text\" name=\"height\" value=\"" + _height
+ "\" /> (-1 for the default) <br />\n");
+ "\" /><br />\n");
_out.write("Refresh delay: <select name=\"refreshDelay\"><option value=\"60\">1 minute</option><option value=\"120\">2 minutes</option><option value=\"300\">5 minutes</option><option value=\"600\">10 minutes</option><option value=\"-1\">Never</option></select><br />\n");
_out.write("<input type=\"submit\" value=\"Redraw\" />");
} catch (IOException ioe) {

View File

@ -43,7 +43,10 @@ public class StatSummarizer implements Runnable {
",udp.sendConfirmTime.60000" +
",udp.sendPacketSize.60000" +
",router.activePeers.60000" +
",router.activeSendPeers.60000";
",router.activeSendPeers.60000" +
",tunnel.acceptLoad.60000" +
",client.sendAckTime.60000" +
",client.dispatchNoACK.60000";
private String adjustDatabases(String oldSpecs) {
String spec = _context.getProperty("stat.summaries", DEFAULT_DATABASES);
@ -90,13 +93,13 @@ public class StatSummarizer implements Runnable {
//System.out.println("Start listening for " + r.getRateStat().getName() + ": " + r.getPeriod());
}
public boolean renderPng(Rate rate, OutputStream out) throws IOException {
return renderPng(rate, out, -1, -1, false, false, false, false, -1);
return renderPng(rate, out, -1, -1, false, false, false, false, -1, true);
}
public boolean renderPng(Rate rate, OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount) throws IOException {
public boolean renderPng(Rate rate, OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, boolean showCredit) throws IOException {
for (int i = 0; i < _listeners.size(); i++) {
SummaryListener lsnr = (SummaryListener)_listeners.get(i);
if (lsnr.getRate().equals(rate)) {
lsnr.renderPng(out, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount);
lsnr.renderPng(out, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount, showCredit);
return true;
}
}

View File

@ -32,7 +32,7 @@ class SummaryListener implements RateSummaryListener {
private RrdMemoryBackendFactory _factory;
private SummaryRenderer _renderer;
static final int PERIODS = 600;
static final int PERIODS = 1440;
static {
try {
@ -49,10 +49,13 @@ class SummaryListener implements RateSummaryListener {
}
public void add(double totalValue, long eventCount, double totalEventTime, long period) {
long now = now();
long when = now / 1000;
//System.out.println("add to " + getRate().getRateStat().getName() + " on " + System.currentTimeMillis() + " / " + now + " / " + when);
if (_db != null) {
// add one value to the db (the average value for the period)
try {
_sample.setTime(now()/1000);
_sample.setTime(when);
double val = eventCount > 0 ? (totalValue / (double)eventCount) : 0d;
_sample.setValue(_name, val);
_sample.setValue(_eventName, eventCount);
@ -88,10 +91,12 @@ class SummaryListener implements RateSummaryListener {
_eventName = createName(_context, baseName + ".events");
try {
RrdDef def = new RrdDef(_name, now()/1000, period/1000);
long heartbeat = period*3/1000; // max seconds between events
// for info on the heartbeat, xff, steps, etc, see the rrdcreate man page, aka
// http://www.jrobin.org/support/man/rrdcreate.html
long heartbeat = period*10/1000;
def.addDatasource(_name, "GAUGE", heartbeat, Double.NaN, Double.NaN);
def.addDatasource(_eventName, "GAUGE", heartbeat, 0, Double.NaN);
double xff = 0.5;
double xff = 0.9;
int steps = 1;
int rows = PERIODS;
def.addArchive("AVERAGE", xff, steps, rows);
@ -117,8 +122,8 @@ class SummaryListener implements RateSummaryListener {
_factory.delete(_db.getPath());
_db = null;
}
public void renderPng(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount) throws IOException {
_renderer.render(out, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount);
public void renderPng(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, boolean showCredit) throws IOException {
_renderer.render(out, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount, showCredit);
}
public void renderPng(OutputStream out) throws IOException { _renderer.render(out); }
@ -167,8 +172,8 @@ class SummaryRenderer {
throw ioe;
}
}
public void render(OutputStream out) throws IOException { render(out, -1, -1, false, false, false, false, -1); }
public void render(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount) throws IOException {
public void render(OutputStream out) throws IOException { render(out, -1, -1, false, false, false, false, -1, true); }
public void render(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, boolean showCredit) throws IOException {
long end = _listener.now();
if (periodCount <= 0) periodCount = SummaryListener.PERIODS;
if (periodCount > SummaryListener.PERIODS)
@ -201,6 +206,8 @@ class SummaryRenderer {
def.gprint(plotName, "AVERAGE", "average: @2@s");
def.gprint(plotName, "MAX", " max: @2@s@r");
}
if (!showCredit)
def.setShowSignature(false);
/*
// these four lines set up a graph plotting both values and events on the same chart
// (but with the same coordinates, so the values may look pretty skewed)
@ -220,7 +227,7 @@ class SummaryRenderer {
//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");
//System.out.println("Graph created");
byte data[] = null;
if ( (width <= 0) || (height <= 0) )
data = graph.getPNGBytes();

View File

@ -36,7 +36,10 @@ if ( !rendered && (rs != null)) {
boolean hideGrid = Boolean.valueOf(""+request.getParameter("hideGrid")).booleanValue();
boolean hideTitle = Boolean.valueOf(""+request.getParameter("hideTitle")).booleanValue();
boolean showEvents = Boolean.valueOf(""+request.getParameter("showEvents")).booleanValue();
rendered = net.i2p.router.web.StatSummarizer.instance().renderPng(rate, cout, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount);
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 (rendered)
cout.close();

View File

@ -1,4 +1,8 @@
$Id: history.txt,v 1.434 2006/03/18 18:09:38 jrandom Exp $
$Id: history.txt,v 1.435 2006/03/18 19:23:23 jrandom Exp $
2006-03-20 jrandom
* Fix to allow for some slack when coalescing stats
* Workaround some oddball errors
2006-03-18 jrandom
* Added a new graphs.jsp page to show all of the stats being harvested

View File

@ -1018,10 +1018,10 @@ class CoalesceStatsEvent implements SimpleTimer.TimedEvent {
_ctx = ctx;
ctx.statManager().createRateStat("bw.receiveBps", "How fast we receive data (in KBps)", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("bw.sendBps", "How fast we send data (in KBps)", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("bw.sendRate", "Low level bandwidth send rate, averaged every minute", "Bandwidth", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("bw.recvRate", "Low level bandwidth receive rate, averaged every minute", "Bandwidth", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("bw.sendRate", "Low level bandwidth send rate", "Bandwidth", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("bw.recvRate", "Low level bandwidth receive rate", "Bandwidth", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("router.activePeers", "How many peers we are actively talking with", "Throttle", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("router.activeSendPeers", "How many peers have sent messages to this minute", "Throttle", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("router.activeSendPeers", "How many peers we've sent to this minute", "Throttle", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("router.highCapacityPeers", "How many high capacity peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("router.fastPeers", "How many fast peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
}

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.375 $ $Date: 2006/03/18 18:09:37 $";
public final static String ID = "$Revision: 1.376 $ $Date: 2006/03/18 19:23:23 $";
public final static String VERSION = "0.6.1.12";
public final static long BUILD = 13;
public final static long BUILD = 14;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -108,7 +108,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
ctx.statManager().createFrequencyStat("client.sendMessageFailFrequency", "How often does a client fail to send a message?", "ClientMessages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.sendMessageSize", "How large are messages sent by the client?", "ClientMessages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.sendAckTime", "How long does it take to get an ACK back from a message?", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.sendAckTime", "Message round trip time", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.timeoutCongestionTunnel", "How lagged our tunnels are when a send times out?", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.timeoutCongestionMessage", "How fast we process messages locally when a send times out?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.timeoutCongestionInbound", "How much faster we are receiving data than our average bps when a send times out?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
@ -119,7 +119,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
ctx.statManager().createRateStat("client.dispatchTime", "How long until we've dispatched the message (since we started)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.dispatchSendTime", "How long the actual dispatching takes?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.dispatchNoTunnels", "How long after start do we run out of tunnels to send/receive with?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.dispatchNoACK", "How often we send a client message without asking for an ACK?", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("client.dispatchNoACK", "Repeated message sends to a peer (no ack required)", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l });
long timeoutMs = OVERALL_TIMEOUT_MS_DEFAULT;
_clientMessage = msg;
_clientMessageId = msg.getMessageId();

View File

@ -118,10 +118,16 @@ public class MessageReceiver {
int size = message.getCompleteSize();
if (_log.shouldLog(Log.INFO))
_log.info("Full message received (" + message.getMessageId() + ") after " + message.getLifetime());
I2NPMessage msg = readMessage(buf, message, handler);
long afterRead = System.currentTimeMillis();
if (msg != null)
_transport.messageReceived(msg, null, message.getFrom(), message.getLifetime(), size);
long afterRead = -1;
try {
I2NPMessage msg = readMessage(buf, message, handler);
afterRead = System.currentTimeMillis();
if (msg != null)
_transport.messageReceived(msg, null, message.getFrom(), message.getLifetime(), size);
} catch (RuntimeException re) {
_log.error("b0rked receiving a message.. wazza huzza hmm?", re);
continue;
}
message = null;
long after = System.currentTimeMillis();
if (afterRead - before > 100)

View File

@ -61,7 +61,7 @@ public class OutboundMessageFragments {
_context.statManager().createRateStat("udp.sendConfirmVolley", "How many times did fragments need to be sent before ACK", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.sendFailed", "How many sends a failed message was pushed", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.sendAggressiveFailed", "How many volleys was a packet sent before we gave up", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.outboundActiveCount", "How many messages are in the active pool when a new one is added", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.outboundActiveCount", "How many messages are in the active pool", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.sendRejected", "What volley are we on when the peer was throttled (time == message lifetime)", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.partialACKReceived", "How many fragments were partially ACKed (time == message lifetime)", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.sendSparse", "How many fragments were partially ACKed and hence not resent (time == message lifetime)", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });

View File

@ -92,6 +92,10 @@ public class FragmentHandler {
}
} catch (ArrayIndexOutOfBoundsException aioobe) {
_context.statManager().addRateData("tunnel.corruptMessage", 1, 1);
} catch (NullPointerException npe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Corrupt fragment received: offset = " + offset, npe);
_context.statManager().addRateData("tunnel.corruptMessage", 1, 1);
} catch (RuntimeException e) {
if (_log.shouldLog(Log.ERROR))
_log.error("Corrupt fragment received: offset = " + offset, e);

View File

@ -53,7 +53,7 @@ public class TunnelDispatcher implements Service {
_leaveJob = new LeaveTunnel(ctx);
ctx.statManager().createRateStat("tunnel.participatingTunnels",
"How many tunnels are we participating in?", "Tunnels",
new long[] { 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l });
new long[] { 60*1000, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("tunnel.dispatchOutboundPeer",
"How many messages we send out a tunnel targetting a peer?", "Tunnels",
new long[] { 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l });

View File

@ -42,7 +42,7 @@ class BuildHandler {
_context.statManager().createRateStat("tunnel.rejectTimeout", "How often we reject a tunnel because we can't find the next hop", "Tunnels", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("tunnel.rejectOverloaded", "How long we had to wait before processing the request (when it was rejected)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("tunnel.acceptLoad", "How long we had to wait before processing the request (when it was accepted)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("tunnel.acceptLoad", "Delay before processing the accepted request", "Tunnels", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("tunnel.dropLoad", "How long we had to wait before finally giving up on an inbound request (period is queue count)?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("tunnel.handleRemaining", "How many pending inbound requests were left on the queue after one pass?", "Tunnels", new long[] { 60*1000, 10*60*1000 });

View File

@ -189,8 +189,6 @@ class TestJob extends JobImpl {
private int getTestPeriod() { return 20*1000; }
private void scheduleRetest() { scheduleRetest(false); }
private void scheduleRetest(boolean asap) {
_outTunnel = null;
_replyTunnel = null;
if (asap) {
requeue(getContext().random().nextInt(TEST_DELAY));
} else {