- 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:
zzz committed 2009-08-18 20:33:15 +00:00
1 parent a379e36e24
commit 475187fcbc
7 files changed
+53 -43

No files matched your search

@@ -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();
@@ -1,65 +0,0 @@
package net.i2p.stat;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
public class SimpleStatDumper {
private final static Log _log = new Log(SimpleStatDumper.class);
public static void dumpStats(I2PAppContext context, int logLevel) {
if (!_log.shouldLog(logLevel)) return;
StringBuilder buf = new StringBuilder(4 * 1024);
dumpFrequencies(context, buf);
dumpRates(context, buf);
_log.log(logLevel, buf.toString());
}
private static void dumpFrequencies(I2PAppContext ctx, StringBuilder buf) {
Set frequencies = new TreeSet(ctx.statManager().getFrequencyNames());
for (Iterator iter = frequencies.iterator(); iter.hasNext();) {
String name = (String) iter.next();
FrequencyStat freq = ctx.statManager().getFrequency(name);
buf.append('\n');
buf.append(freq.getGroupName()).append('.').append(freq.getName()).append(": ")
.append(freq.getDescription()).append('\n');
long periods[] = freq.getPeriods();
Arrays.sort(periods);
for (int i = 0; i < periods.length; i++) {
buf.append('\t').append(periods[i]).append(':');
Frequency curFreq = freq.getFrequency(periods[i]);
buf.append(" average interval: ").append(curFreq.getAverageInterval());
buf.append(" min average interval: ").append(curFreq.getMinAverageInterval());
buf.append('\n');
}
}
}
private static void dumpRates(I2PAppContext ctx, StringBuilder buf) {
Set rates = new TreeSet(ctx.statManager().getRateNames());
for (Iterator iter = rates.iterator(); iter.hasNext();) {
String name = (String) iter.next();
RateStat rate = ctx.statManager().getRate(name);
buf.append('\n');
buf.append(rate.getGroupName()).append('.').append(rate.getName()).append(": ")
.append(rate.getDescription()).append('\n');
long periods[] = rate.getPeriods();
Arrays.sort(periods);
for (int i = 0; i < periods.length; i++) {
buf.append('\t').append(periods[i]).append(':');
Rate curRate = rate.getRate(periods[i]);
dumpRate(curRate, buf);
buf.append('\n');
}
}
}
static void dumpRate(Rate curRate, StringBuilder buf) {
buf.append(curRate.toString());
}
}
@@ -1,76 +0,0 @@
package net.i2p.stat;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Simple CLI to splot the stat logs into per-stat files containing
* #seconds since beginning and the value (ready for loading into your
* favorite plotting tool)
*/
public class StatLogSplitter {
private static final String DATE_FORMAT = "yyyyMMdd HH:mm:ss.SSS";
private static SimpleDateFormat _fmt = new SimpleDateFormat(DATE_FORMAT);
public static void main(String args[]) {
if (args.length != 1) {
System.err.println("Usage: StatLogSplitter filename");
return;
}
splitLog(args[0]);
}
private static void splitLog(String filename) {
Map outputFiles = new HashMap(4);
try {
BufferedReader in = new BufferedReader(new FileReader(filename));
String line;
long first = 0;
while ( (line = in.readLine()) != null) {
String date = line.substring(0, DATE_FORMAT.length()).trim();
int endGroup = line.indexOf(' ', DATE_FORMAT.length()+1);
int endStat = line.indexOf(' ', endGroup+1);
int endValue = line.indexOf(' ', endStat+1);
String group = line.substring(DATE_FORMAT.length()+1, endGroup).trim();
String stat = line.substring(endGroup, endStat).trim();
String value = line.substring(endStat, endValue).trim();
String duration = line.substring(endValue).trim();
//System.out.println(date + " " + group + " " + stat + " " + value + " " + duration);
try {
Date when = _fmt.parse(date);
if (first <= 0) first = when.getTime();
long val = Long.parseLong(value);
long time = Long.parseLong(duration);
if (!outputFiles.containsKey(stat)) {
outputFiles.put(stat, new FileWriter(stat + ".dat"));
System.out.println("Including data to " + stat + ".dat");
}
FileWriter out = (FileWriter)outputFiles.get(stat);
double s = (when.getTime()-first)/1000.0;
//long s = when.getTime();
out.write(s + " " + val + " [" + line + "]\n");
out.flush();
} catch (ParseException pe) {
continue;
} catch (NumberFormatException nfe){
continue;
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
for (Iterator iter = outputFiles.values().iterator(); iter.hasNext(); ) {
FileWriter out = (FileWriter)iter.next();
try { out.close(); } catch (IOException ioe) {}
}
}
}
+32 -22
View File
@@ -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;