[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] [ernie/master 2/2] Add table of relay flags in votes and consensus to consensus-health.html.
Author: Karsten Loesing <karsten.loesing@xxxxxxx>
Date: Tue, 20 Apr 2010 15:50:35 +0200
Subject: Add table of relay flags in votes and consensus to consensus-health.html.
Commit: 6ed94820fc7f2d376a857847a9f0f2a0dc5e73eb
---
src/ConsensusHealthChecker.java | 132 ++++++++++++++++++++++++++++++++++++--
1 files changed, 125 insertions(+), 7 deletions(-)
diff --git a/src/ConsensusHealthChecker.java b/src/ConsensusHealthChecker.java
index 10eef35..a86dcea 100644
--- a/src/ConsensusHealthChecker.java
+++ b/src/ConsensusHealthChecker.java
@@ -2,6 +2,7 @@ import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
+import org.apache.commons.codec.binary.*;
/*
* TODO Possible extensions:
@@ -60,12 +61,18 @@ public class ConsensusHealthChecker {
StringBuilder paramsResults = new StringBuilder();
StringBuilder authorityKeysResults = new StringBuilder();
StringBuilder bandwidthScannersResults = new StringBuilder();
+ SortedSet<String> allKnownFlags = new TreeSet<String>();
+ SortedSet<String> allKnownVotes = new TreeSet<String>();
+ SortedMap<String, String> consensusAssignedFlags =
+ new TreeMap<String, String>();
+ SortedMap<String, SortedSet<String>> votesAssignedFlags =
+ new TreeMap<String, SortedSet<String>>();
/* Read consensus and parse all information that we want to compare to
* votes. */
String consensusConsensusMethod = null, consensusKnownFlags = null,
consensusClientVersions = null, consensusServerVersions = null,
- consensusParams = null;
+ consensusParams = null, rLineTemp = null;
int consensusTotalRelays = 0, consensusRunningRelays = 0;
Scanner s = new Scanner(new String(this.mostRecentConsensus));
while (s.hasNextLine()) {
@@ -80,11 +87,16 @@ public class ConsensusHealthChecker {
consensusKnownFlags = line;
} else if (line.startsWith("params ")) {
consensusParams = line;
+ } else if (line.startsWith("r ")) {
+ rLineTemp = line;
} else if (line.startsWith("s ")) {
consensusTotalRelays++;
if (line.contains(" Running")) {
consensusRunningRelays++;
}
+ consensusAssignedFlags.put(Hex.encodeHexString(
+ Base64.decodeBase64(rLineTemp.split(" ")[2] + "=")).
+ toUpperCase() + " " + rLineTemp.split(" ")[1], line);
}
}
s.close();
@@ -94,8 +106,7 @@ public class ConsensusHealthChecker {
for (byte[] voteBytes : this.mostRecentVotes.values()) {
String voteConsensusMethods = null, voteKnownFlags = null,
voteClientVersions = null, voteServerVersions = null,
- voteParams = null, voteDirSourceLine = null,
- voteDirKeyExpires = null;
+ voteParams = null, dirSource = null, voteDirKeyExpires = null;
int voteTotalRelays = 0, voteRunningRelays = 0,
voteContainsBandwidthWeights = 0;
s = new Scanner(new String(voteBytes));
@@ -112,14 +123,28 @@ public class ConsensusHealthChecker {
} else if (line.startsWith("params ")) {
voteParams = line;
} else if (line.startsWith("dir-source ")) {
- voteDirSourceLine = line;
+ dirSource = line.split(" ")[1];
+ allKnownVotes.add(dirSource);
} else if (line.startsWith("dir-key-expires ")) {
voteDirKeyExpires = line;
+ } else if (line.startsWith("r ")) {
+ rLineTemp = line;
} else if (line.startsWith("s ")) {
voteTotalRelays++;
if (line.contains(" Running")) {
voteRunningRelays++;
}
+ String relayKey = Hex.encodeHexString(Base64.decodeBase64(
+ rLineTemp.split(" ")[2] + "=")).toUpperCase() + " "
+ + rLineTemp.split(" ")[1];
+ SortedSet<String> sLines = null;
+ if (votesAssignedFlags.containsKey(relayKey)) {
+ sLines = votesAssignedFlags.get(relayKey);
+ } else {
+ sLines = new TreeSet<String>();
+ votesAssignedFlags.put(relayKey, sLines);
+ }
+ sLines.add(dirSource + " " + line);
} else if (line.startsWith("w ")) {
if (line.contains(" Measured")) {
voteContainsBandwidthWeights++;
@@ -128,14 +153,15 @@ public class ConsensusHealthChecker {
}
s.close();
- /* Remember authority nickname. */
- String dirSource = voteDirSourceLine.split(" ")[1];
-
/* Write known flags. */
knownFlagsResults.append(" <tr>\n"
+ " <td>" + dirSource + "</td>\n"
+ " <td>" + voteKnownFlags + "</td>\n"
+ " </tr>\n");
+ for (String flag : voteKnownFlags.substring(
+ "known-flags ".length()).split(" ")) {
+ allKnownFlags.add(flag);
+ }
/* Write number of relays voted about. */
numRelaysVotesResults.append(" <tr>\n"
@@ -484,6 +510,98 @@ public class ConsensusHealthChecker {
}
bw.write(" </table>\n");
+ /* Write (huge) table with all flags. */
+ bw.write(" <br/>\n"
+ + " <h3>Relay flags</h3>\n"
+ + " <table border=\"0\" cellpadding=\"4\" "
+ + "cellspacing=\"0\" summary=\"\">\n"
+ + " <colgroup>\n"
+ + " <col width=\"120\">\n"
+ + " <col width=\"80\">\n");
+ for (int i = 0; i < allKnownVotes.size(); i++) {
+ bw.write(" <col width=\""
+ + (640 / allKnownVotes.size()) + "\">\n");
+ }
+ bw.write(" </colgroup>\n");
+ int linesWritten = 0;
+ for (Map.Entry<String, SortedSet<String>> e :
+ votesAssignedFlags.entrySet()) {
+ if (linesWritten++ % 10 == 0) {
+ bw.write(" <tr><td/><td/>\n");
+ for (String dir : allKnownVotes) {
+ String shortDirName = dir.length() > 6 ?
+ dir.substring(0, 5) + "." : dir;
+ bw.write("<td><br/><b>" + shortDirName + "</b></td>");
+ }
+ bw.write("</tr>\n");
+ }
+ String relayKey = e.getKey();
+ SortedSet<String> votes = e.getValue();
+ String fingerprint = relayKey.split(" ")[0].substring(0, 8);
+ String nickname = relayKey.split(" ")[1];
+ bw.write(" <tr>\n"
+ + " <td>" + fingerprint + "</td>\n"
+ + " <td>" + nickname + "</td>\n");
+ SortedSet<String> relevantFlags = new TreeSet<String>();
+ for (String vote : votes) {
+ String[] parts = vote.split(" ");
+ for (int j = 2; j < parts.length; j++) {
+ relevantFlags.add(parts[j]);
+ }
+ }
+ String consensusFlags = null;
+ if (consensusAssignedFlags.containsKey(relayKey)) {
+ consensusFlags = consensusAssignedFlags.get(relayKey);
+ String[] parts = consensusFlags.split(" ");
+ for (int j = 1; j < parts.length; j++) {
+ relevantFlags.add(parts[j]);
+ }
+ }
+ for (String dir : allKnownVotes) {
+ String flags = null;
+ for (String vote : votes) {
+ if (vote.startsWith(dir)) {
+ flags = vote;
+ break;
+ }
+ }
+ if (flags != null) {
+ votes.remove(flags);
+ bw.write(" <td>");
+ int flagsWritten = 0;
+ for (String flag : relevantFlags) {
+ bw.write(flagsWritten++ > 0 ? "<br/>" : "");
+ if (flags.contains(" " + flag)) {
+ if (consensusFlags == null ||
+ consensusFlags.contains(" " + flag)) {
+ bw.write(flag);
+ } else {
+ bw.write("<font color=\"red\">" + flag + "</font>");
+ }
+ }
+ }
+ bw.write("</td>\n");
+ } else {
+ bw.write(" <td/>\n");
+ }
+ }
+ if (consensusFlags != null) {
+ bw.write(" <td>");
+ int flagsWritten = 0;
+ for (String flag : relevantFlags) {
+ bw.write(flagsWritten++ > 0 ? "<br/>" : "");
+ if (consensusFlags.contains(" " + flag)) {
+ bw.write("<font color=\"blue\">" + flag + "</font>");
+ }
+ }
+ bw.write("</td>\n");
+ } else {
+ bw.write(" <td/>\n");
+ }
+ bw.write(" </tr>\n");
+ }
+ bw.write(" </table>\n");
+
/* Finish writing. */
bw.write(" </div>\n"
+ " </div>\n"
--
1.6.5