Console: Add links to bandwidth graphs on /tunnels

This commit is contained in:
zzz
2018-04-16 14:34:41 +00:00
parent b9bc254fd3
commit d189c3912c
2 changed files with 67 additions and 12 deletions

View File

@@ -21,6 +21,7 @@ import net.i2p.router.tunnel.HopConfig;
import net.i2p.router.tunnel.pool.TunnelPool;
import net.i2p.router.web.HelperBase;
import net.i2p.router.web.Messages;
import net.i2p.stat.Rate;
import net.i2p.stat.RateStat;
/**
@@ -36,8 +37,14 @@ class TunnelRenderer {
}
public void renderStatusHTML(Writer out) throws IOException {
out.write("<h3 class=\"tabletitle\" id=\"exploratorytunnels\"><a name=\"exploratory\" ></a>" + _t("Exploratory tunnels") + " <a href=\"/configtunnels#exploratory\" title=\"" + _t("Configure tunnels") + "\">[" + _t("configure") + "]</a></h3>\n");
renderPool(out, _context.tunnelManager().getInboundExploratoryPool(), _context.tunnelManager().getOutboundExploratoryPool());
TunnelPool ei = _context.tunnelManager().getInboundExploratoryPool();
TunnelPool eo = _context.tunnelManager().getOutboundExploratoryPool();
out.write("<h3 class=\"tabletitle\" id=\"exploratorytunnels\"><a name=\"exploratory\" ></a>" + _t("Exploratory tunnels"));
// links are set to float:right in CSS so they will be displayed in reverse order
out.write(" <a href=\"/configtunnels#exploratory\" title=\"" + _t("Configure tunnels") + "\">[" + _t("configure") + "]</a>");
writeGraphLinks(out, ei, eo);
out.write("</h3>\n");
renderPool(out, ei, eo);
List<Hash> destinations = null;
Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
@@ -64,10 +71,14 @@ class TunnelRenderer {
name = client.toBase64().substring(0,4);
out.write("<h3 class=\"tabletitle\" id=\"" + client.toBase64().substring(0,4)
+ "\" >" + _t("Client tunnels for") + ' ' + DataHelper.escapeHTML(_t(name)));
if (isLocal)
out.write(" <a href=\"/configtunnels#" + client.toBase64().substring(0,4) +"\" title=\"" + _t("Configure tunnels for session") + "\">[" + _t("configure") + "]</a></h3>\n");
else
if (isLocal) {
// links are set to float:right in CSS so they will be displayed in reverse order
out.write(" <a href=\"/configtunnels#" + client.toBase64().substring(0,4) +"\" title=\"" + _t("Configure tunnels for session") + "\">[" + _t("configure") + "]</a>");
writeGraphLinks(out, in, outPool);
out.write("</h3>\n");
} else {
out.write(" (" + _t("dead") + ")</h3>\n");
}
if (in != null) {
// list aliases
Set<Hash> aliases = in.getSettings().getAliases();
@@ -167,7 +178,7 @@ class TunnelRenderer {
else if (displayed <= 0)
out.write("<div class=\"statusnotes\"><b>" + _t("none") + "</b></div>\n");
out.write("<div class=\"statusnotes\"><b>" + _t("Lifetime bandwidth usage") + ":&nbsp;&nbsp;" + DataHelper.formatSize2Decimal(processed*1024) + "B</b></div>\n");
} else {
} else { // bwShare > 12
out.write("<div class=\"statusnotes noparticipate\"><b>" + _t("Not enough shared bandwidth to build participating tunnels.") +
"</b> <a href=\"config\">[" + _t("Configure") + "]</a></div>\n");
}
@@ -202,6 +213,39 @@ class TunnelRenderer {
}
}
/** @since 0.9.35 */
private void writeGraphLinks(Writer out, TunnelPool in, TunnelPool outPool) throws IOException {
if (in == null || outPool == null)
return;
String irname = in.getRateName();
String orname = outPool.getRateName();
RateStat irs = _context.statManager().getRate(irname);
RateStat ors = _context.statManager().getRate(orname);
if (irs == null || ors == null)
return;
Rate ir = irs.getRate(5*60*1000L);
Rate or = ors.getRate(5*60*1000L);
if (ir == null || or == null)
return;
final String tgd = _t("Graph Data");
final String tcg = _t("Configure Graph Display");
// links are set to float:right in CSS so they will be displayed in reverse order
if (or.getSummaryListener() != null) {
out.write("<a href=\"graph?stat=" + orname + ".300000&amp;w=600&amp;h=200\">" +
"<img src=\"/themes/console/images/outbound.png\" alt=\"" + tgd + "\" title=\"" + tgd + "\"></a>");
} else {
out.write("<a href=\"configstats#" + orname + "\">" +
"<img src=\"/themes/console/images/outbound.png\" alt=\"" + tcg + "\" title=\"" + tcg + "\"></a>");
}
if (ir.getSummaryListener() != null) {
out.write("<a href=\"graph?stat=" + irname + ".300000&amp;w=600&amp;h=200\">" +
"<img src=\"/themes/console/images/inbound.png\" alt=\"" + tgd + "\" title=\"" + tgd + "\"></a> ");
} else {
out.write("<a href=\"configstats#" + irname + "\">" +
"<img src=\"/themes/console/images/inbound.png\" alt=\"" + tcg + "\" title=\"" + tcg + "\"></a>");
}
}
private void renderPool(Writer out, TunnelPool in, TunnelPool outPool) throws IOException {
List<TunnelInfo> tunnels = null;
if (in == null)
@@ -235,6 +279,8 @@ class TunnelRenderer {
out.write("<th>" + _t("Endpoint") + "</th>");
}
out.write("</tr>\n");
final String tib = _t("Inbound");
final String tob = _t("Outbound");
for (int i = 0; i < tunnels.size(); i++) {
TunnelInfo info = tunnels.get(i);
long timeLeft = info.getExpiration()-_context.clock().now();
@@ -243,11 +289,11 @@ class TunnelRenderer {
live++;
boolean isInbound = info.isInbound();
if (isInbound)
out.write("<tr><td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/inbound.png\" alt=\"Inbound\" title=\"" +
_t("Inbound") + "\"></td>");
out.write("<tr><td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/inbound.png\" alt=\"" + tib + "\" title=\"" +
tib + "\"></td>");
else
out.write("<tr><td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/outbound.png\" alt=\"Outbound\" title=\"" +
_t("Outbound") + "\"></td>");
out.write("<tr><td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/outbound.png\" alt=\"" + tob + "\" title=\"" +
tob + "\"></td>");
out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatDuration2(timeLeft) + "</td>\n");
int count = info.getProcessedMessagesCount() * 1024 / 1000;
out.write("<td class=\"cells\" align=\"center\">" + count + " KB</td>\n");
@@ -293,7 +339,7 @@ class TunnelRenderer {
// PooledTunnelCreatorConfig
List<?> pending = in.listPending();
if (!pending.isEmpty()) {
out.write("<div class=\"statusnotes\"><center><b>" + _t("Build in progress") + ":&nbsp;&nbsp;" + pending.size() + " " + _t("inbound") + "</b></center></div>\n");
out.write("<div class=\"statusnotes\"><center><b>" + _t("Build in progress") + ":&nbsp;&nbsp;" + pending.size() + " " + tib + "</b></center></div>\n");
live += pending.size();
}
}
@@ -301,7 +347,7 @@ class TunnelRenderer {
// PooledTunnelCreatorConfig
List<?> pending = outPool.listPending();
if (!pending.isEmpty()) {
out.write("<div class=\"statusnotes\"><center><b>" + _t("Build in progress") + ":&nbsp;&nbsp;" + pending.size() + " " + _t("outbound") + "</b></center></div>\n");
out.write("<div class=\"statusnotes\"><center><b>" + _t("Build in progress") + ":&nbsp;&nbsp;" + pending.size() + " " + tob + "</b></center></div>\n");
live += pending.size();
}
}

View File

@@ -130,6 +130,15 @@ public class TunnelPool {
}
}
/**
* RateStat name for the bandwidth graph
* @return non-null
* @since 0.9.35
*/
public String getRateName() {
return _rateName;
}
private void refreshSettings() {
if (!_settings.isExploratory())
return; // don't override client specified settings