diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHandler.java index 0deb159294..8d21fd63ef 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHandler.java @@ -104,14 +104,21 @@ public class ConfigStatsHandler extends FormHandler { } _context.router().setConfigSetting(StatManager.PROP_STAT_FILTER, stats.toString()); + boolean graphsChanged = !_graphs.equals(_context.getProperty("stat.summaries")); _context.router().setConfigSetting("stat.summaries", _graphs); + boolean fullChanged = _context.getBooleanProperty(StatManager.PROP_STAT_FULL) != _isFull; _context.router().setConfigSetting(StatManager.PROP_STAT_FULL, "" + _isFull); - boolean ok = _context.router().saveConfig(); - if (ok) + _context.router().saveConfig(); + if (!_stats.isEmpty()) addFormNotice(_("Stat filter and location updated successfully to") + ": " + stats.toString()); - else - addFormError(_("Failed to update the stat filter and location")); - addFormNotice(_("Graph list updated, may take up to 60s to be reflected here and on the Graphs Page")); + if (fullChanged) { + if (_isFull) + addFormNotice(_("Full statistics enabled - restart required to take effect")); + else + addFormNotice(_("Full statistics disabled - restart required to take effect")); + } + if (graphsChanged) + addFormNotice(_("Graph list updated, may take up to 60s to be reflected here and on the Graphs Page")); } } 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 d08bdc3a03..431696296e 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java @@ -258,7 +258,7 @@ public class StatSummarizer implements Runnable { if (txLsnr == null || rxLsnr == null) throw new IOException("no rates for combined graph"); - long end = _context.clock().now() - 60*1000; + long end = _context.clock().now() - 75*1000; if (width > GraphHelper.MAX_X) width = GraphHelper.MAX_X; else if (width <= 0) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java index 0d9693c2b0..ba7ee6fb18 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java @@ -83,7 +83,7 @@ class SummaryRenderer { false, false, false, false, -1, false); } 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() - 60*1000; + long end = _listener.now() - 75*1000; if (periodCount <= 0 || periodCount > _listener.getRows()) periodCount = _listener.getRows(); long start = end - _listener.getRate().getPeriod()*periodCount; diff --git a/apps/routerconsole/jsp/viewstat.jsp b/apps/routerconsole/jsp/viewstat.jsp index fb57b2173f..ccb832874c 100644 --- a/apps/routerconsole/jsp/viewstat.jsp +++ b/apps/routerconsole/jsp/viewstat.jsp @@ -42,6 +42,8 @@ if ( !rendered && ((rs != null) || fakeBw) ) { } } else { response.setContentType("image/png"); + // very brief 45 sec expire + response.setDateHeader("Expires", net.i2p.I2PAppContext.getGlobalContext().clock().now() + (45*1000)); int width = -1; int height = -1; int periodCount = -1; @@ -80,4 +82,4 @@ if (!rendered) { else response.sendError(403, "No stat specified"); } -%> \ No newline at end of file +%> diff --git a/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java b/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java index 849090f458..195b892b1d 100644 --- a/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java +++ b/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java @@ -38,8 +38,8 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl for (int i = 0; i < _bufferCount; i++) status[i] = STATUS_NEED_FILL; _context = context; - context.statManager().createRateStat("prng.bufferWaitTime", "", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } ); - context.statManager().createRateStat("prng.bufferFillTime", "", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } ); + context.statManager().createRequiredRateStat("prng.bufferWaitTime", "Delay for random number buffer (ms)", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } ); + context.statManager().createRequiredRateStat("prng.bufferFillTime", "Time to fill random number buffer (ms)", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } ); _log = context.logManager().getLog(AsyncFortunaStandalone.class); } diff --git a/core/java/src/net/i2p/crypto/ElGamalEngine.java b/core/java/src/net/i2p/crypto/ElGamalEngine.java index b311d3c079..29f5df35a0 100644 --- a/core/java/src/net/i2p/crypto/ElGamalEngine.java +++ b/core/java/src/net/i2p/crypto/ElGamalEngine.java @@ -64,11 +64,11 @@ public class ElGamalEngine { * */ public ElGamalEngine(I2PAppContext context) { - context.statManager().createRateStat("crypto.elGamal.encrypt", - "how long does it take to do a full ElGamal encryption", "Encryption", + context.statManager().createRequiredRateStat("crypto.elGamal.encrypt", + "Time for ElGamal encryption (ms)", "Encryption", new long[] { 60 * 60 * 1000}); - context.statManager().createRateStat("crypto.elGamal.decrypt", - "how long does it take to do a full ElGamal decryption", "Encryption", + context.statManager().createRequiredRateStat("crypto.elGamal.decrypt", + "Time for ElGamal decryption (ms)", "Encryption", new long[] { 60 * 60 * 1000}); _context = context; _log = context.logManager().getLog(ElGamalEngine.class); diff --git a/core/java/src/net/i2p/stat/StatManager.java b/core/java/src/net/i2p/stat/StatManager.java index 868e18402a..55bc234c21 100644 --- a/core/java/src/net/i2p/stat/StatManager.java +++ b/core/java/src/net/i2p/stat/StatManager.java @@ -21,8 +21,8 @@ import net.i2p.util.Log; * */ public class StatManager { - private Log _log; - private I2PAppContext _context; + private final Log _log; + private final I2PAppContext _context; /** stat name to FrequencyStat */ private final ConcurrentHashMap _frequencyStats; @@ -39,28 +39,8 @@ public class StatManager { public static final String PROP_STAT_FILTER = "stat.logFilters"; public static final String PROP_STAT_FILE = "stat.logFile"; public static final String DEFAULT_STAT_FILE = "stats.log"; - /** default true */ + /** default false */ public static final String PROP_STAT_FULL = "stat.full"; - public static final String PROP_STAT_REQUIRED = "stat.required"; - /** - * These are all the stats published in netDb, plus those required for the operation of - * the router (many in RouterThrottleImpl), plus those that are on graphs.jsp by default, - * plus those used on the summary bar (SummaryHelper.java). - * Wildcard ('*') allowed at end of stat only. - * Ignore all the rest of the stats unless stat.full=true. - */ - public static final String DEFAULT_STAT_REQUIRED = - "bw.recvRate,bw.sendBps,bw.sendRate,client.sendAckTime,clock.skew,crypto.elGamal.encrypt," + - "jobQueue.jobLag,netDb.successTime,peer.failedLookupRate,router.fastPeers," + - "prng.bufferFillTime,prng.bufferWaitTime,router.memoryUsed," + - "transport.receiveMessageSize,transport.sendMessageSize,transport.sendProcessingTime," + - "tunnel.acceptLoad,tunnel.buildRequestTime,tunnel.rejectOverloaded,tunnel.rejectTimeout," + - "tunnel.buildClientExpire,tunnel.buildClientReject,tunnel.buildClientSuccess," + - "tunnel.buildExploratoryExpire,tunnel.buildExploratoryReject,tunnel.buildExploratorySuccess," + - "tunnel.buildRatio.*,tunnel.corruptMessage,tunnel.dropLoad*," + - "tunnel.decryptRequestTime,tunnel.fragmentedDropped,tunnel.participatingMessageCount,"+ - "tunnel.participatingTunnels,tunnel.testFailedTime,tunnel.testSuccessTime," + - "tunnel.participatingBandwidth,udp.sendPacketSize,udp.packetsRetransmitted,udp.sendException" ; /** * The stat manager should only be constructed and accessed through the @@ -89,6 +69,7 @@ public class StatManager { /** * Create a new statistic to monitor the frequency of some event. + * The stat is ONLY created if the stat.full property is true or we are not in the router context. * * @param name unique name of the statistic * @param description simple description of the statistic @@ -97,12 +78,27 @@ public class StatManager { */ public void createFrequencyStat(String name, String description, String group, long periods[]) { if (ignoreStat(name)) return; + createRequiredFrequencyStat(name, description, group, periods); + } + + /** + * Create a new statistic to monitor the frequency of some event. + * The stat is always created, independent of the stat.full setting or context. + * + * @param name unique name of the statistic + * @param description simple description of the statistic + * @param group used to group statistics together + * @param periods array of period lengths (in milliseconds) + * @since 0.8.6 + */ + public void createRequiredFrequencyStat(String name, String description, String group, long periods[]) { if (_frequencyStats.containsKey(name)) return; _frequencyStats.putIfAbsent(name, new FrequencyStat(name, description, group, periods)); } /** * Create a new statistic to monitor the average value and confidence of some action. + * The stat is ONLY created if the stat.full property is true or we are not in the router context. * * @param name unique name of the statistic * @param description simple description of the statistic @@ -111,6 +107,20 @@ public class StatManager { */ public void createRateStat(String name, String description, String group, long periods[]) { if (ignoreStat(name)) return; + createRequiredRateStat(name, description, group, periods); + } + + /** + * Create a new statistic to monitor the average value and confidence of some action. + * The stat is always created, independent of the stat.full setting or context. + * + * @param name unique name of the statistic + * @param description simple description of the statistic + * @param group used to group statistics together + * @param periods array of period lengths (in milliseconds) + * @since 0.8.6 + */ + public void createRequiredRateStat(String name, String description, String group, long periods[]) { if (_rateStats.containsKey(name)) return; RateStat rs = new RateStat(name, description, group, periods); if (_statLog != null) rs.setStatLog(_statLog); @@ -202,20 +212,13 @@ public class StatManager { public String getStatFile() { return _context.getProperty(PROP_STAT_FILE, DEFAULT_STAT_FILE); } /** - * Save memory by not creating stats unless they are required for router operation + * Save memory by not creating stats unless they are required for router operation. + * For backward compatibility of any external clients, always returns false if not in router context. + * + * @param statName ignored * @return true if the stat should be ignored. */ public boolean ignoreStat(String statName) { - if (_context.getBooleanProperty(PROP_STAT_FULL)) - return false; - String required = _context.getProperty(PROP_STAT_REQUIRED, DEFAULT_STAT_REQUIRED); - String req[] = required.split(","); - for (int i=0; i