load what stats we want to monitor from a config file (harvester.config)

This commit is contained in:
jrandom
2004-04-17 03:32:51 +00:00
committed by zzz
parent 061460f978
commit 8c7b91bd79
3 changed files with 202 additions and 76 deletions

View File

@ -5,6 +5,7 @@ import net.i2p.util.Log;
import net.i2p.util.Clock;
import java.util.Properties;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Locale;
@ -21,8 +22,22 @@ class DataHarvester {
private static final Log _log = new Log(DataHarvester.class);
private static final DataHarvester _instance = new DataHarvester();
public static final DataHarvester getInstance() { return _instance; }
/**
* Contains the list of StatGroup objects loaded from the harvest.config file
* {@see StatGroupLoader} where each statGroup defines a set of stats to pull
* from each router's options.
*
*/
private List _statGroups;
protected DataHarvester() {}
/**
* Where are we reading the stat groups from? For now, "harvester.config".
*/
private static final String STAT_GROUP_CONFIG_FILENAME = "harvester.config";
protected DataHarvester() {
_statGroups = StatGroupLoader.loadStatGroups(STAT_GROUP_CONFIG_FILENAME);
}
/**
* Harvest all of the data from the peers and store it in the monitor.
@ -45,9 +60,7 @@ class DataHarvester {
_log.info("Harvest the data from " + peer.getIdentity().getHash().toBase64());
harvestRank(monitor, peer, peers);
harvestRankAs(monitor, peer);
harvestEncryptionTime(monitor, peer);
harvestDroppedJobs(monitor, peer);
harvestProcessingTime(monitor, peer);
harvestGroups(monitor, peer);
}
/**
@ -138,88 +151,56 @@ class DataHarvester {
}
/**
* How long does it take the peer to perform an elGamal encryption? Stored in
* the peer summary as "encryptTime", containing 4 doubles (numMs for 1 minute,
* quantity in the last minute, numMs for 1 hour, quantity in the last hour)
*
* @param peer who are we checking the encryption time of
* Harvest all data points from the peer
*
*/
private void harvestEncryptionTime(NetMonitor monitor, RouterInfo peer) {
double minuteMs = getDouble(peer, "stat_crypto.elGamal.encrypt.60s", 0);
double hourMs = getDouble(peer, "stat_crypto.elGamal.encrypt.60m", 0);
double minuteQuantity = getDouble(peer, "stat_crypto.elGamal.encrypt.60s", 7);
double hourQuantity = getDouble(peer, "stat_crypto.elGamal.encrypt.60m", 7);
if ( (minuteMs == -1) || (hourMs == -1) || (minuteQuantity == -1) || (hourQuantity == -1) )
return;
double times[] = new double[4];
times[0] = minuteMs;
times[1] = minuteQuantity;
times[2] = hourMs;
times[3] = hourQuantity;
String description = "how long it takes to do an ElGamal encryption";
String valDescr[] = new String[4];
valDescr[0] = "encryption time avg ms (minute)";
valDescr[1] = "# encryptions (minute)";
valDescr[2] = "encryption time avg ms (hour)";
valDescr[3] = "# encryptions (hour)";
monitor.addData(peer.getIdentity().getHash().toBase64(), "encryptTime", description, valDescr, peer.getPublished(), times);
private void harvestGroups(NetMonitor monitor, RouterInfo peer) {
_log.debug("Harvesting group data for " + peer.getIdentity().getHash().toBase64());
for (int i = 0; i < _statGroups.size(); i++) {
StatGroup group = (StatGroup)_statGroups.get(i);
harvestGroup(monitor, peer, group);
}
}
/**
* How jobs has the peer dropped in the last minute / hour? Stored in
* the peer summary as "droppedJobs", containing 2 doubles (num jobs for 1 minute,
* num jobs for 1 hour)
* Harvest the data points for the given group from the peer and toss them
* into the monitor
*
* @param peer who are we checking the frequency of dropping jobs for
*/
private void harvestDroppedJobs(NetMonitor monitor, RouterInfo peer) {
double minute = getDouble(peer, "stat_jobQueue.droppedJobs.60s", 0);
double hour = getDouble(peer, "stat_jobQueue.droppedJobs.60m", 0);
double quantity[] = new double[2];
quantity[0] = minute;
quantity[1] = hour;
if ( (minute == -1) || (hour == -1) )
return;
String valDescr[] = new String[2];
valDescr[0] = "# dropped jobs (minute)";
valDescr[1] = "# dropped jobs (hour)";
String description = "how many dropped jobs";
monitor.addData(peer.getIdentity().getHash().toBase64(), "droppedJobs", description, valDescr, peer.getPublished(), quantity);
private void harvestGroup(NetMonitor monitor, RouterInfo peer, StatGroup group) {
_log.debug("Harvesting group data for " + peer.getIdentity().getHash().toBase64() + " / " + group.getDescription());
double values[] = harvestGroupValues(peer, group);
if (values == null) return;
String description = "how long it takes to do an ElGamal encryption";
String valDescr[] = new String[group.getStatCount()];
for (int i = 0; i < group.getStatCount(); i++)
valDescr[i] = group.getStat(i).getStatDescription();
monitor.addData(peer.getIdentity().getHash().toBase64(), group.getDescription(), group.getDescription(), valDescr, peer.getPublished(), values);
}
/**
* How long does it take to process an outbound message? Stored in
* the peer summary as "processingTime", containing 4 doubles (avg ms for 1 minute,
* num messages for 1 minute, avg ms for 1 hour, num messages for 1 hour)
/**
* Pull up a list of all values associated with the group (in the order that the
* group specifies).
*
* @param peer who are we checking the frequency of dropping jobs for
* @return values or null on error
*/
private void harvestProcessingTime(NetMonitor monitor, RouterInfo peer) {
double minuteMs = getDouble(peer, "stat_transport.sendProcessingTime.60s", 0);
double minuteFreq = getDouble(peer, "stat_transport.sendProcessingTime.60s", 7);
double hourMs = getDouble(peer, "stat_transport.sendProcessingTime.60m", 0);
double hourFreq = getDouble(peer, "stat_transport.sendProcessingTime.60m", 7);
if ( (minuteMs == -1) || (hourMs == -1) || (minuteFreq == -1) || (hourFreq == -1) )
return;
double times[] = new double[4];
times[0] = minuteMs;
times[1] = minuteFreq;
times[2] = hourMs;
times[3] = hourFreq;
String valDescr[] = new String[4];
valDescr[0] = "process time avg ms (minute)";
valDescr[1] = "process events (minute)";
valDescr[2] = "process time avg ms (hour)";
valDescr[3] = "process events (hour)";
String description = "how long does it take to process a message";
monitor.addData(peer.getIdentity().getHash().toBase64(), "processingTime", description, valDescr, peer.getPublished(), times);
private double[] harvestGroupValues(RouterInfo peer, StatGroup group) {
List values = new ArrayList(8);
for (int i = 0; i < group.getStatCount(); i++) {
StatGroup.StatDescription stat = group.getStat(i);
double val = getDouble(peer, stat.getOptionName(), stat.getOptionField());
if (val == -1)
return null;
else
values.add(new Double(val));
}
double rv[] = new double[values.size()];
for (int i = 0; i < values.size(); i++)
rv[i] = ((Double)values.get(i)).doubleValue();
return rv;
}
/**
* Pull a value from the peer's option as a double, assuming the standard semicolon
* delimited formatting

View File

@ -0,0 +1,53 @@
package net.i2p.netmonitor;
import java.util.ArrayList;
import java.util.List;
/**
* Stupid little structure to configure the DataHarvester's gathering of statistics.
*
*/
public class StatGroup {
private String _groupDescription;
private List _stats;
public StatGroup(String description) {
_groupDescription = description;
_stats = new ArrayList();
}
public String getDescription() { return _groupDescription; }
public int getStatCount() { return _stats.size(); }
public StatDescription getStat(int index) { return (StatDescription)_stats.get(index); }
public void addStat(String description, String optionName, int optionField) {
StatDescription descr = new StatDescription(description, optionName, optionField);
_stats.add(descr);
}
public class StatDescription {
private String _statDescription;
private String _optionName;
private int _optionField;
public StatDescription(String descr, String optionName, int optionField) {
_statDescription = descr;
_optionName = optionName;
_optionField = optionField;
}
/** brief description of this data point */
public String getStatDescription() { return _statDescription; }
/**
* if this is harvested from the RouterInfo's options, this specifies
* which key in that map to pull from (or null if it isn't harvested
* from there)
*/
public String getOptionName() { return _optionName; }
/**
* if this is harvested from the RouterInfo's options, this specifies
* which field in value of that map to pull from (or -1 if it isn't harvested
* from there)
*/
public int getOptionField() { return _optionField; }
}
}

View File

@ -0,0 +1,92 @@
package net.i2p.netmonitor;
import net.i2p.util.Log;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.ArrayList;
import java.util.Properties;
/**
* Load up the StatGroups from the location specified to configure the data harvester.
* The stat groups are formatted in a simple properties file style, e.g.: <pre>
* # dropped jobs
* statGroup.0.name=droppedJobs
* statGroup.0.detail.0.name=num dropped jobs (minute)
* statGroup.0.detail.0.option=stat_jobQueue.droppedJobs.60m
* statGroup.0.detail.0.field=3
* statGroup.0.detail.1.name=num dropped jobs (hour)
* statGroup.0.detail.1.option=stat_jobQueue.droppedJobs.60h
* statGroup.0.detail.1.field=3
* #
* statGroup.1.name=encryptTime
* statGroup.1.detail.0.name=encryption time avg ms (minute)
* statGroup.1.detail.0.option=stat_crypto.elGamal.encrypt.60s
* statGroup.1.detail.0.field=0
* statGroup.1.detail.1.name=num encryptions (minute)
* statGroup.1.detail.1.option=stat_crypto.elGamal.encrypt.60s
* statGroup.1.detail.1.field=7
* statGroup.1.detail.2.name=encryption time avg ms (hour)
* statGroup.1.detail.2.option=stat_crypto.elGamal.encrypt.60s
* statGroup.1.detail.2.field=0
* statGroup.1.detail.3.name=num encryptions (hour)
* statGroup.1.detail.3.option=stat_crypto.elGamal.encrypt.60s
* statGroup.1.detail.3.field=7
* </pre>
*/
class StatGroupLoader {
private static final Log _log = new Log(StatGroupLoader.class);
/**
* Load a list of stat groups from the file specified
*
* @return list of StatGroup objects
*/
public static List loadStatGroups(String filename) {
_log.debug("Loading stat groups from " + filename);
FileInputStream fis = null;
File f = new File(filename);
try {
fis = new FileInputStream(f);
Properties p = new Properties();
p.load(fis);
_log.debug("Config loaded from " + filename);
return loadStatGroups(p);
} catch (IOException ioe) {
_log.error("Error loading the stat groups from " + f.getAbsolutePath(), ioe);
return new ArrayList();
}
}
private static List loadStatGroups(Properties props) {
List rv = new ArrayList(8);
int groupNum = 0;
while (true) {
String description = props.getProperty("statGroup." + groupNum + ".name");
if (description == null) break;
int detailNum = 0;
StatGroup group = new StatGroup(description);
while (true) {
String detailPrefix = "statGroup." + groupNum + ".detail." + detailNum + '.';
String name = props.getProperty(detailPrefix + "name");
if (name == null) break;
String option = props.getProperty(detailPrefix + "option");
if (option == null) break;
String field = props.getProperty(detailPrefix + "field");
if (field == null) break;
try {
int fieldNum = Integer.parseInt(field);
group.addStat(name, option, fieldNum);
} catch (NumberFormatException nfe) {
_log.warn("Unable to parse the field number from [" + field + "]", nfe);
break;
}
detailNum++;
}
rv.add(group);
groupNum++;
}
return rv;
}
}