* updated stats:
- sendsPerFailure: how many partial sends we make when they all fail - timeoutCongestionInbound: describes how much faster than our average speed we were receiving data when each partial send timed out (in Bps) - timeoutCongestionMessage: our send processing time when each partial send timed out (in ms) - timeoutCongestionTunnel: our tunnel test time when each partial send timed out (in ms) - participatingMessagesProcessedActive: # of messages more than the (most recent) average that a tunnel we were participating in transmitted (for tunnels with more than the average) * updated to use Writer for rendering the console, so we can do partial writes (and hopefully help debug some kooky threading bugs on kaffe)
This commit is contained in:
@ -2,11 +2,14 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class NetDbHelper {
|
||||
private RouterContext _context;
|
||||
private Writer _out;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@ -23,13 +26,21 @@ public class NetDbHelper {
|
||||
|
||||
public NetDbHelper() {}
|
||||
|
||||
public void setWriter(Writer writer) { _out = writer; }
|
||||
|
||||
public String getNetDbSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
try {
|
||||
_context.netDb().renderStatusHTML(baos);
|
||||
if (_out != null) {
|
||||
_context.netDb().renderStatusHTML(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
_context.netDb().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
@ -9,6 +11,7 @@ import net.i2p.router.admin.StatsGenerator;
|
||||
|
||||
public class OldConsoleHelper {
|
||||
private RouterContext _context;
|
||||
private Writer _out;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@ -25,11 +28,20 @@ public class OldConsoleHelper {
|
||||
|
||||
public OldConsoleHelper() {}
|
||||
|
||||
public void setWriter(Writer writer) {
|
||||
_out = writer;
|
||||
}
|
||||
|
||||
public String getConsole() {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(128*1024);
|
||||
_context.router().renderStatusHTML(baos);
|
||||
return baos.toString();
|
||||
if (_out != null) {
|
||||
_context.router().renderStatusHTML(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(128*1024);
|
||||
_context.router().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
return baos.toString();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return "<b>Error rending the console</b>";
|
||||
}
|
||||
@ -38,9 +50,14 @@ public class OldConsoleHelper {
|
||||
public String getStats() {
|
||||
StatsGenerator gen = new StatsGenerator(_context);
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
gen.generateStatsPage(baos);
|
||||
return baos.toString();
|
||||
if (_out != null) {
|
||||
gen.generateStatsPage(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
gen.generateStatsPage(new OutputStreamWriter(baos));
|
||||
return baos.toString();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return "<b>Error rending the console</b>";
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
@ -26,7 +27,7 @@ public class ProfilesHelper {
|
||||
public String getProfileSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(16*1024);
|
||||
try {
|
||||
_context.profileOrganizer().renderStatusHTML(baos);
|
||||
_context.profileOrganizer().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
@ -36,7 +37,7 @@ public class ProfilesHelper {
|
||||
public String getShitlistSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024);
|
||||
try {
|
||||
_context.shitlist().renderStatusHTML(baos);
|
||||
_context.shitlist().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
@ -334,7 +335,7 @@ public class SummaryHelper {
|
||||
public String getDestinations() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
||||
try {
|
||||
_context.clientManager().renderStatusHTML(baos);
|
||||
_context.clientManager().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
return new String(baos.toByteArray());
|
||||
} catch (IOException ioe) {
|
||||
_context.logManager().getLog(SummaryHelper.class).error("Error rendering client info", ioe);
|
||||
@ -397,8 +398,7 @@ public class SummaryHelper {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate delayRate = _context.statManager().getRate("transport.sendProcessingTime").getRate(60*1000);
|
||||
return ((int)delayRate.getAverageValue()) + "ms";
|
||||
return _context.throttle().getMessageDelay() + "ms";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -410,7 +410,6 @@ public class SummaryHelper {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate lagRate = _context.statManager().getRate("tunnel.testSuccessTime").getRate(10*60*1000);
|
||||
return ((int)lagRate.getAverageValue()) + "ms";
|
||||
return _context.throttle().getTunnelLag() + "ms";
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
<div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.NetDbHelper" id="netdbHelper" scope="request" />
|
||||
<jsp:setProperty name="netdbHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="netdbHelper" property="writer" value="<%=out%>" />
|
||||
<jsp:getProperty name="netdbHelper" property="netDbSummary" />
|
||||
</div>
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.OldConsoleHelper" id="conhelper" scope="request" />
|
||||
<jsp:setProperty name="conhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="conhelper" property="writer" value="<%=out%>" />
|
||||
|
||||
<div class="main" id="main">
|
||||
<jsp:getProperty name="conhelper" property="console" />
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.OldConsoleHelper" id="oldhelper" scope="request" />
|
||||
<jsp:setProperty name="oldhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="oldhelper" property="writer" value="<%=out%>" />
|
||||
|
||||
<div class="main" id="main">
|
||||
<jsp:getProperty name="oldhelper" property="stats" />
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
@ -70,7 +70,7 @@ public abstract class ClientManagerFacade implements Service {
|
||||
*
|
||||
*/
|
||||
public abstract SessionConfig getClientSessionConfig(Destination dest);
|
||||
public void renderStatusHTML(OutputStream out) throws IOException { }
|
||||
public void renderStatusHTML(Writer out) throws IOException { }
|
||||
}
|
||||
|
||||
class DummyClientManagerFacade extends ClientManagerFacade {
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -23,7 +23,7 @@ import java.util.Set;
|
||||
public abstract class CommSystemFacade implements Service {
|
||||
public abstract void processMessage(OutNetMessage msg);
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException { }
|
||||
public void renderStatusHTML(Writer out) throws IOException { }
|
||||
|
||||
/** Create the set of RouterAddress structures based on the router's config */
|
||||
public Set createAddresses() { return new HashSet(); }
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@ -558,18 +558,18 @@ public class JobQueue {
|
||||
// the remainder are utility methods for dumping status info
|
||||
////
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
ArrayList readyJobs = null;
|
||||
ArrayList timedJobs = null;
|
||||
ArrayList activeJobs = new ArrayList(1);
|
||||
ArrayList justFinishedJobs = new ArrayList(4);
|
||||
out.write("<!-- jobQueue rendering -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering -->\n");
|
||||
out.flush();
|
||||
synchronized (_readyJobs) { readyJobs = new ArrayList(_readyJobs); }
|
||||
out.write("<!-- jobQueue rendering: after readyJobs sync -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after readyJobs sync -->\n");
|
||||
out.flush();
|
||||
synchronized (_timedJobs) { timedJobs = new ArrayList(_timedJobs); }
|
||||
out.write("<!-- jobQueue rendering: after timedJobs sync -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after timedJobs sync -->\n");
|
||||
out.flush();
|
||||
int numRunners = 0;
|
||||
synchronized (_queueRunners) {
|
||||
@ -586,7 +586,7 @@ public class JobQueue {
|
||||
numRunners = _queueRunners.size();
|
||||
}
|
||||
|
||||
out.write("<!-- jobQueue rendering: after queueRunners sync -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after queueRunners sync -->\n");
|
||||
out.flush();
|
||||
|
||||
StringBuffer buf = new StringBuffer(32*1024);
|
||||
@ -631,15 +631,15 @@ public class JobQueue {
|
||||
}
|
||||
buf.append("</ol>\n");
|
||||
|
||||
out.write("<!-- jobQueue rendering: after main buffer, before stats -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after main buffer, before stats -->\n");
|
||||
out.flush();
|
||||
|
||||
getJobStats(buf);
|
||||
|
||||
out.write("<!-- jobQueue rendering: after stats -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after stats -->\n");
|
||||
out.flush();
|
||||
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
/** render the HTML for the job stats */
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@ -95,5 +95,5 @@ class DummyNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
|
||||
public Set findNearestRouters(Hash key, int maxNumRouters, Set peersToIgnore) { return new HashSet(_routers.values()); }
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {}
|
||||
public void renderStatusHTML(Writer out) throws IOException {}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@ -315,8 +315,8 @@ public class Router {
|
||||
_context.inNetMessagePool().registerHandlerJobBuilder(TunnelMessage.MESSAGE_TYPE, new TunnelMessageHandler(_context));
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
out.write(("<h1>Router console</h1>\n" +
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
out.write("<h1>Router console</h1>\n" +
|
||||
"<i><a href=\"/oldconsole.jsp\">console</a> | <a href=\"/oldstats.jsp\">stats</a></i><br>\n" +
|
||||
"<form action=\"/oldconsole.jsp\">" +
|
||||
"<select name=\"go\" onChange='location.href=this.value'>" +
|
||||
@ -331,7 +331,7 @@ public class Router {
|
||||
"<option value=\"/oldconsole.jsp#netdb\">Network Database</option>\n" +
|
||||
"<option value=\"/oldconsole.jsp#logs\">Log messages</option>\n" +
|
||||
"</select> <input type=\"submit\" value=\"GO\" /> </form>" +
|
||||
"<hr />\n").getBytes());
|
||||
"<hr />\n");
|
||||
|
||||
StringBuffer buf = new StringBuffer(32*1024);
|
||||
|
||||
@ -453,39 +453,39 @@ public class Router {
|
||||
buf.append("trying to transfer data. Lifetime averages count how many elephants there are on the moon [like anyone reads this text]</i>");
|
||||
buf.append("\n");
|
||||
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
|
||||
_context.bandwidthLimiter().renderStatusHTML(out);
|
||||
|
||||
out.write("<hr /><a name=\"clients\"> </a>\n".getBytes());
|
||||
out.write("<hr /><a name=\"clients\"> </a>\n");
|
||||
|
||||
_context.clientManager().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"transports\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"transports\"> </a>\n");
|
||||
|
||||
_context.commSystem().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"profiles\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"profiles\"> </a>\n");
|
||||
|
||||
_context.peerManager().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"tunnels\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"tunnels\"> </a>\n");
|
||||
|
||||
_context.tunnelManager().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"jobs\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"jobs\"> </a>\n");
|
||||
|
||||
_context.jobQueue().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"shitlist\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"shitlist\"> </a>\n");
|
||||
|
||||
_context.shitlist().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"pending\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"pending\"> </a>\n");
|
||||
|
||||
_context.messageRegistry().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"netdb\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"netdb\"> </a>\n");
|
||||
|
||||
_context.netDb().renderStatusHTML(out);
|
||||
|
||||
@ -500,7 +500,7 @@ public class Router {
|
||||
buf.append("</pre></td></tr>\n");
|
||||
}
|
||||
buf.append("</table>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
private static int MAX_MSG_LENGTH = 120;
|
||||
|
@ -31,4 +31,15 @@ public interface RouterThrottle {
|
||||
*
|
||||
*/
|
||||
public boolean acceptNetDbLookupRequest(Hash key);
|
||||
|
||||
/** How backed up we are at the moment processing messages (in milliseconds) */
|
||||
public long getMessageDelay();
|
||||
/** How backed up our tunnels are at the moment (in milliseconds) */
|
||||
public long getTunnelLag();
|
||||
/**
|
||||
* How much faster (or if negative, slower) we are receiving data as
|
||||
* opposed to our longer term averages?
|
||||
*
|
||||
*/
|
||||
public double getInboundRateDelta();
|
||||
}
|
||||
|
@ -154,5 +154,35 @@ class RouterThrottleImpl implements RouterThrottle {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public long getMessageDelay() {
|
||||
Rate delayRate = _context.statManager().getRate("transport.sendProcessingTime").getRate(60*1000);
|
||||
return (long)delayRate.getAverageValue();
|
||||
}
|
||||
|
||||
public long getTunnelLag() {
|
||||
Rate lagRate = _context.statManager().getRate("tunnel.testSuccessTime").getRate(10*60*1000);
|
||||
return (long)lagRate.getAverageValue();
|
||||
}
|
||||
|
||||
public double getInboundRateDelta() {
|
||||
RateStat receiveRate = _context.statManager().getRate("transport.sendMessageSize");
|
||||
double nowBps = getBps(receiveRate.getRate(60*1000));
|
||||
double fiveMinBps = getBps(receiveRate.getRate(5*60*1000));
|
||||
double hourBps = getBps(receiveRate.getRate(60*60*1000));
|
||||
double dailyBps = getBps(receiveRate.getRate(24*60*60*1000));
|
||||
|
||||
if (nowBps < 0) return 0;
|
||||
if (dailyBps > 0) return nowBps - dailyBps;
|
||||
if (hourBps > 0) return nowBps - hourBps;
|
||||
if (fiveMinBps > 0) return nowBps - fiveMinBps;
|
||||
return 0;
|
||||
}
|
||||
private double getBps(Rate rate) {
|
||||
if (rate == null) return -1;
|
||||
double bytes = rate.getLastTotalValue();
|
||||
return (bytes*1000.0d)/rate.getPeriod();
|
||||
}
|
||||
|
||||
protected RouterContext getContext() { return _context; }
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* Define the manageable service interface for the subsystems in the I2P router
|
||||
@ -37,5 +37,5 @@ public interface Service {
|
||||
*/
|
||||
public void restart();
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException;
|
||||
public void renderStatusHTML(Writer out) throws IOException;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.crypto.PersistentSessionKeyManager;
|
||||
import net.i2p.crypto.SessionKeyManager;
|
||||
@ -97,7 +97,7 @@ public class SessionKeyPersistenceHelper implements Service {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) { }
|
||||
public void renderStatusHTML(Writer out) { }
|
||||
|
||||
private class SessionKeyWriterJob extends JobImpl {
|
||||
public SessionKeyWriterJob() {
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@ -123,7 +123,7 @@ public class Shitlist {
|
||||
}
|
||||
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("<h2>Shitlist</h2>");
|
||||
Map shitlist = null;
|
||||
@ -152,6 +152,6 @@ public class Shitlist {
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
buf.append("</ul>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ package net.i2p.router;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
@ -107,32 +107,33 @@ public class StatisticsManager implements Service {
|
||||
includeRate("jobQueue.jobLag", stats, new long[] { 60*1000, 60*60*1000 });
|
||||
includeRate("jobQueue.jobRun", stats, new long[] { 60*1000, 60*60*1000 });
|
||||
includeRate("crypto.elGamal.encrypt", stats, new long[] { 60*1000, 60*60*1000 });
|
||||
includeRate("crypto.garlic.decryptFail", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
//includeRate("crypto.garlic.decryptFail", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("tunnel.unknownTunnelTimeLeft", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("jobQueue.readyJobs", stats, new long[] { 60*1000, 60*60*1000 });
|
||||
//includeRate("jobQueue.droppedJobs", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("inNetPool.dropped", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("tunnel.participatingTunnels", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("tunnel.testSuccessTime", stats, new long[] { 60*60*1000l, 24*60*60*1000l });
|
||||
includeRate("tunnel.outboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
includeRate("tunnel.inboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("tunnel.outboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("tunnel.inboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
includeRate("tunnel.participatingMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
includeRate("tunnel.expiredAfterAcceptTime", stats, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
includeRate("tunnel.participatingMessagesProcessedActive", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("tunnel.expiredAfterAcceptTime", stats, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
includeRate("tunnel.bytesAllocatedAtAccept", stats, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
includeRate("netDb.lookupsReceived", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("netDb.lookupsHandled", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("netDb.lookupsMatched", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("netDb.storeSent", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("netDb.storeSent", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("netDb.successPeers", stats, new long[] { 60*60*1000 });
|
||||
includeRate("netDb.failedPeers", stats, new long[] { 60*60*1000 });
|
||||
includeRate("router.throttleNetDbDoSSend", stats, new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("router.throttleNetDbDoS", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("router.throttleNetDbDoSSend", stats, new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
//includeRate("router.throttleNetDbDoS", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("netDb.searchCount", stats, new long[] { 3*60*60*1000});
|
||||
//includeRate("netDb.searchMessageCount", stats, new long[] { 5*60*1000, 10*60*1000, 60*60*1000 });
|
||||
//includeRate("inNetMessage.timeToDiscard", stats, new long[] { 5*60*1000, 10*60*1000, 60*60*1000 });
|
||||
//includeRate("outNetMessage.timeToDiscard", stats, new long[] { 5*60*1000, 10*60*1000, 60*60*1000 });
|
||||
includeRate("router.throttleNetworkCause", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
includeRate("transport.receiveMessageSize", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("router.throttleNetworkCause", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.receiveMessageSize", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.sendMessageSize", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.sendMessageSmall", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.sendMessageMedium", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
@ -141,6 +142,10 @@ public class StatisticsManager implements Service {
|
||||
//includeRate("transport.receiveMessageMedium", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.receiveMessageLarge", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("client.sendAckTime", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
includeRate("client.sendsPerFailure", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
includeRate("client.timeoutCongestionTunnel", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
includeRate("client.timeoutCongestionMessage", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
includeRate("client.timeoutCongestionInbound", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
stats.setProperty("stat_uptime", DataHelper.formatDuration(_context.router().getUptime()));
|
||||
stats.setProperty("stat__rateKey", "avg;maxAvg;pctLifetime;[sat;satLim;maxSat;maxSatLim;][num;lifetimeFreq;maxFreq]");
|
||||
_log.debug("Publishing peer rankings");
|
||||
@ -266,5 +271,5 @@ public class StatisticsManager implements Service {
|
||||
private final String num(double num) { synchronized (_fmt) { return _fmt.format(num); } }
|
||||
private final String pct(double num) { synchronized (_pct) { return _pct.format(num); } }
|
||||
|
||||
public void renderStatusHTML(OutputStream out) { }
|
||||
public void renderStatusHTML(Writer out) { }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.i2p.router.admin;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.Service;
|
||||
@ -20,7 +20,7 @@ public class AdminManager implements Service {
|
||||
_log = context.logManager().getLog(AdminManager.class);
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) { }
|
||||
public void renderStatusHTML(Writer out) { }
|
||||
|
||||
public void shutdown() {
|
||||
if (_listener != null) {
|
||||
|
@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.Socket;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
@ -47,7 +48,7 @@ class AdminRunner implements Runnable {
|
||||
} else if ( (command.indexOf("routerStats.html") >= 0) || (command.indexOf("oldstats.jsp") >= 0) ) {
|
||||
try {
|
||||
out.write("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n".getBytes());
|
||||
_generator.generateStatsPage(out);
|
||||
_generator.generateStatsPage(new OutputStreamWriter(out));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
@ -61,7 +62,7 @@ class AdminRunner implements Runnable {
|
||||
} else if (true || command.indexOf("routerConsole.html") > 0) {
|
||||
try {
|
||||
out.write("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n".getBytes());
|
||||
_context.router().renderStatusHTML(out);
|
||||
_context.router().renderStatusHTML(new OutputStreamWriter(out));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
|
@ -2,6 +2,7 @@ package net.i2p.router.admin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@ -27,13 +28,13 @@ public class StatsGenerator {
|
||||
_log = context.logManager().getLog(StatsGenerator.class);
|
||||
}
|
||||
|
||||
public void generateStatsPage(OutputStream out) throws IOException {
|
||||
public void generateStatsPage(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(16*1024);
|
||||
buf.append("<h1>Router statistics</h1>");
|
||||
buf.append("<i><a href=\"/oldconsole.jsp\">console</a> | <a href=\"/oldstats.jsp\">stats</a></i><hr />");
|
||||
buf.append("<form action=\"/oldstats.jsp\">");
|
||||
buf.append("<select name=\"go\" onChange='location.href=this.value'>");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
|
||||
Map groups = _context.statManager().getStatsByGroup();
|
||||
@ -50,7 +51,7 @@ public class StatsGenerator {
|
||||
buf.append(stat);
|
||||
buf.append("</option>\n");
|
||||
}
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
buf.append("</select> <input type=\"submit\" value=\"GO\" />");
|
||||
@ -61,7 +62,7 @@ public class StatsGenerator {
|
||||
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<p />");
|
||||
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
|
||||
for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) {
|
||||
@ -73,7 +74,7 @@ public class StatsGenerator {
|
||||
buf.append(group);
|
||||
buf.append("</a></h2>");
|
||||
buf.append("<ul>");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) {
|
||||
String stat = (String)statIter.next();
|
||||
@ -86,10 +87,10 @@ public class StatsGenerator {
|
||||
renderFrequency(stat, buf);
|
||||
else
|
||||
renderRate(stat, buf);
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
out.write("</ul><hr />".getBytes());
|
||||
out.write("</ul><hr />");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router.client;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@ -332,7 +332,7 @@ public class ClientManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(8*1024);
|
||||
buf.append("<u><b>Local destinations</b></u><br />");
|
||||
|
||||
@ -376,7 +376,7 @@ public class ClientManager {
|
||||
}
|
||||
|
||||
buf.append("\n<hr />\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
public void messageReceived(ClientMessage msg) {
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router.client;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
@ -158,7 +158,7 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
if (_manager != null)
|
||||
_manager.renderStatusHTML(out);
|
||||
}
|
||||
|
@ -104,7 +104,11 @@ public class OutboundClientMessageJob extends JobImpl {
|
||||
ctx.statManager().createRateStat("client.sendMessageSize", "How large are messages sent by the client?", "Client Messages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
ctx.statManager().createRateStat("client.sendAttemptAverage", "How many different tunnels do we have to try when sending a client message?", "Client Messages", 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?", "Client Messages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
|
||||
ctx.statManager().createRateStat("client.sendsPerFailure", "How many send attempts do we make when they all fail?", "Client Messages", new long[] { 60*60*1000l, 24*60*60*1000l });
|
||||
ctx.statManager().createRateStat("client.timeoutCongestionTunnel", "How lagged our tunnels are when a send times out?", "Client Messages", new long[] { 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?", "Client Messages", 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?", "Client Messages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
|
||||
long timeoutMs = OVERALL_TIMEOUT_MS_DEFAULT;
|
||||
|
||||
String param = msg.getSenderConfig().getOptions().getProperty(OVERALL_TIMEOUT_MS_PARAM);
|
||||
@ -122,7 +126,7 @@ public class OutboundClientMessageJob extends JobImpl {
|
||||
}
|
||||
|
||||
_overallExpiration = timeoutMs + getContext().clock().now();
|
||||
_status = new OutboundClientMessageStatus(msg);
|
||||
_status = new OutboundClientMessageStatus(ctx, msg);
|
||||
_nextStep = new NextStepJob();
|
||||
_lookupLeaseSetFailed = new LookupLeaseSetFailedJob();
|
||||
_shouldBundle = getShouldBundle();
|
||||
@ -423,6 +427,7 @@ public class OutboundClientMessageJob extends JobImpl {
|
||||
getContext().clientManager().messageDeliveryStatusUpdate(msg.getFromDestination(), msg.getMessageId(), false);
|
||||
getContext().statManager().updateFrequency("client.sendMessageFailFrequency");
|
||||
getContext().statManager().addRateData("client.sendAttemptAverage", _status.getNumSent(), sendTime);
|
||||
getContext().statManager().addRateData("client.sendsPerFailure", _status.getNumSent(), sendTime);
|
||||
}
|
||||
|
||||
/** build the payload clove that will be used for all of the messages, placing the clove in the status structure */
|
||||
@ -455,126 +460,6 @@ public class OutboundClientMessageJob extends JobImpl {
|
||||
_log.debug(getJobId() + ": Built payload clove with id " + clove.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Good ol' fashioned struct with the send status
|
||||
*
|
||||
*/
|
||||
private class OutboundClientMessageStatus {
|
||||
private ClientMessage _msg;
|
||||
private PayloadGarlicConfig _clove;
|
||||
private LeaseSet _leaseSet;
|
||||
private Set _sent;
|
||||
private int _numLookups;
|
||||
private boolean _success;
|
||||
private boolean _failure;
|
||||
private long _start;
|
||||
private int _previousSent;
|
||||
|
||||
public OutboundClientMessageStatus(ClientMessage msg) {
|
||||
_msg = msg;
|
||||
_clove = null;
|
||||
_leaseSet = null;
|
||||
_sent = new HashSet(4);
|
||||
_success = false;
|
||||
_failure = false;
|
||||
_numLookups = 0;
|
||||
_previousSent = 0;
|
||||
_start = getContext().clock().now();
|
||||
}
|
||||
|
||||
/** raw payload */
|
||||
public Payload getPayload() { return _msg.getPayload(); }
|
||||
/** clove, if we've built it */
|
||||
public PayloadGarlicConfig getClove() { return _clove; }
|
||||
public void setClove(PayloadGarlicConfig clove) { _clove = clove; }
|
||||
public ClientMessage getMessage() { return _msg; }
|
||||
/** date we started the process on */
|
||||
public long getStart() { return _start; }
|
||||
|
||||
public int getNumLookups() { return _numLookups; }
|
||||
public void incrementLookups() { _numLookups++; }
|
||||
public void clearAlreadySent() {
|
||||
synchronized (_sent) {
|
||||
_previousSent += _sent.size();
|
||||
_sent.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/** who sent the message? */
|
||||
public Destination getFrom() { return _msg.getFromDestination(); }
|
||||
/** who is the message going to? */
|
||||
public Destination getTo() { return _msg.getDestination(); }
|
||||
/** what is the target's current leaseSet (or null if we don't know yet) */
|
||||
public LeaseSet getLeaseSet() { return _leaseSet; }
|
||||
public void setLeaseSet(LeaseSet ls) { _leaseSet = ls; }
|
||||
/** have we already sent the message down this tunnel? */
|
||||
public boolean alreadySent(Hash gateway, TunnelId tunnelId) {
|
||||
Tunnel t = new Tunnel(gateway, tunnelId);
|
||||
synchronized (_sent) {
|
||||
return _sent.contains(t);
|
||||
}
|
||||
}
|
||||
public void sent(Hash gateway, TunnelId tunnelId) {
|
||||
Tunnel t = new Tunnel(gateway, tunnelId);
|
||||
synchronized (_sent) {
|
||||
_sent.add(t);
|
||||
}
|
||||
}
|
||||
/** how many messages have we sent through various leases? */
|
||||
public int getNumSent() {
|
||||
synchronized (_sent) {
|
||||
return _sent.size() + _previousSent;
|
||||
}
|
||||
}
|
||||
/** did we totally fail? */
|
||||
public boolean getFailure() { return _failure; }
|
||||
/** we failed. returns true if we had already failed before */
|
||||
public boolean failed() {
|
||||
boolean already = _failure;
|
||||
_failure = true;
|
||||
return already;
|
||||
}
|
||||
/** have we totally succeeded? */
|
||||
public boolean getSuccess() { return _success; }
|
||||
/** we succeeded. returns true if we had already succeeded before */
|
||||
public boolean success() {
|
||||
boolean already = _success;
|
||||
_success = true;
|
||||
return already;
|
||||
}
|
||||
|
||||
/** represent a unique tunnel at any given time */
|
||||
private class Tunnel {
|
||||
private Hash _gateway;
|
||||
private TunnelId _tunnel;
|
||||
|
||||
public Tunnel(Hash tunnelGateway, TunnelId tunnel) {
|
||||
_gateway = tunnelGateway;
|
||||
_tunnel = tunnel;
|
||||
}
|
||||
|
||||
public Hash getGateway() { return _gateway; }
|
||||
public TunnelId getTunnel() { return _tunnel; }
|
||||
|
||||
public int hashCode() {
|
||||
int rv = 0;
|
||||
if (_gateway != null)
|
||||
rv += _gateway.hashCode();
|
||||
if (_tunnel != null)
|
||||
rv += 7*_tunnel.getTunnelId();
|
||||
return rv;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) return false;
|
||||
if (o.getClass() != Tunnel.class) return false;
|
||||
Tunnel t = (Tunnel)o;
|
||||
return (getTunnel() == t.getTunnel()) &&
|
||||
getGateway().equals(t.getGateway());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep an eye out for any of the delivery status message tokens that have been
|
||||
* sent down the various tunnels to deliver this message
|
||||
@ -712,6 +597,14 @@ public class OutboundClientMessageJob extends JobImpl {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(OutboundClientMessageJob.this.getJobId()
|
||||
+ ": Soft timeout through the lease " + _lease);
|
||||
|
||||
long messageDelay = getContext().throttle().getMessageDelay();
|
||||
long tunnelLag = getContext().throttle().getTunnelLag();
|
||||
long inboundDelta = (long)getContext().throttle().getInboundRateDelta();
|
||||
getContext().statManager().addRateData("client.timeoutCongestionTunnel", tunnelLag, 1);
|
||||
getContext().statManager().addRateData("client.timeoutCongestionMessage", messageDelay, 1);
|
||||
getContext().statManager().addRateData("client.timeoutCongestionInbound", inboundDelta, 1);
|
||||
|
||||
_lease.setNumFailure(_lease.getNumFailure()+1);
|
||||
sendNext();
|
||||
}
|
||||
|
@ -0,0 +1,133 @@
|
||||
package net.i2p.router.message;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.Payload;
|
||||
import net.i2p.data.TunnelId;
|
||||
import net.i2p.router.ClientMessage;
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
/**
|
||||
* Good ol' fashioned struct with the send status
|
||||
*
|
||||
*/
|
||||
class OutboundClientMessageStatus {
|
||||
private RouterContext _context;
|
||||
private ClientMessage _msg;
|
||||
private PayloadGarlicConfig _clove;
|
||||
private LeaseSet _leaseSet;
|
||||
private Set _sent;
|
||||
private int _numLookups;
|
||||
private boolean _success;
|
||||
private boolean _failure;
|
||||
private long _start;
|
||||
private int _previousSent;
|
||||
|
||||
public OutboundClientMessageStatus(RouterContext ctx, ClientMessage msg) {
|
||||
_context = ctx;
|
||||
_msg = msg;
|
||||
_clove = null;
|
||||
_leaseSet = null;
|
||||
_sent = new HashSet(4);
|
||||
_success = false;
|
||||
_failure = false;
|
||||
_numLookups = 0;
|
||||
_previousSent = 0;
|
||||
_start = ctx.clock().now();
|
||||
}
|
||||
|
||||
/** raw payload */
|
||||
public Payload getPayload() { return _msg.getPayload(); }
|
||||
/** clove, if we've built it */
|
||||
public PayloadGarlicConfig getClove() { return _clove; }
|
||||
public void setClove(PayloadGarlicConfig clove) { _clove = clove; }
|
||||
public ClientMessage getMessage() { return _msg; }
|
||||
/** date we started the process on */
|
||||
public long getStart() { return _start; }
|
||||
|
||||
public int getNumLookups() { return _numLookups; }
|
||||
public void incrementLookups() { _numLookups++; }
|
||||
public void clearAlreadySent() {
|
||||
synchronized (_sent) {
|
||||
_previousSent += _sent.size();
|
||||
_sent.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/** who sent the message? */
|
||||
public Destination getFrom() { return _msg.getFromDestination(); }
|
||||
/** who is the message going to? */
|
||||
public Destination getTo() { return _msg.getDestination(); }
|
||||
/** what is the target's current leaseSet (or null if we don't know yet) */
|
||||
public LeaseSet getLeaseSet() { return _leaseSet; }
|
||||
public void setLeaseSet(LeaseSet ls) { _leaseSet = ls; }
|
||||
/** have we already sent the message down this tunnel? */
|
||||
public boolean alreadySent(Hash gateway, TunnelId tunnelId) {
|
||||
Tunnel t = new Tunnel(gateway, tunnelId);
|
||||
synchronized (_sent) {
|
||||
return _sent.contains(t);
|
||||
}
|
||||
}
|
||||
public void sent(Hash gateway, TunnelId tunnelId) {
|
||||
Tunnel t = new Tunnel(gateway, tunnelId);
|
||||
synchronized (_sent) {
|
||||
_sent.add(t);
|
||||
}
|
||||
}
|
||||
/** how many messages have we sent through various leases? */
|
||||
public int getNumSent() {
|
||||
synchronized (_sent) {
|
||||
return _sent.size() + _previousSent;
|
||||
}
|
||||
}
|
||||
/** did we totally fail? */
|
||||
public boolean getFailure() { return _failure; }
|
||||
/** we failed. returns true if we had already failed before */
|
||||
public boolean failed() {
|
||||
boolean already = _failure;
|
||||
_failure = true;
|
||||
return already;
|
||||
}
|
||||
/** have we totally succeeded? */
|
||||
public boolean getSuccess() { return _success; }
|
||||
/** we succeeded. returns true if we had already succeeded before */
|
||||
public boolean success() {
|
||||
boolean already = _success;
|
||||
_success = true;
|
||||
return already;
|
||||
}
|
||||
|
||||
/** represent a unique tunnel at any given time */
|
||||
private class Tunnel {
|
||||
private Hash _gateway;
|
||||
private TunnelId _tunnel;
|
||||
|
||||
public Tunnel(Hash tunnelGateway, TunnelId tunnel) {
|
||||
_gateway = tunnelGateway;
|
||||
_tunnel = tunnel;
|
||||
}
|
||||
|
||||
public Hash getGateway() { return _gateway; }
|
||||
public TunnelId getTunnel() { return _tunnel; }
|
||||
|
||||
public int hashCode() {
|
||||
int rv = 0;
|
||||
if (_gateway != null)
|
||||
rv += _gateway.hashCode();
|
||||
if (_tunnel != null)
|
||||
rv += 7*_tunnel.getTunnelId();
|
||||
return rv;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) return false;
|
||||
if (o.getClass() != Tunnel.class) return false;
|
||||
Tunnel t = (Tunnel)o;
|
||||
return (getTunnel() == t.getTunnel()) &&
|
||||
getGateway().equals(t.getGateway());
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ package net.i2p.router.networkdb.kademlia;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
@ -810,17 +810,17 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
return routers;
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(10*1024);
|
||||
buf.append("<h2>Kademlia Network DB Contents</h2>\n");
|
||||
if (!_initialized) {
|
||||
buf.append("<i>Not initialized</i>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
return;
|
||||
}
|
||||
Set leases = getLeases();
|
||||
buf.append("<h3>Leases</h3>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
long now = _context.clock().now();
|
||||
for (Iterator iter = leases.iterator(); iter.hasNext(); ) {
|
||||
@ -838,17 +838,17 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
buf.append("</i> tunnelId <i>").append(ls.getLease(i).getTunnelId().getTunnelId()).append("</i><br />\n");
|
||||
}
|
||||
buf.append("<hr />\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
|
||||
Hash us = _context.routerHash();
|
||||
Set routers = getRouters();
|
||||
out.write("<h3>Routers</h3>\n".getBytes());
|
||||
out.write("<h3>Routers</h3>\n");
|
||||
|
||||
RouterInfo ourInfo = _context.router().getRouterInfo();
|
||||
renderRouterInfo(buf, ourInfo, true);
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
|
||||
/* coreVersion to Map of routerVersion to Integer */
|
||||
@ -860,7 +860,7 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
boolean isUs = key.equals(us);
|
||||
if (!isUs) {
|
||||
renderRouterInfo(buf, ri, false);
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
String coreVersion = ri.getOptions().getProperty("coreVersion");
|
||||
String routerVersion = ri.getOptions().getProperty("router.version");
|
||||
@ -895,7 +895,7 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
}
|
||||
buf.append("</table>\n");
|
||||
}
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
private void renderRouterInfo(StringBuffer buf, RouterInfo info, boolean isUs) {
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router.peermanager;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@ -116,7 +116,7 @@ class PeerManager {
|
||||
return new ArrayList(peers);
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
_organizer.renderStatusHTML(out);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router.peermanager;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -59,7 +59,7 @@ public class PeerManagerFacadeImpl implements PeerManagerFacade {
|
||||
return _manager.selectPeers(criteria);
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
_manager.renderStatusHTML(out);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.i2p.router.peermanager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.ArrayList;
|
||||
@ -203,7 +204,7 @@ public class ProfileOrganizer {
|
||||
_persistenceHelper.writeProfile(prof, out);
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
ProfileOrganizerRenderer rend = new ProfileOrganizerRenderer(this, _context);
|
||||
rend.renderStatusHTML(out);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.i2p.router.peermanager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
@ -27,7 +27,7 @@ class ProfileOrganizerRenderer {
|
||||
_context = context;
|
||||
_organizer = organizer;
|
||||
}
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
Set peers = _organizer.selectAllPeers();
|
||||
|
||||
long hideBefore = _context.clock().now() - 3*60*60*1000;
|
||||
@ -126,7 +126,7 @@ class ProfileOrganizerRenderer {
|
||||
buf.append("<b>Speed:</b> ").append(num(_organizer.getSpeedThreshold())).append(" (").append(fast).append(" fast peers)<br />");
|
||||
buf.append("<b>Capacity:</b> ").append(num(_organizer.getCapacityThreshold())).append(" (").append(reliable).append(" high capacity peers)<br />");
|
||||
buf.append("<b>Integration:</b> ").append(num(_organizer.getIntegrationThreshold())).append(" (").append(integrated).append(" well integrated peers)<br />");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
private final static DecimalFormat _fmt = new DecimalFormat("###,##0.00", new DecimalFormatSymbols(Locale.UK));
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.i2p.router.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -407,7 +407,7 @@ public class FIFOBandwidthLimiter {
|
||||
return satisfied;
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
long now = _context.clock().now();
|
||||
StringBuffer buf = new StringBuffer(4096);
|
||||
buf.append("<br /><b>Pending bandwidth requests (with ");
|
||||
@ -436,7 +436,7 @@ public class FIFOBandwidthLimiter {
|
||||
}
|
||||
}
|
||||
buf.append("</ol></li></ul>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
private static long __requestId = 0;
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router.transport;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
@ -275,7 +275,7 @@ public class OutboundMessageRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(8192);
|
||||
buf.append("<h2>Pending messages</h2>\n");
|
||||
Map msgs = null;
|
||||
@ -295,7 +295,7 @@ public class OutboundMessageRegistry {
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
buf.append("</ul>");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,7 +9,7 @@ package net.i2p.router.transport;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -265,7 +265,7 @@ public class TransportManager implements TransportEventListener {
|
||||
return rv;
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(8*1024);
|
||||
buf.append("<h2>Transport Manager</h2>\n");
|
||||
buf.append("Listening on: <br /><pre>\n");
|
||||
@ -283,6 +283,6 @@ public class TransportManager implements TransportEventListener {
|
||||
if (str != null)
|
||||
buf.append(str);
|
||||
}
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.i2p.router.tunnelmanager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -229,7 +229,7 @@ public class PoolingTunnelManagerFacade implements TunnelManagerFacade {
|
||||
* Aint she pretty?
|
||||
*
|
||||
*/
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
if (_pool != null)
|
||||
_pool.renderStatusHTML(out);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.i2p.router.tunnelmanager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -66,7 +66,8 @@ class TunnelPool {
|
||||
_context.statManager().createRateStat("tunnel.inboundMessagesProcessed", "How many messages does an inbound tunnel process in its lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
_context.statManager().createRateStat("tunnel.outboundMessagesProcessed", "How many messages does an inbound tunnel process in its lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
_context.statManager().createRateStat("tunnel.participatingMessagesProcessed", "How many messages does an inbound tunnel process in its lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
|
||||
_context.statManager().createRateStat("tunnel.participatingMessagesProcessedActive", "How many messages beyond the average were processed in a more-than-average tunnel's lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
|
||||
_isLive = true;
|
||||
_persistenceHelper = new TunnelPoolPersistenceHelper(_context);
|
||||
_tunnelBuilder = new TunnelBuilder(_context);
|
||||
@ -603,8 +604,8 @@ class TunnelPool {
|
||||
|
||||
public void shutdown() {
|
||||
if (_log.shouldLog(Log.INFO)) _log.info("Shutting down tunnel pool");
|
||||
if (_persistenceHelper != null)
|
||||
_persistenceHelper.writePool(this);
|
||||
//if (_persistenceHelper != null)
|
||||
// _persistenceHelper.writePool(this);
|
||||
_isLive = false; // the subjobs [should] check getIsLive() on each run
|
||||
_outboundTunnels = null;
|
||||
_freeInboundTunnels = null;
|
||||
@ -633,10 +634,17 @@ class TunnelPool {
|
||||
info.getSettings().getCreated());
|
||||
break;
|
||||
case TunnelId.TYPE_PARTICIPANT:
|
||||
long numMsgs = info.getMessagesProcessed();
|
||||
long lastAvg = (long)_context.statManager().getRate("tunnel.participatingMessagesProcessed").getRate(10*60*1000l).getAverageValue();
|
||||
_context.statManager().addRateData("tunnel.participatingMessagesProcessed",
|
||||
info.getMessagesProcessed(),
|
||||
numMsgs,
|
||||
info.getSettings().getExpiration() -
|
||||
info.getSettings().getCreated());
|
||||
if (numMsgs > lastAvg)
|
||||
_context.statManager().addRateData("tunnel.participatingMessagesProcessedActive",
|
||||
numMsgs-lastAvg,
|
||||
info.getSettings().getExpiration() -
|
||||
info.getSettings().getCreated());
|
||||
break;
|
||||
case TunnelId.TYPE_UNSPECIFIED:
|
||||
default:
|
||||
@ -651,9 +659,9 @@ class TunnelPool {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
if (!_isLive) return;
|
||||
out.write("<h2>Tunnel Pool</h2>\n".getBytes());
|
||||
out.write("<h2>Tunnel Pool</h2>\n");
|
||||
StringBuffer buf = new StringBuffer(4096);
|
||||
renderTunnels(out, buf, "Free inbound tunnels", getFreeTunnels());
|
||||
renderTunnels(out, buf, "Outbound tunnels", getOutboundTunnels());
|
||||
@ -665,19 +673,19 @@ class TunnelPool {
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTunnels(OutputStream out, StringBuffer buf, String msg, Set tunnelIds) throws IOException {
|
||||
private void renderTunnels(Writer out, StringBuffer buf, String msg, Set tunnelIds) throws IOException {
|
||||
buf.append("<b>").append(msg).append(":</b> <i>(").append(tunnelIds.size()).append(" tunnels)</i><ul>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
for (Iterator iter = tunnelIds.iterator(); iter.hasNext(); ) {
|
||||
TunnelId id = (TunnelId)iter.next();
|
||||
TunnelInfo tunnel = getTunnelInfo(id);
|
||||
renderTunnel(out, buf, id, tunnel);
|
||||
}
|
||||
out.write("</ul>\n".getBytes());
|
||||
out.write("</ul>\n");
|
||||
}
|
||||
|
||||
private final void renderTunnel(OutputStream out, StringBuffer buf, TunnelId id, TunnelInfo tunnel) throws IOException {
|
||||
private final void renderTunnel(Writer out, StringBuffer buf, TunnelId id, TunnelInfo tunnel) throws IOException {
|
||||
buf.setLength(0);
|
||||
if (tunnel == null) {
|
||||
buf.append("<li>Tunnel: ").append(id.getTunnelId()).append(" is not known</li>\n");
|
||||
@ -713,7 +721,7 @@ class TunnelPool {
|
||||
|
||||
buf.append("\n</pre>");
|
||||
}
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user