diff --git a/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java index ea66bed63..2e2bb9fbe 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java @@ -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("
"); - _out.write("Periods:
\n"); + _out.write("Periods:
\n"); _out.write("Plot averages: "); _out.write("or plot events:
\n"); _out.write("Image sizes: width: pixels, height: (-1 for the default)
\n"); + + "\" />
\n"); _out.write("Refresh delay:
\n"); _out.write(""); } catch (IOException ioe) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java b/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java index f193122aa..a3344e094 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java @@ -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; } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryListener.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryListener.java index 27ee97074..8cbc73f57 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryListener.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryListener.java @@ -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(); diff --git a/apps/routerconsole/jsp/viewstat.jsp b/apps/routerconsole/jsp/viewstat.jsp index c5663e0f3..0c29f6560 100644 --- a/apps/routerconsole/jsp/viewstat.jsp +++ b/apps/routerconsole/jsp/viewstat.jsp @@ -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(); diff --git a/history.txt b/history.txt index eeb54386e..eb1791df1 100644 --- a/history.txt +++ b/history.txt @@ -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 diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index e1af6eb0c..213ac640a 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -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 }); } diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 8704ead42..0b74812c8 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -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); diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java index eff234246..dd9f0b300 100644 --- a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java +++ b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java @@ -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(); diff --git a/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java b/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java index 764d7cf97..b28df9ede 100644 --- a/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java +++ b/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java @@ -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) diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java index f61041f84..37803efa4 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java @@ -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 }); diff --git a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java index 32128d059..ce756ad6e 100644 --- a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java +++ b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java @@ -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); diff --git a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java index 1503c4aaa..9156537a0 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java @@ -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 }); diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index 2f29badfd..f0359dbeb 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -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 }); diff --git a/router/java/src/net/i2p/router/tunnel/pool/TestJob.java b/router/java/src/net/i2p/router/tunnel/pool/TestJob.java index a593b20ed..060b7c1c3 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TestJob.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TestJob.java @@ -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 {