* Stats:
- Fix BufferedStatsLog so it works at all - Don't instantiate BufferedStatsLog unless stats.logFilters property is defined (restart now required to enable logging) This eliminates the StatLogWriter thread and a decent amount of memory. - Move two CLI classes out of the lib - Commment out places where getStatLog() isn't checked for null - Cleanups
This commit is contained in:
@ -333,7 +333,8 @@ public class Connection {
|
||||
ResendPacketEvent rpe = new ResendPacketEvent(packet, timeout);
|
||||
}
|
||||
|
||||
_context.statManager().getStatLog().addData(Packet.toId(_sendStreamId), "stream.rtt", _options.getRTT(), _options.getWindowSize());
|
||||
// warning, getStatLog() can be null
|
||||
//_context.statManager().getStatLog().addData(Packet.toId(_sendStreamId), "stream.rtt", _options.getRTT(), _options.getWindowSize());
|
||||
|
||||
_lastSendTime = _context.clock().now();
|
||||
_outboundQueue.enqueue(packet);
|
||||
|
@ -15,7 +15,8 @@ import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Note - if no filter is defined in stat.logFilters at startup, this class will not
|
||||
* be instantiated - see StatManager.
|
||||
*/
|
||||
public class BufferedStatLog implements StatLog {
|
||||
private I2PAppContext _context;
|
||||
@ -46,7 +47,7 @@ public class BufferedStatLog implements StatLog {
|
||||
_lastWrite = _events.length-1;
|
||||
_statFilters = new ArrayList(10);
|
||||
_flushFrequency = 500;
|
||||
_filtersSpecified = false;
|
||||
updateFilters();
|
||||
I2PThread writer = new I2PThread(new StatLogWriter(), "StatLogWriter");
|
||||
writer.setDaemon(true);
|
||||
writer.start();
|
||||
@ -93,10 +94,7 @@ public class BufferedStatLog implements StatLog {
|
||||
_statFilters.clear();
|
||||
while (tok.hasMoreTokens())
|
||||
_statFilters.add(tok.nextToken().trim());
|
||||
if (_statFilters.size() > 0)
|
||||
_filtersSpecified = true;
|
||||
else
|
||||
_filtersSpecified = false;
|
||||
_filtersSpecified = _statFilters.size() > 0;
|
||||
}
|
||||
}
|
||||
_lastFilters = val;
|
||||
@ -107,9 +105,7 @@ public class BufferedStatLog implements StatLog {
|
||||
}
|
||||
}
|
||||
|
||||
String filename = _context.getProperty(StatManager.PROP_STAT_FILE);
|
||||
if (filename == null)
|
||||
filename = StatManager.DEFAULT_STAT_FILE;
|
||||
String filename = _context.getProperty(StatManager.PROP_STAT_FILE, StatManager.DEFAULT_STAT_FILE);
|
||||
File foo = new File(filename);
|
||||
if (!foo.isAbsolute())
|
||||
filename = (new File(_context.getRouterDir(), filename)).getAbsolutePath();
|
||||
|
@ -25,11 +25,17 @@ public class StatManager {
|
||||
private I2PAppContext _context;
|
||||
|
||||
/** stat name to FrequencyStat */
|
||||
private final Map _frequencyStats;
|
||||
private final Map<String, FrequencyStat> _frequencyStats;
|
||||
/** stat name to RateStat */
|
||||
private final Map _rateStats;
|
||||
private final Map<String, RateStat> _rateStats;
|
||||
/** may be null */
|
||||
private StatLog _statLog;
|
||||
|
||||
/**
|
||||
* Comma-separated stats or * for all.
|
||||
* This property must be set at startup, or
|
||||
* logging is disabled.
|
||||
*/
|
||||
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";
|
||||
@ -65,17 +71,19 @@ public class StatManager {
|
||||
public StatManager(I2PAppContext context) {
|
||||
_log = context.logManager().getLog(StatManager.class);
|
||||
_context = context;
|
||||
_frequencyStats = Collections.synchronizedMap(new HashMap(128));
|
||||
_frequencyStats = Collections.synchronizedMap(new HashMap(8));
|
||||
_rateStats = new HashMap(128); // synchronized only on add //Collections.synchronizedMap(new HashMap(128));
|
||||
_statLog = new BufferedStatLog(context);
|
||||
if (getStatFilter() != null)
|
||||
_statLog = new BufferedStatLog(context);
|
||||
}
|
||||
|
||||
/** may be null */
|
||||
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();
|
||||
for (Iterator<RateStat> iter = _rateStats.values().iterator(); iter.hasNext(); ) {
|
||||
RateStat rs = iter.next();
|
||||
rs.setStatLog(log);
|
||||
}
|
||||
}
|
||||
@ -122,28 +130,28 @@ public class StatManager {
|
||||
|
||||
/** update the given frequency statistic, taking note that an event occurred (and recalculating all frequencies) */
|
||||
public void updateFrequency(String name) {
|
||||
FrequencyStat freq = (FrequencyStat) _frequencyStats.get(name);
|
||||
FrequencyStat freq = _frequencyStats.get(name);
|
||||
if (freq != null) freq.eventOccurred();
|
||||
}
|
||||
|
||||
/** update the given rate statistic, taking note that the given data point was received (and recalculating all rates) */
|
||||
public void addRateData(String name, long data, long eventDuration) {
|
||||
RateStat stat = (RateStat) _rateStats.get(name); // unsynchronized
|
||||
RateStat stat = _rateStats.get(name); // unsynchronized
|
||||
if (stat != null) stat.addData(data, eventDuration);
|
||||
}
|
||||
|
||||
public void coalesceStats() {
|
||||
synchronized (_frequencyStats) {
|
||||
for (Iterator iter = _frequencyStats.values().iterator(); iter.hasNext();) {
|
||||
FrequencyStat stat = (FrequencyStat)iter.next();
|
||||
for (Iterator<FrequencyStat> iter = _frequencyStats.values().iterator(); iter.hasNext();) {
|
||||
FrequencyStat stat = iter.next();
|
||||
if (stat != null) {
|
||||
stat.coalesceStats();
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized (_rateStats) {
|
||||
for (Iterator iter = _rateStats.values().iterator(); iter.hasNext();) {
|
||||
RateStat stat = (RateStat)iter.next();
|
||||
for (Iterator<RateStat> iter = _rateStats.values().iterator(); iter.hasNext();) {
|
||||
RateStat stat = iter.next();
|
||||
if (stat != null) {
|
||||
stat.coalesceStats();
|
||||
}
|
||||
@ -152,18 +160,18 @@ public class StatManager {
|
||||
}
|
||||
|
||||
public FrequencyStat getFrequency(String name) {
|
||||
return (FrequencyStat) _frequencyStats.get(name);
|
||||
return _frequencyStats.get(name);
|
||||
}
|
||||
|
||||
public RateStat getRate(String name) {
|
||||
return (RateStat) _rateStats.get(name);
|
||||
return _rateStats.get(name);
|
||||
}
|
||||
|
||||
public Set getFrequencyNames() {
|
||||
public Set<String> getFrequencyNames() {
|
||||
return new HashSet(_frequencyStats.keySet());
|
||||
}
|
||||
|
||||
public Set getRateNames() {
|
||||
public Set<String> getRateNames() {
|
||||
return new HashSet(_rateStats.keySet());
|
||||
}
|
||||
|
||||
@ -180,14 +188,14 @@ public class StatManager {
|
||||
/** Group name (String) to a Set of stat names, ordered alphabetically */
|
||||
public Map getStatsByGroup() {
|
||||
Map groups = new TreeMap(Collator.getInstance());
|
||||
for (Iterator iter = _frequencyStats.values().iterator(); iter.hasNext();) {
|
||||
FrequencyStat stat = (FrequencyStat) iter.next();
|
||||
for (Iterator<FrequencyStat> iter = _frequencyStats.values().iterator(); iter.hasNext();) {
|
||||
FrequencyStat stat = iter.next();
|
||||
if (!groups.containsKey(stat.getGroupName())) groups.put(stat.getGroupName(), new TreeSet());
|
||||
Set names = (Set) groups.get(stat.getGroupName());
|
||||
names.add(stat.getName());
|
||||
}
|
||||
for (Iterator iter = _rateStats.values().iterator(); iter.hasNext();) {
|
||||
RateStat stat = (RateStat) iter.next();
|
||||
for (Iterator<RateStat> iter = _rateStats.values().iterator(); iter.hasNext();) {
|
||||
RateStat stat = iter.next();
|
||||
if (!groups.containsKey(stat.getGroupName())) groups.put(stat.getGroupName(), new TreeSet());
|
||||
Set names = (Set) groups.get(stat.getGroupName());
|
||||
names.add(stat.getName());
|
||||
@ -198,8 +206,10 @@ public class StatManager {
|
||||
public String getStatFilter() { return _context.getProperty(PROP_STAT_FILTER); }
|
||||
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
|
||||
// Return true if the stat should be ignored.
|
||||
/**
|
||||
* Save memory by not creating stats unless they are required for router operation
|
||||
* @return true if the stat should be ignored.
|
||||
*/
|
||||
public boolean ignoreStat(String statName) {
|
||||
if (_context.getProperty(PROP_STAT_FULL, DEFAULT_STAT_FULL).equalsIgnoreCase("true"))
|
||||
return false;
|
||||
|
@ -303,12 +303,13 @@ public class FIFOBandwidthLimiter {
|
||||
else
|
||||
_recvBps = (0.9f)*_recvBps + (0.1f)*((float)recv*1000)/(float)time;
|
||||
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
// warning, getStatLog() can be null
|
||||
//if (_log.shouldLog(Log.WARN)) {
|
||||
//if (_log.shouldLog(Log.INFO))
|
||||
// _log.info("BW: time = " + time + " sent: " + _sendBps + " recv: " + _recvBps);
|
||||
_context.statManager().getStatLog().addData("bw", "bw.sendBps1s", (long)_sendBps, sent);
|
||||
_context.statManager().getStatLog().addData("bw", "bw.recvBps1s", (long)_recvBps, recv);
|
||||
}
|
||||
// _context.statManager().getStatLog().addData("bw", "bw.sendBps1s", (long)_sendBps, sent);
|
||||
// _context.statManager().getStatLog().addData("bw", "bw.recvBps1s", (long)_recvBps, recv);
|
||||
//}
|
||||
|
||||
// Maintain an approximate average with a 15-second halflife
|
||||
// Weights (0.955 and 0.045) are tuned so that transition between two values (e.g. 0..10)
|
||||
@ -323,12 +324,13 @@ public class FIFOBandwidthLimiter {
|
||||
//else
|
||||
_recvBps15s = (0.955f)*_recvBps15s + (0.045f)*((float)recv*1000)/(float)time;
|
||||
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("BW15: time = " + time + " sent: " + _sendBps + " recv: " + _recvBps);
|
||||
_context.statManager().getStatLog().addData("bw", "bw.sendBps15s", (long)_sendBps15s, sent);
|
||||
_context.statManager().getStatLog().addData("bw", "bw.recvBps15s", (long)_recvBps15s, recv);
|
||||
}
|
||||
// warning, getStatLog() can be null
|
||||
//if (_log.shouldLog(Log.WARN)) {
|
||||
// if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("BW15: time = " + time + " sent: " + _sendBps + " recv: " + _recvBps);
|
||||
// _context.statManager().getStatLog().addData("bw", "bw.sendBps15s", (long)_sendBps15s, sent);
|
||||
// _context.statManager().getStatLog().addData("bw", "bw.recvBps15s", (long)_recvBps15s, recv);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,8 @@ class UDPFlooder implements Runnable {
|
||||
if (to == null)
|
||||
continue;
|
||||
msg.setTarget(to);
|
||||
_context.statManager().getStatLog().addData(peer.getRemotePeer().toBase64().substring(0,6), "udp.floodDataSent", 1, 0);
|
||||
// warning, getStatLog() can be null
|
||||
//_context.statManager().getStatLog().addData(peer.getRemotePeer().toBase64().substring(0,6), "udp.floodDataSent", 1, 0);
|
||||
|
||||
_transport.send(msg);
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user