expose some data points for the new console, and cleaned up some html

new piece of data exposed and maintained is a list of router contexts - shown as a singleton off RouterContext - allowing an app in the same JVM to find the routers (and chose between which one they want)
This commit is contained in:
jrandom
2004-07-23 17:36:29 +00:00
committed by zzz
parent 69981e4d78
commit 9f4439583d
7 changed files with 114 additions and 37 deletions

View File

@ -491,6 +491,7 @@ public class Router {
try { _context.messageRegistry().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the message registry", t); }
try { _context.messageValidator().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the message validator", t); }
try { _sessionKeyPersistenceHelper.shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the session key manager", t); }
_context.listContexts().remove(_context);
dumpStats();
_log.log(Log.CRIT, "Shutdown complete", new Exception("Shutdown"));
try { _context.logManager().shutdown(); } catch (Throwable t) { }

View File

@ -1,5 +1,7 @@
package net.i2p.router;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import net.i2p.I2PAppContext;
@ -57,11 +59,14 @@ public class RouterContext extends I2PAppContext {
private Calculator _reliabilityCalc;
private Calculator _capacityCalc;
private static List _contexts = new ArrayList(1);
public RouterContext(Router router) { this(router, null); }
public RouterContext(Router router, Properties envProps) {
super(envProps);
_router = router;
initAll();
_contexts.add(this);
}
private void initAll() {
_clientManagerFacade = new ClientManagerFacadeImpl(this);
@ -94,6 +99,15 @@ public class RouterContext extends I2PAppContext {
_capacityCalc = new CapacityCalculator(this);
}
/**
* Retrieve the list of router contexts currently instantiated in this JVM.
* This will always contain only one item (except when a simulation per the
* MultiRouter is going on), and the list should only be modified when a new
* context is created or a router is shut down.
*
*/
public static List listContexts() { return _contexts; }
/** what router is this context working for? */
public Router router() { return _router; }
/** convenience method for querying the router's ident */

View File

@ -38,6 +38,12 @@ public class Shitlist {
_shitlist = new HashMap(100);
}
public int getRouterCount() {
synchronized (_shitlist) {
return _shitlist.size();
}
}
public boolean shitlistRouter(Hash peer) {
if (peer == null) return false;
if (_context.routerHash().equals(peer)) {

View File

@ -63,4 +63,8 @@ public interface TunnelManagerFacade extends Service {
/** how many tunnels are we participating in? */
public int getParticipatingCount();
/** how many free inbound tunnels do we have available? */
public int getFreeTunnelCount();
/** how many outbound tunnels do we have available? */
public int getOutboundTunnelCount();
}

View File

@ -21,10 +21,12 @@ import java.util.Map;
import java.util.Set;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.DataStructure;
import net.i2p.data.Hash;
import net.i2p.data.Lease;
import net.i2p.data.LeaseSet;
import net.i2p.data.RouterAddress;
import net.i2p.data.RouterInfo;
import net.i2p.data.i2np.DatabaseLookupMessage;
import net.i2p.data.i2np.DatabaseSearchReplyMessage;
@ -616,51 +618,73 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
}
Set leases = getLeases();
buf.append("<h3>Leases</h3>\n");
buf.append("<table border=\"1\">\n");
out.write(buf.toString().getBytes());
buf.setLength(0);
long now = _context.clock().now();
for (Iterator iter = leases.iterator(); iter.hasNext(); ) {
LeaseSet ls = (LeaseSet)iter.next();
Hash key = ls.getDestination().calculateHash();
buf.append("<tr><td valign=\"top\" align=\"left\"><b>").append(key.toBase64()).append("</b></td>");
if (getLastSent(key).longValue() > 0)
buf.append("<td valign=\"top\" align=\"left\"><b>Last sent successfully:</b> ").append(new Date(getLastSent(key).longValue())).append("</td></tr>");
else
buf.append("<td valign=\"top\" align=\"left\"><b>Last sent successfully:</b> never</td></tr>");
buf.append("<tr><td valign=\"top\" align=\"left\" colspan=\"2\"><pre>\n").append(ls.toString()).append("</pre></td></tr>\n");
buf.append("<b>LeaseSet: ").append(key.toBase64()).append("</b><br />\n");
long exp = ls.getEarliestLeaseDate()-now;
buf.append("Earliest expiration date in: <i>").append(DataHelper.formatDuration(exp)).append("</i><br />\n");
for (int i = 0; i < ls.getLeaseCount(); i++) {
buf.append("Lease ").append(i).append(": gateway <i>");
buf.append(ls.getLease(i).getRouterIdentity().getHash().toBase64().substring(0,6));
buf.append("</i> tunnelId <i>").append(ls.getLease(i).getTunnelId().getTunnelId()).append("</i><br />\n");
}
buf.append("<hr />\n");
out.write(buf.toString().getBytes());
buf.setLength(0);
}
buf.append("</table>\n");
Hash us = _context.routerHash();
Set routers = getRouters();
buf.append("<h3>Routers</h3>\n");
buf.append("<table border=\"1\">\n");
out.write("<h3>Routers</h3>\n".getBytes());
RouterInfo ourInfo = _context.router().getRouterInfo();
renderRouterInfo(buf, ourInfo, true);
out.write(buf.toString().getBytes());
buf.setLength(0);
for (Iterator iter = routers.iterator(); iter.hasNext(); ) {
RouterInfo ri = (RouterInfo)iter.next();
Hash key = ri.getIdentity().getHash();
boolean isUs = key.equals(us);
if (isUs) {
buf.append("<tr><td valign=\"top\" align=\"left\"><font color=\"red\"><b>").append(key.toBase64()).append("</b></font></td>");
buf.append("<td valign=\"top\" align=\"left\" colspan=\"2\"><b>Last sent successfully:</b> ").append(new Date(getLastSent(key).longValue())).append("</td></tr>");
} else {
buf.append("<tr><td valign=\"top\" align=\"left\"><a name=\"").append(key.toBase64().substring(0,32)).append("\"><b>").append(key.toBase64()).append("</b></a></td>");
if (getLastSent(key).longValue() > 0)
buf.append("<td valign=\"top\" align=\"left\"><b>Last sent successfully:</b> ").append(new Date(getLastSent(key).longValue())).append("</td>");
else
buf.append("<td valign=\"top\" align=\"left\"><b>Last sent successfully:</b> never</td>");
buf.append("<td valign=\"top\" align=\"left\"><a href=\"/profile/").append(key.toBase64().substring(0, 32)).append("\">Profile</a></td></tr>");
}
buf.append("<tr><td valign=\"top\" align=\"left\" colspan=\"3\"><pre>\n").append(ri.toString()).append("</pre></td></tr>\n");
if (!isUs) {
renderRouterInfo(buf, ri, false);
out.write(buf.toString().getBytes());
buf.setLength(0);
}
out.write("</table>\n".getBytes());
}
}
private void renderRouterInfo(StringBuffer buf, RouterInfo info, boolean isUs) {
if (isUs) {
buf.append("<b>Our info: </b><br />\n");
} else {
String hash = info.getIdentity().getHash().toBase64();
buf.append("<a name=\"").append(hash.substring(0, 6)).append("\" />");
buf.append("<b>Peer info for:</b> ").append(hash).append("<br />\n");
}
long age = _context.clock().now() - info.getPublished();
buf.append("Published: <i>").append(DataHelper.formatDuration(age)).append(" ago</i><br />\n");
buf.append("Address(es): <i>");
for (Iterator iter = info.getAddresses().iterator(); iter.hasNext(); ) {
RouterAddress addr = (RouterAddress)iter.next();
buf.append(addr.getTransportStyle()).append(": ");
for (Iterator optIter = addr.getOptions().keySet().iterator(); optIter.hasNext(); ) {
String name = (String)optIter.next();
String val = addr.getOptions().getProperty(name);
buf.append('[').append(name).append('=').append(val).append("] ");
}
}
buf.append("</i><br />\n");
buf.append("Stats: <br /><i><code>\n");
for (Iterator iter = info.getOptions().keySet().iterator(); iter.hasNext(); ) {
String key = (String)iter.next();
String val = info.getOptions().getProperty(key);
buf.append(key).append(" = ").append(val).append("<br />\n");
}
buf.append("</code></i><hr />\n");
}
}

View File

@ -167,6 +167,31 @@ public class ProfileOrganizer {
public int countNotFailingPeers() { synchronized (_reorganizeLock) { return _notFailingPeers.size(); } }
public int countFailingPeers() { synchronized (_reorganizeLock) { return _failingPeers.size(); } }
public int countActivePeers() {
synchronized (_reorganizeLock) {
int activePeers = 0;
long hideBefore = _context.clock().now() - 6*60*60*1000;
for (Iterator iter = _failingPeers.values().iterator(); iter.hasNext(); ) {
PeerProfile profile = (PeerProfile)iter.next();
if (profile.getLastSendSuccessful() >= hideBefore)
activePeers++;
else if (profile.getLastHeardFrom() >= hideBefore)
activePeers++;
}
for (Iterator iter = _notFailingPeers.values().iterator(); iter.hasNext(); ) {
PeerProfile profile = (PeerProfile)iter.next();
if (profile.getLastSendSuccessful() >= hideBefore)
activePeers++;
else if (profile.getLastHeardFrom() >= hideBefore)
activePeers++;
}
return activePeers;
}
}
public boolean isFast(Hash peer) { synchronized (_reorganizeLock) { return _fastPeers.containsKey(peer); } }
public boolean isHighCapacity(Hash peer) { synchronized (_reorganizeLock) { return _highCapacityPeers.containsKey(peer); } }
public boolean isWellIntegrated(Hash peer) { synchronized (_reorganizeLock) { return _wellIntegratedPeers.containsKey(peer); } }
@ -628,14 +653,13 @@ public class ProfileOrganizer {
buf.append("<h2>Peer Profiles</h2>\n");
buf.append("<table border=\"1\">");
buf.append("<tr>");
buf.append("<td><b>Peer</b> (").append(order.size()).append(", hiding ").append(peers.size()-order.size()).append(" inactive ones)</td>");
buf.append("<td><b>Peer</b> (").append(order.size()).append(", hiding ").append(peers.size()-order.size()).append(")</td>");
buf.append("<td><b>Groups</b></td>");
buf.append("<td><b>Speed</b></td>");
buf.append("<td><b>Capacity</b></td>");
buf.append("<td><b>Integration</b></td>");
buf.append("<td><b>Failing?</b></td>");
buf.append("<td><b>Reliability (deprecated)</b></td>");
buf.append("<td><b>Profile data</b></td>");
//buf.append("<td><b>Profile data</b></td>");
buf.append("</tr>");
for (Iterator iter = order.keySet().iterator(); iter.hasNext();) {
String name = (String)iter.next();
@ -645,10 +669,10 @@ public class ProfileOrganizer {
buf.append("<tr>");
buf.append("<td><code>");
if (prof.getIsFailing()) {
buf.append("<font color=\"red\">--").append(peer.toBase64()).append("</font>");
buf.append("<font color=\"red\">--").append(peer.toBase64().substring(0,6)).append("</font>");
} else {
if (prof.getIsActive()) {
buf.append("<font color=\"blue\">++").append(peer.toBase64()).append("</font>");
buf.append("<font color=\"blue\">++").append(peer.toBase64().substring(0,6)).append("</font>");
} else {
buf.append("__").append(peer.toBase64());
}
@ -678,20 +702,19 @@ public class ProfileOrganizer {
}
switch (tier) {
case 1: buf.append("Fast+High Capacity"); break;
case 1: buf.append("Fast"); break;
case 2: buf.append("High Capacity"); break;
case 3: buf.append("Not Failing"); break;
default: buf.append("Failing"); break;
}
if (isIntegrated) buf.append(", Well integrated");
if (isIntegrated) buf.append(", Integrated");
buf.append("<td align=\"right\">").append(num(prof.getSpeedValue())).append("</td>");
buf.append("<td align=\"right\">").append(num(prof.getCapacityValue())).append("</td>");
buf.append("<td align=\"right\">").append(num(prof.getIntegrationValue())).append("</td>");
buf.append("<td align=\"right\">").append(prof.getIsFailing()).append("</td>");
buf.append("<td align=\"right\">").append(num(prof.getReliabilityValue())).append("</td>");
buf.append("<td><a href=\"/profile/").append(prof.getPeer().toBase64().substring(0, 32)).append("\">profile.txt</a> ");
buf.append(" <a href=\"#").append(prof.getPeer().toBase64().substring(0, 32)).append("\">netDb</a></td>");
//buf.append("<td><a href=\"/profile/").append(prof.getPeer().toBase64().substring(0, 32)).append("\">profile.txt</a> ");
//buf.append(" <a href=\"#").append(prof.getPeer().toBase64().substring(0, 32)).append("\">netDb</a></td>");
buf.append("</tr>");
}
buf.append("</table>");
@ -700,7 +723,6 @@ public class ProfileOrganizer {
buf.append("<li><b>capacity</b>: how many tunnels can we ask them to join in an hour?</li>");
buf.append("<li><b>integration</b>: how many new peers have they told us about lately?</li>");
buf.append("<li><b>failing?</b>: is the peer currently swamped (and if possible we should avoid nagging them)?</li>");
buf.append("<li><b>reliability</b>: no sound semantics... just a random kludge of a value.</li>");
buf.append("</ul></i>");
buf.append("Red peers prefixed with '--' means the peer is failing, and blue peers prefixed ");
buf.append("with '++' means we've sent or received a message from them ");

View File

@ -212,6 +212,12 @@ public class PoolingTunnelManagerFacade implements TunnelManagerFacade {
public int getParticipatingCount() {
return _pool.getParticipatingTunnelCount();
}
public int getFreeTunnelCount() {
return _pool.getFreeTunnelCount();
}
public int getOutboundTunnelCount() {
return _pool.getOutboundTunnelCount();
}
/**
* Aint she pretty?