From 98d2d661a838d8d679a159d96eb505b3fc48964d Mon Sep 17 00:00:00 2001 From: jrandom Date: Sun, 3 Oct 2004 20:48:43 +0000 Subject: [PATCH] 2004-10-03 jrandom * Add a new stat logging component to optionally dump the raw stats to disk as they are generated, rather than rely upon the summarized data. By default, this is off, but the router property "stat.logFilters" can be set to a comma delimited list of stats (e.g. "client.sendAckTime") which will be written to the file "stats.log" (or whatever the property "stat.logFile" is set to). This can also log profile related stats, such as "dbResponseTime" or "tunnelTestResponseTime". --- .../src/net/i2p/stat/BufferedStatLog.java | 146 ++++++++++++++++++ core/java/src/net/i2p/stat/RateStat.java | 6 +- core/java/src/net/i2p/stat/StatLog.java | 8 + core/java/src/net/i2p/stat/StatManager.java | 17 +- history.txt | 11 +- .../src/net/i2p/router/RouterVersion.java | 4 +- .../net/i2p/router/client/ClientManager.java | 2 +- .../message/OutboundClientMessageJob.java | 16 +- .../DatabaseLookupMessageHandler.java | 4 +- .../HandleDatabaseLookupMessageJob.java | 4 +- .../HandleDatabaseStoreMessageJob.java | 2 +- .../router/networkdb/kademlia/SearchJob.java | 18 +-- .../router/networkdb/kademlia/StoreJob.java | 6 +- .../net/i2p/router/peermanager/DBHistory.java | 16 +- .../i2p/router/peermanager/PeerProfile.java | 32 ++-- .../i2p/router/peermanager/TunnelHistory.java | 16 +- 16 files changed, 252 insertions(+), 56 deletions(-) create mode 100644 core/java/src/net/i2p/stat/BufferedStatLog.java create mode 100644 core/java/src/net/i2p/stat/StatLog.java diff --git a/core/java/src/net/i2p/stat/BufferedStatLog.java b/core/java/src/net/i2p/stat/BufferedStatLog.java new file mode 100644 index 000000000..0c008184c --- /dev/null +++ b/core/java/src/net/i2p/stat/BufferedStatLog.java @@ -0,0 +1,146 @@ +package net.i2p.stat; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.StringTokenizer; + +import net.i2p.I2PAppContext; +import net.i2p.util.I2PThread; + +/** + * + */ +public class BufferedStatLog implements StatLog { + private I2PAppContext _context; + private List _events; + /** flush stat events to disk after this many events (or 30s)*/ + private int _flushFrequency; + private List _statFilters; + private BufferedWriter _out; + private String _outFile; + + public BufferedStatLog(I2PAppContext ctx) { + _context = ctx; + _events = new ArrayList(1000); + _statFilters = new ArrayList(10); + _flushFrequency = 1000; + I2PThread writer = new I2PThread(new StatLogWriter(), "StatLogWriter"); + writer.setDaemon(true); + writer.start(); + } + + public void addData(String scope, String stat, long value, long duration) { + synchronized (_events) { + _events.add(new StatEvent(scope, stat, value, duration)); + if (_events.size() > _flushFrequency) + _events.notifyAll(); + } + } + + private boolean shouldLog(String stat) { + synchronized (_statFilters) { + return _statFilters.contains(stat); + } + } + + private void updateFilters() { + String val = _context.getProperty("stat.logFilters"); + if (val != null) { + StringTokenizer tok = new StringTokenizer(val, ","); + synchronized (_statFilters) { + _statFilters.clear(); + while (tok.hasMoreTokens()) + _statFilters.add(tok.nextToken().trim()); + } + } else { + synchronized (_statFilters) { _statFilters.clear(); } + } + + String filename = _context.getProperty("stat.logFile"); + if (filename == null) + filename = "stats.log"; + if ( (_outFile != null) && (_outFile.equals(filename)) ) { + // noop + } else { + if (_out != null) try { _out.close(); } catch (IOException ioe) {} + _outFile = filename; + try { + _out = new BufferedWriter(new FileWriter(_outFile)); + } catch (IOException ioe) { ioe.printStackTrace(); } + } + } + + private class StatLogWriter implements Runnable { + private SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd hh:mm:ss.SSS"); + public void run() { + List cur = new ArrayList(1000); + while (true) { + synchronized (_events) { + if (_events.size() < _flushFrequency) { + try { _events.wait(30*1000); } catch (InterruptedException ie) {} + } + cur.addAll(_events); + _events.clear(); + } + if (cur.size() > 0) { + writeEvents(cur); + cur.clear(); + } + } + } + + private void writeEvents(List events) { + try { + updateFilters(); + for (int i = 0; i < events.size(); i++) { + StatEvent evt = (StatEvent)events.get(i); + if (!shouldLog(evt.getStat())) continue; + String when = null; + synchronized (_fmt) { + when = _fmt.format(new Date(evt.getTime())); + } + _out.write(when); + _out.write(" "); + if (evt.getScope() == null) + _out.write("noScope "); + else + _out.write(evt.getScope() + " "); + _out.write(evt.getStat()+" "); + _out.write(evt.getValue()+" "); + _out.write(evt.getDuration()+"\n"); + } + _out.flush(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + } + + private class StatEvent { + private long _time; + private String _scope; + private String _stat; + private long _value; + private long _duration; + + public StatEvent(String scope, String stat, long value, long duration) { + _scope = scope; + _stat = stat; + _value = value; + _duration = duration; + _time = _context.clock().now(); + } + + public long getTime() { return _time; } + public String getScope() { return _scope; } + public String getStat() { return _stat; } + public long getValue() { return _value; } + public long getDuration() { return _duration; } + } +} diff --git a/core/java/src/net/i2p/stat/RateStat.java b/core/java/src/net/i2p/stat/RateStat.java index b2e558f39..81932fc38 100644 --- a/core/java/src/net/i2p/stat/RateStat.java +++ b/core/java/src/net/i2p/stat/RateStat.java @@ -19,6 +19,8 @@ public class RateStat { private String _description; /** actual rate objects for this statistic */ private Rate _rates[]; + /** component we tell about events as they occur */ + private StatLog _statLog; public RateStat(String name, String description, String group, long periods[]) { _statName = name; @@ -28,11 +30,13 @@ public class RateStat { for (int i = 0; i < periods.length; i++) _rates[i] = new Rate(periods[i]); } - + public void setStatLog(StatLog sl) { _statLog = sl; } + /** * update all of the rates for the various periods with the given value. */ public void addData(long value, long eventDuration) { + if (_statLog != null) _statLog.addData(_groupName, _statName, value, eventDuration); for (int i = 0; i < _rates.length; i++) _rates[i].addData(value, eventDuration); } diff --git a/core/java/src/net/i2p/stat/StatLog.java b/core/java/src/net/i2p/stat/StatLog.java new file mode 100644 index 000000000..bc4ef8128 --- /dev/null +++ b/core/java/src/net/i2p/stat/StatLog.java @@ -0,0 +1,8 @@ +package net.i2p.stat; + +/** + * Component to be notified when a particular event occurs + */ +public interface StatLog { + public void addData(String scope, String stat, long value, long duration); +} diff --git a/core/java/src/net/i2p/stat/StatManager.java b/core/java/src/net/i2p/stat/StatManager.java index 91e8aa3ff..cdf2442b8 100644 --- a/core/java/src/net/i2p/stat/StatManager.java +++ b/core/java/src/net/i2p/stat/StatManager.java @@ -27,6 +27,7 @@ public class StatManager { private Map _frequencyStats; /** stat name to RateStat */ private Map _rateStats; + private StatLog _statLog; /** * The stat manager should only be constructed and accessed through the @@ -39,6 +40,18 @@ public class StatManager { _context = context; _frequencyStats = Collections.synchronizedMap(new HashMap(128)); _rateStats = Collections.synchronizedMap(new HashMap(128)); + _statLog = new BufferedStatLog(context); + } + + public StatLog getStatLog() { return _statLog; } + public void setStatLog(StatLog log) { + _statLog = log; + synchronized (_rateStats) { + for (Iterator iter = _rateStats.values().iterator(); iter.hasNext(); ) { + RateStat rs = (RateStat)iter.next(); + rs.setStatLog(log); + } + } } /** @@ -64,7 +77,9 @@ public class StatManager { */ public void createRateStat(String name, String description, String group, long periods[]) { if (_rateStats.containsKey(name)) return; - _rateStats.put(name, new RateStat(name, description, group, periods)); + RateStat rs = new RateStat(name, description, group, periods); + if (_statLog != null) rs.setStatLog(_statLog); + _rateStats.put(name, rs); } /** update the given frequency statistic, taking note that an event occurred (and recalculating all frequencies) */ diff --git a/history.txt b/history.txt index 1013efa78..72a911412 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,13 @@ -$Id: history.txt,v 1.29 2004/10/02 07:31:16 jrandom Exp $ +$Id: history.txt,v 1.30 2004/10/02 14:05:24 jrandom Exp $ + +2004-10-03 jrandom + * Add a new stat logging component to optionally dump the raw stats to + disk as they are generated, rather than rely upon the summarized data. + By default, this is off, but the router property "stat.logFilters" can + be set to a comma delimited list of stats (e.g. "client.sendAckTime") + which will be written to the file "stats.log" (or whatever the property + "stat.logFile" is set to). This can also log profile related stats, + such as "dbResponseTime" or "tunnelTestResponseTime". 2004-10-02 jrandom * Assure that we quickly fail messages bound for shitlisted peers. diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 4a547e56c..6142682cb 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.39 $ $Date: 2004/10/02 07:31:15 $"; + public final static String ID = "$Revision: 1.40 $ $Date: 2004/10/02 14:05:24 $"; public final static String VERSION = "0.4.1.1"; - public final static long BUILD = 5; + public final static long BUILD = 6; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION); System.out.println("Router ID: " + RouterVersion.ID); diff --git a/router/java/src/net/i2p/router/client/ClientManager.java b/router/java/src/net/i2p/router/client/ClientManager.java index c677b0a9a..a6623ddbc 100644 --- a/router/java/src/net/i2p/router/client/ClientManager.java +++ b/router/java/src/net/i2p/router/client/ClientManager.java @@ -52,7 +52,7 @@ public class ClientManager { _log = context.logManager().getLog(ClientManager.class); _context.statManager().createRateStat("client.receiveMessageSize", "How large are messages received by the client?", - "Client Messages", + "ClientMessages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l }); _runners = new HashMap(); _pendingRunners = new HashSet(); diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageJob.java index a09a7bc18..5253cda0f 100644 --- a/router/java/src/net/i2p/router/message/OutboundClientMessageJob.java +++ b/router/java/src/net/i2p/router/message/OutboundClientMessageJob.java @@ -100,14 +100,14 @@ public class OutboundClientMessageJob extends JobImpl { super(ctx); _log = ctx.logManager().getLog(OutboundClientMessageJob.class); - ctx.statManager().createFrequencyStat("client.sendMessageFailFrequency", "How often does a client fail to send a message?", "Client Messages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l }); - 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 }); + 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.sendAttemptAverage", "How many different tunnels do we have to try when sending a client message?", "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[] { 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?", "ClientMessages", new long[] { 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[] { 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 }); long timeoutMs = OVERALL_TIMEOUT_MS_DEFAULT; diff --git a/router/java/src/net/i2p/router/networkdb/DatabaseLookupMessageHandler.java b/router/java/src/net/i2p/router/networkdb/DatabaseLookupMessageHandler.java index 8f103c5ab..29ee4f3fb 100644 --- a/router/java/src/net/i2p/router/networkdb/DatabaseLookupMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/DatabaseLookupMessageHandler.java @@ -27,8 +27,8 @@ public class DatabaseLookupMessageHandler implements HandlerJobBuilder { public DatabaseLookupMessageHandler(RouterContext context) { _context = context; _log = context.logManager().getLog(DatabaseLookupMessageHandler.class); - _context.statManager().createRateStat("netDb.lookupsReceived", "How many netDb lookups have we received?", "Network Database", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); - _context.statManager().createRateStat("netDb.lookupsDropped", "How many netDb lookups did we drop due to throttling?", "Network Database", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _context.statManager().createRateStat("netDb.lookupsReceived", "How many netDb lookups have we received?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _context.statManager().createRateStat("netDb.lookupsDropped", "How many netDb lookups did we drop due to throttling?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); } public Job createJob(I2NPMessage receivedMessage, RouterIdentity from, Hash fromHash) { diff --git a/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java b/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java index 683cf62d2..4b7424cf0 100644 --- a/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java +++ b/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java @@ -51,8 +51,8 @@ public class HandleDatabaseLookupMessageJob extends JobImpl { public HandleDatabaseLookupMessageJob(RouterContext ctx, DatabaseLookupMessage receivedMessage, RouterIdentity from, Hash fromHash) { super(ctx); _log = getContext().logManager().getLog(HandleDatabaseLookupMessageJob.class); - getContext().statManager().createRateStat("netDb.lookupsHandled", "How many netDb lookups have we handled?", "Network Database", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.lookupsMatched", "How many netDb lookups did we have the data for?", "Network Database", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.lookupsHandled", "How many netDb lookups have we handled?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.lookupsMatched", "How many netDb lookups did we have the data for?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); _message = receivedMessage; _from = from; _fromHash = fromHash; diff --git a/router/java/src/net/i2p/router/networkdb/HandleDatabaseStoreMessageJob.java b/router/java/src/net/i2p/router/networkdb/HandleDatabaseStoreMessageJob.java index 37e8c3287..56e5e910c 100644 --- a/router/java/src/net/i2p/router/networkdb/HandleDatabaseStoreMessageJob.java +++ b/router/java/src/net/i2p/router/networkdb/HandleDatabaseStoreMessageJob.java @@ -38,7 +38,7 @@ public class HandleDatabaseStoreMessageJob extends JobImpl { public HandleDatabaseStoreMessageJob(RouterContext ctx, DatabaseStoreMessage receivedMessage, RouterIdentity from, Hash fromHash) { super(ctx); _log = ctx.logManager().getLog(HandleDatabaseStoreMessageJob.class); - ctx.statManager().createRateStat("netDb.storeHandled", "How many netDb store messages have we handled?", "Network Database", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + ctx.statManager().createRateStat("netDb.storeHandled", "How many netDb store messages have we handled?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); _message = receivedMessage; _from = from; _fromHash = fromHash; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java index fd93f852e..c5e868ae1 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java @@ -82,15 +82,15 @@ class SearchJob extends JobImpl { _isLease = isLease; _peerSelector = new PeerSelector(getContext()); _expiration = getContext().clock().now() + timeoutMs; - getContext().statManager().createRateStat("netDb.successTime", "How long a successful search takes", "Network Database", new long[] { 60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.failedTime", "How long a failed search takes", "Network Database", new long[] { 60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.successPeers", "How many peers are contacted in a successful search", "Network Database", new long[] { 60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.failedPeers", "How many peers fail to respond to a lookup?", "Network Database", new long[] { 60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.searchCount", "Overall number of searches sent", "Network Database", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.searchMessageCount", "Overall number of mesages for all searches sent", "Network Database", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.searchReplyValidated", "How many search replies we get that we are able to validate (fetch)", "Network Database", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.searchReplyNotValidated", "How many search replies we get that we are NOT able to validate (fetch)", "Network Database", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.searchReplyValidationSkipped", "How many search replies we get from unreliable peers that we skip?", "Network Database", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.successTime", "How long a successful search takes", "NetworkDatabase", new long[] { 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.failedTime", "How long a failed search takes", "NetworkDatabase", new long[] { 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.successPeers", "How many peers are contacted in a successful search", "NetworkDatabase", new long[] { 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.failedPeers", "How many peers fail to respond to a lookup?", "NetworkDatabase", new long[] { 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.searchCount", "Overall number of searches sent", "NetworkDatabase", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.searchMessageCount", "Overall number of mesages for all searches sent", "NetworkDatabase", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.searchReplyValidated", "How many search replies we get that we are able to validate (fetch)", "NetworkDatabase", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.searchReplyNotValidated", "How many search replies we get that we are NOT able to validate (fetch)", "NetworkDatabase", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.searchReplyValidationSkipped", "How many search replies we get from unreliable peers that we skip?", "NetworkDatabase", new long[] { 5*60*1000l, 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); if (_log.shouldLog(Log.DEBUG)) _log.debug("Search (" + getClass().getName() + " for " + key.toBase64(), new Exception("Search enqueued by")); } diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java index c7664412b..c65f50a28 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java @@ -73,9 +73,9 @@ class StoreJob extends JobImpl { DataStructure data, Job onSuccess, Job onFailure, long timeoutMs, Set toSkip) { super(context); _log = context.logManager().getLog(StoreJob.class); - getContext().statManager().createRateStat("netDb.storeSent", "How many netDb store messages have we sent?", "Network Database", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.storePeers", "How many peers each netDb must be sent to before success?", "Network Database", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); - getContext().statManager().createRateStat("netDb.ackTime", "How long does it take for a peer to ack a netDb store?", "Network Database", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.storeSent", "How many netDb store messages have we sent?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.storePeers", "How many peers each netDb must be sent to before success?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + getContext().statManager().createRateStat("netDb.ackTime", "How long does it take for a peer to ack a netDb store?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); _facade = facade; _state = new StoreState(getContext(), key, data, toSkip); _onSuccess = onSuccess; diff --git a/router/java/src/net/i2p/router/peermanager/DBHistory.java b/router/java/src/net/i2p/router/peermanager/DBHistory.java index 0b3307885..b2b089898 100644 --- a/router/java/src/net/i2p/router/peermanager/DBHistory.java +++ b/router/java/src/net/i2p/router/peermanager/DBHistory.java @@ -28,10 +28,12 @@ public class DBHistory { private long _lastLookupReceived; private long _unpromptedDbStoreNew; private long _unpromptedDbStoreOld; + private String _statGroup; - public DBHistory(RouterContext context) { + public DBHistory(RouterContext context, String statGroup) { _context = context; _log = context.logManager().getLog(DBHistory.class); + _statGroup = statGroup; _successfulLookups = 0; _failedLookups = 0; _failedLookupRate = null; @@ -45,7 +47,7 @@ public class DBHistory { _lastLookupReceived = -1; _unpromptedDbStoreNew = 0; _unpromptedDbStoreOld = 0; - createRates(); + createRates(statGroup); } /** how many times we have sent them a db lookup and received the value back from them */ @@ -212,15 +214,17 @@ public class DBHistory { _invalidReplyRate.load(props, "dbHistory.invalidReplyRate", true); } catch (IllegalArgumentException iae) { _log.warn("DB History invalid reply rate is corrupt, resetting", iae); - createRates(); + createRates(_statGroup); } } - private void createRates() { + private void createRates(String statGroup) { if (_failedLookupRate == null) - _failedLookupRate = new RateStat("dbHistory.failedLookupRate", "How often does this peer to respond to a lookup?", "dbHistory", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l }); + _failedLookupRate = new RateStat("dbHistory.failedLookupRate", "How often does this peer to respond to a lookup?", statGroup, new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l }); if (_invalidReplyRate == null) - _invalidReplyRate = new RateStat("dbHistory.invalidReplyRate", "How often does this peer give us a bad (nonexistant, forged, etc) peer?", "dbHistory", new long[] { 30*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _invalidReplyRate = new RateStat("dbHistory.invalidReplyRate", "How often does this peer give us a bad (nonexistant, forged, etc) peer?", statGroup, new long[] { 30*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _failedLookupRate.setStatLog(_context.statManager().getStatLog()); + _invalidReplyRate.setStatLog(_context.statManager().getStatLog()); } private final static long getLong(Properties props, String key) { diff --git a/router/java/src/net/i2p/router/peermanager/PeerProfile.java b/router/java/src/net/i2p/router/peermanager/PeerProfile.java index 134b51801..3af9c3514 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerProfile.java +++ b/router/java/src/net/i2p/router/peermanager/PeerProfile.java @@ -45,9 +45,6 @@ public class PeerProfile { // does this peer profile contain expanded data, or just the basics? private boolean _expanded; - public PeerProfile(RouterContext context) { - this(context, null, true); - } public PeerProfile(RouterContext context, Hash peer) { this(context, peer, true); } @@ -236,28 +233,37 @@ public class PeerProfile { * */ public void expandProfile() { + String group = (null == _peer ? "profileUnknown" : _peer.toBase64().substring(0,6)); if (_sendSuccessSize == null) - _sendSuccessSize = new RateStat("sendSuccessSize", "How large successfully sent messages are", "profile", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _sendSuccessSize = new RateStat("sendSuccessSize", "How large successfully sent messages are", group, new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); if (_sendFailureSize == null) - _sendFailureSize = new RateStat("sendFailureSize", "How large messages that could not be sent were", "profile", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000 } ); + _sendFailureSize = new RateStat("sendFailureSize", "How large messages that could not be sent were", group, new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000 } ); if (_receiveSize == null) - _receiveSize = new RateStat("receiveSize", "How large received messages are", "profile", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000 } ); + _receiveSize = new RateStat("receiveSize", "How large received messages are", group, new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000 } ); if (_dbResponseTime == null) - _dbResponseTime = new RateStat("dbResponseTime", "how long it takes to get a db response from the peer (in milliseconds)", "profile", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000 } ); + _dbResponseTime = new RateStat("dbResponseTime", "how long it takes to get a db response from the peer (in milliseconds)", group, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000 } ); if (_tunnelCreateResponseTime == null) - _tunnelCreateResponseTime = new RateStat("tunnelCreateResponseTime", "how long it takes to get a tunnel create response from the peer (in milliseconds)", "profile", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000 } ); + _tunnelCreateResponseTime = new RateStat("tunnelCreateResponseTime", "how long it takes to get a tunnel create response from the peer (in milliseconds)", group, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000 } ); if (_tunnelTestResponseTime == null) - _tunnelTestResponseTime = new RateStat("tunnelTestResponseTime", "how long it takes to successfully test a tunnel this peer participates in (in milliseconds)", "profile", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000 } ); + _tunnelTestResponseTime = new RateStat("tunnelTestResponseTime", "how long it takes to successfully test a tunnel this peer participates in (in milliseconds)", group, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000 } ); if (_commError == null) - _commError = new RateStat("commErrorRate", "how long between communication errors with the peer (e.g. disconnection)", "profile", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000 } ); + _commError = new RateStat("commErrorRate", "how long between communication errors with the peer (e.g. disconnection)", group, new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000 } ); if (_dbIntroduction == null) - _dbIntroduction = new RateStat("dbIntroduction", "how many new peers we get from dbSearchReplyMessages or dbStore messages", "profile", new long[] { 60*60*1000l, 24*60*60*1000l, 7*24*60*60*1000l }); + _dbIntroduction = new RateStat("dbIntroduction", "how many new peers we get from dbSearchReplyMessages or dbStore messages", group, new long[] { 60*60*1000l, 24*60*60*1000l, 7*24*60*60*1000l }); if (_tunnelHistory == null) - _tunnelHistory = new TunnelHistory(_context); + _tunnelHistory = new TunnelHistory(_context, group); if (_dbHistory == null) - _dbHistory = new DBHistory(_context); + _dbHistory = new DBHistory(_context, group); + _sendSuccessSize.setStatLog(_context.statManager().getStatLog()); + _sendFailureSize.setStatLog(_context.statManager().getStatLog()); + _receiveSize.setStatLog(_context.statManager().getStatLog()); + _dbResponseTime.setStatLog(_context.statManager().getStatLog()); + _tunnelCreateResponseTime.setStatLog(_context.statManager().getStatLog()); + _tunnelTestResponseTime.setStatLog(_context.statManager().getStatLog()); + _commError.setStatLog(_context.statManager().getStatLog()); + _dbIntroduction.setStatLog(_context.statManager().getStatLog()); _expanded = true; } diff --git a/router/java/src/net/i2p/router/peermanager/TunnelHistory.java b/router/java/src/net/i2p/router/peermanager/TunnelHistory.java index d9c498e6f..0f61ed4f0 100644 --- a/router/java/src/net/i2p/router/peermanager/TunnelHistory.java +++ b/router/java/src/net/i2p/router/peermanager/TunnelHistory.java @@ -23,22 +23,26 @@ public class TunnelHistory { private volatile long _lastFailed; private RateStat _rejectRate; private RateStat _failRate; + private String _statGroup; - public TunnelHistory(RouterContext context) { + public TunnelHistory(RouterContext context, String statGroup) { _context = context; _log = context.logManager().getLog(TunnelHistory.class); + _statGroup = statGroup; _lifetimeAgreedTo = 0; _lifetimeFailed = 0; _lifetimeRejected = 0; _lastAgreedTo = 0; _lastFailed = 0; _lastRejected = 0; - createRates(); + createRates(statGroup); } - private void createRates() { - _rejectRate = new RateStat("tunnelHistory.rejectRate", "How often does this peer reject a tunnel request?", "tunnelHistory", new long[] { 60*1000l, 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l }); - _failRate = new RateStat("tunnelHistory.failRate", "How often do tunnels this peer accepts fail?", "tunnelHistory", new long[] { 60*1000l, 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l }); + private void createRates(String statGroup) { + _rejectRate = new RateStat("tunnelHistory.rejectRate", "How often does this peer reject a tunnel request?", statGroup, new long[] { 60*1000l, 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _failRate = new RateStat("tunnelHistory.failRate", "How often do tunnels this peer accepts fail?", statGroup, new long[] { 60*1000l, 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _rejectRate.setStatLog(_context.statManager().getStatLog()); + _failRate.setStatLog(_context.statManager().getStatLog()); } /** total tunnels the peer has agreed to participate in */ @@ -126,7 +130,7 @@ public class TunnelHistory { _log.debug("Loading tunnelHistory.failRate"); } catch (IllegalArgumentException iae) { _log.warn("TunnelHistory rates are corrupt, resetting", iae); - createRates(); + createRates(_statGroup); } }