|
@@ -17,25 +17,22 @@
|
|
|
*/
|
|
|
package org.apache.zookeeper.graph;
|
|
|
|
|
|
-
|
|
|
-import org.json.simple.JSONArray;
|
|
|
-import org.json.simple.JSONObject;
|
|
|
-import org.json.simple.JSONValue;
|
|
|
-
|
|
|
-import java.io.Writer;
|
|
|
-import java.io.OutputStreamWriter;
|
|
|
-import java.io.IOException;
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.core.util.MinimalPrettyPrinter;
|
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
|
+import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
import java.util.regex.Pattern;
|
|
|
import java.util.regex.Matcher;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.Iterator;
|
|
|
-import java.util.LinkedList;
|
|
|
-import java.util.ListIterator;
|
|
|
import java.util.Set;
|
|
|
|
|
|
public class JsonGenerator {
|
|
|
- private JSONObject root;
|
|
|
- private Set<Integer> servers;
|
|
|
+ private final ObjectMapper mapper = new ObjectMapper();
|
|
|
+ private final JsonNode root;
|
|
|
+ private final Set<Integer> servers;
|
|
|
|
|
|
private class Message {
|
|
|
private int from;
|
|
@@ -55,170 +52,178 @@ public class JsonGenerator {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- public JSONObject txnEntry(TransactionEntry e) {
|
|
|
- JSONObject event = new JSONObject();
|
|
|
+ public JsonNode txnEntry(TransactionEntry e) {
|
|
|
+ JsonNode event = mapper.createObjectNode();
|
|
|
|
|
|
- event.put("time", Long.toString(e.getTimestamp()));
|
|
|
- event.put("client", Long.toHexString(e.getClientId()));
|
|
|
- event.put("cxid", Long.toHexString(e.getCxid()));
|
|
|
- event.put("zxid", Long.toHexString(e.getZxid()));
|
|
|
- event.put("op", e.getOp());
|
|
|
- event.put("extra", e.getExtra());
|
|
|
- event.put("type", "transaction");
|
|
|
+ ((ObjectNode) event).put("time", Long.toString(e.getTimestamp()));
|
|
|
+ ((ObjectNode) event).put("client", Long.toHexString(e.getClientId()));
|
|
|
+ ((ObjectNode) event).put("cxid", Long.toHexString(e.getCxid()));
|
|
|
+ ((ObjectNode) event).put("zxid", Long.toHexString(e.getZxid()));
|
|
|
+ ((ObjectNode) event).put("op", e.getOp());
|
|
|
+ ((ObjectNode) event).put("extra", e.getExtra());
|
|
|
+ ((ObjectNode) event).put("type", "transaction");
|
|
|
|
|
|
- return event;
|
|
|
+ return event;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
Assumes entries are sorted by timestamp.
|
|
|
*/
|
|
|
public JsonGenerator(LogIterator iter) {
|
|
|
- servers = new HashSet<Integer>();
|
|
|
+ servers = new HashSet<Integer>();
|
|
|
|
|
|
- Pattern stateChangeP = Pattern.compile("- (LOOKING|FOLLOWING|LEADING)");
|
|
|
- Pattern newElectionP = Pattern.compile("New election. My id = (\\d+), Proposed zxid = (\\d+)");
|
|
|
- Pattern receivedProposalP = Pattern.compile("Notification: (\\d+) \\(n.leader\\), (\\d+) \\(n.zxid\\), (\\d+) \\(n.round\\), .+ \\(n.state\\), (\\d+) \\(n.sid\\), .+ \\(my state\\)");
|
|
|
- Pattern exceptionP = Pattern.compile("xception");
|
|
|
-
|
|
|
- root = new JSONObject();
|
|
|
- Matcher m = null;
|
|
|
- JSONArray events = new JSONArray();
|
|
|
- root.put("events", events);
|
|
|
-
|
|
|
- long starttime = Long.MAX_VALUE;
|
|
|
- long endtime = 0;
|
|
|
-
|
|
|
- int leader = 0;
|
|
|
- long curEpoch = 0;
|
|
|
- boolean newEpoch = false;
|
|
|
-
|
|
|
- while (iter.hasNext()) {
|
|
|
- LogEntry ent = iter.next();
|
|
|
-
|
|
|
- if (ent.getTimestamp() < starttime) {
|
|
|
- starttime = ent.getTimestamp();
|
|
|
- }
|
|
|
- if (ent.getTimestamp() > endtime) {
|
|
|
- endtime = ent.getTimestamp();
|
|
|
- }
|
|
|
-
|
|
|
- if (ent.getType() == LogEntry.Type.TXN) {
|
|
|
- events.add(txnEntry((TransactionEntry)ent));
|
|
|
- } else {
|
|
|
- Log4JEntry e = (Log4JEntry)ent;
|
|
|
- servers.add(e.getNode());
|
|
|
-
|
|
|
- if ((m = stateChangeP.matcher(e.getEntry())).find()) {
|
|
|
- JSONObject stateChange = new JSONObject();
|
|
|
- stateChange.put("type", "stateChange");
|
|
|
- stateChange.put("time", e.getTimestamp());
|
|
|
- stateChange.put("server", e.getNode());
|
|
|
- stateChange.put("state", m.group(1));
|
|
|
- events.add(stateChange);
|
|
|
-
|
|
|
- if (m.group(1).equals("LEADING")) {
|
|
|
- leader = e.getNode();
|
|
|
- }
|
|
|
- } else if ((m = newElectionP.matcher(e.getEntry())).find()) {
|
|
|
- Iterator<Integer> iterator = servers.iterator();
|
|
|
- long zxid = Long.valueOf(m.group(2));
|
|
|
- int count = (int)zxid;// & 0xFFFFFFFFL;
|
|
|
- int epoch = (int)Long.rotateRight(zxid, 32);// >> 32;
|
|
|
-
|
|
|
- if (leader != 0 && epoch > curEpoch) {
|
|
|
- JSONObject stateChange = new JSONObject();
|
|
|
- stateChange.put("type", "stateChange");
|
|
|
- stateChange.put("time", e.getTimestamp());
|
|
|
- stateChange.put("server", leader);
|
|
|
- stateChange.put("state", "INIT");
|
|
|
- events.add(stateChange);
|
|
|
- leader = 0;
|
|
|
- }
|
|
|
-
|
|
|
- while (iterator.hasNext()) {
|
|
|
- int dst = iterator.next();
|
|
|
- if (dst != e.getNode()) {
|
|
|
- JSONObject msg = new JSONObject();
|
|
|
- msg.put("type", "postmessage");
|
|
|
- msg.put("src", e.getNode());
|
|
|
- msg.put("dst", dst);
|
|
|
- msg.put("time", e.getTimestamp());
|
|
|
- msg.put("zxid", m.group(2));
|
|
|
- msg.put("count", count);
|
|
|
- msg.put("epoch", epoch);
|
|
|
-
|
|
|
- events.add(msg);
|
|
|
+ Pattern stateChangeP = Pattern.compile("- (LOOKING|FOLLOWING|LEADING)");
|
|
|
+ Pattern newElectionP = Pattern.compile("New election. My id = (\\d+), Proposed zxid = (\\d+)");
|
|
|
+ Pattern receivedProposalP = Pattern.compile("Notification: (\\d+) \\(n.leader\\), (\\d+) \\(n.zxid\\), (\\d+) \\(n.round\\), .+ \\(n.state\\), (\\d+) \\(n.sid\\), .+ \\(my state\\)");
|
|
|
+ Pattern exceptionP = Pattern.compile("xception");
|
|
|
+
|
|
|
+ root = mapper.createObjectNode();
|
|
|
+ Matcher m = null;
|
|
|
+ ArrayNode events = mapper.createArrayNode();
|
|
|
+ ((ObjectNode)root).set("events", events);
|
|
|
+
|
|
|
+ long starttime = Long.MAX_VALUE;
|
|
|
+ long endtime = 0;
|
|
|
+
|
|
|
+ int leader = 0;
|
|
|
+ long curEpoch = 0;
|
|
|
+
|
|
|
+ while (iter.hasNext()) {
|
|
|
+ LogEntry ent = iter.next();
|
|
|
+
|
|
|
+ if (ent.getTimestamp() < starttime) {
|
|
|
+ starttime = ent.getTimestamp();
|
|
|
+ }
|
|
|
+ if (ent.getTimestamp() > endtime) {
|
|
|
+ endtime = ent.getTimestamp();
|
|
|
}
|
|
|
- }
|
|
|
- } else if ((m = receivedProposalP.matcher(e.getEntry())).find()) {
|
|
|
- // Pattern.compile("Notification: \\d+, (\\d+), (\\d+), \\d+, [^,]*, [^,]*, (\\d+)");//, LOOKING, LOOKING, 2
|
|
|
- int src = Integer.valueOf(m.group(4));
|
|
|
- long zxid = Long.valueOf(m.group(2));
|
|
|
- int dst = e.getNode();
|
|
|
- long epoch2 = Long.valueOf(m.group(3));
|
|
|
-
|
|
|
- int count = (int)zxid;// & 0xFFFFFFFFL;
|
|
|
- int epoch = (int)Long.rotateRight(zxid, 32);// >> 32;
|
|
|
-
|
|
|
- if (leader != 0 && epoch > curEpoch) {
|
|
|
- JSONObject stateChange = new JSONObject();
|
|
|
- stateChange.put("type", "stateChange");
|
|
|
- stateChange.put("time", e.getTimestamp());
|
|
|
- stateChange.put("server", leader);
|
|
|
- stateChange.put("state", "INIT");
|
|
|
- events.add(stateChange);
|
|
|
- leader = 0;
|
|
|
- }
|
|
|
-
|
|
|
- if (src != dst) {
|
|
|
- JSONObject msg = new JSONObject();
|
|
|
- msg.put("type", "delivermessage");
|
|
|
- msg.put("src", src);
|
|
|
- msg.put("dst", dst);
|
|
|
- msg.put("time", e.getTimestamp());
|
|
|
- msg.put("zxid", zxid);
|
|
|
- msg.put("epoch", epoch);
|
|
|
- msg.put("count", count);
|
|
|
- msg.put("epoch2", epoch2);
|
|
|
-
|
|
|
- events.add(msg);
|
|
|
- }
|
|
|
- } else if ((m = exceptionP.matcher(e.getEntry())).find()) {
|
|
|
- JSONObject ex = new JSONObject();
|
|
|
- ex.put("type", "exception");
|
|
|
- ex.put("server", e.getNode());
|
|
|
- ex.put("time", e.getTimestamp());
|
|
|
- ex.put("text", e.getEntry());
|
|
|
- events.add(ex);
|
|
|
- }
|
|
|
- }
|
|
|
- JSONObject ex = new JSONObject();
|
|
|
- ex.put("type", "text");
|
|
|
- ex.put("time", ent.getTimestamp());
|
|
|
- String txt = ent.toString();
|
|
|
- ex.put("text", txt);
|
|
|
- events.add(ex);
|
|
|
- }
|
|
|
- // System.out.println("pending messages: "+pendingMessages.size());
|
|
|
- root.put("starttime", starttime);
|
|
|
- root.put("endtime", endtime);
|
|
|
|
|
|
- JSONArray serversarray = new JSONArray();
|
|
|
- root.put("servers", serversarray);
|
|
|
-
|
|
|
- Iterator<Integer> iterator = servers.iterator();
|
|
|
- while (iterator.hasNext()) {
|
|
|
- serversarray.add(iterator.next());
|
|
|
- }
|
|
|
+ if (ent.getType() == LogEntry.Type.TXN) {
|
|
|
+ events.add(txnEntry((TransactionEntry)ent));
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Log4JEntry e = (Log4JEntry)ent;
|
|
|
+ servers.add(e.getNode());
|
|
|
+
|
|
|
+ if ((m = stateChangeP.matcher(e.getEntry())).find()) {
|
|
|
+ JsonNode stateChange = add("stateChange", e.getTimestamp(), e.getNode(), m.group(1));
|
|
|
+ events.add(stateChange);
|
|
|
+
|
|
|
+ if (m.group(1).equals("LEADING")) {
|
|
|
+ leader = e.getNode();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if ((m = newElectionP.matcher(e.getEntry())).find()) {
|
|
|
+ Iterator<Integer> iterator = servers.iterator();
|
|
|
+ long zxid = Long.valueOf(m.group(2));
|
|
|
+ int count = (int)zxid;// & 0xFFFFFFFFL;
|
|
|
+ int epoch = (int)Long.rotateRight(zxid, 32);// >> 32;
|
|
|
+
|
|
|
+ if (leader != 0 && epoch > curEpoch) {
|
|
|
+ JsonNode stateChange = add("stateChange", e.getTimestamp(), leader, "INIT");
|
|
|
+ events.add(stateChange);
|
|
|
+
|
|
|
+ leader = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ int dst = iterator.next();
|
|
|
+ if (dst != e.getNode()) {
|
|
|
+ JsonNode msg = mapper.createObjectNode();
|
|
|
+ ((ObjectNode)msg).put("type", "postmessage");
|
|
|
+ ((ObjectNode)msg).put("src", e.getNode());
|
|
|
+ ((ObjectNode)msg).put("dst", dst);
|
|
|
+ ((ObjectNode)msg).put("time", e.getTimestamp());
|
|
|
+ ((ObjectNode)msg).put("zxid", m.group(2));
|
|
|
+ ((ObjectNode)msg).put("count", count);
|
|
|
+ ((ObjectNode)msg).put("epoch", epoch);
|
|
|
+
|
|
|
+ events.add(msg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if ((m = receivedProposalP.matcher(e.getEntry())).find()) {
|
|
|
+ // Pattern.compile("Notification: \\d+, (\\d+), (\\d+), \\d+, [^,]*, [^,]*, (\\d+)");//, LOOKING, LOOKING, 2
|
|
|
+ int src = Integer.valueOf(m.group(4));
|
|
|
+ long zxid = Long.valueOf(m.group(2));
|
|
|
+ int dst = e.getNode();
|
|
|
+ long epoch2 = Long.valueOf(m.group(3));
|
|
|
+
|
|
|
+ int count = (int)zxid;// & 0xFFFFFFFFL;
|
|
|
+ int epoch = (int)Long.rotateRight(zxid, 32);// >> 32;
|
|
|
+
|
|
|
+ if (leader != 0 && epoch > curEpoch) {
|
|
|
+ JsonNode stateChange = add("stateChange", e.getTimestamp(), leader, "INIT");
|
|
|
+ events.add(stateChange);
|
|
|
+
|
|
|
+ leader = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (src != dst) {
|
|
|
+ JsonNode msg = mapper.createObjectNode();
|
|
|
+ ((ObjectNode)msg).put("type", "delivermessage");
|
|
|
+ ((ObjectNode)msg).put("src", src);
|
|
|
+ ((ObjectNode)msg).put("dst", dst);
|
|
|
+ ((ObjectNode)msg).put("time", e.getTimestamp());
|
|
|
+ ((ObjectNode)msg).put("zxid", zxid);
|
|
|
+ ((ObjectNode)msg).put("count", count);
|
|
|
+ ((ObjectNode)msg).put("epoch", epoch);
|
|
|
+ ((ObjectNode)msg).put("epoch2", epoch2);
|
|
|
+
|
|
|
+ events.add(msg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if ((m = exceptionP.matcher(e.getEntry())).find()) {
|
|
|
+ JsonNode ex = mapper.createObjectNode();
|
|
|
+ ((ObjectNode)ex).put("type", "exception");
|
|
|
+ ((ObjectNode)ex).put("time", e.getTimestamp());
|
|
|
+ ((ObjectNode)ex).put("server", e.getNode());
|
|
|
+ ((ObjectNode)ex).put("text", e.getEntry());
|
|
|
+ events.add(ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ JsonNode ex = mapper.createObjectNode();
|
|
|
+ ((ObjectNode)ex).put("type", "text");
|
|
|
+ ((ObjectNode)ex).put("time", ent.getTimestamp());
|
|
|
+ String txt = ent.toString();
|
|
|
+ ((ObjectNode)ex).put("text", txt);
|
|
|
+ events.add(ex);
|
|
|
+ }
|
|
|
+ // System.out.println("pending messages: "+pendingMessages.size());
|
|
|
+ ((ObjectNode)root).put("starttime", starttime);
|
|
|
+ ((ObjectNode)root).put("endtime", endtime);
|
|
|
+
|
|
|
+ ArrayNode serversarray = mapper.createArrayNode();
|
|
|
+ ((ObjectNode)root).set("servers", serversarray);
|
|
|
+
|
|
|
+ Iterator<Integer> iterator = servers.iterator();
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ serversarray.add(iterator.next());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+ private JsonNode add(String type, long timestamp, int node, String entry){
|
|
|
+ JsonNode stateChange = mapper.createObjectNode();
|
|
|
+ ((ObjectNode)stateChange).put("type", type);
|
|
|
+ ((ObjectNode)stateChange).put("time", timestamp);
|
|
|
+ ((ObjectNode)stateChange).put("server", node);
|
|
|
+ ((ObjectNode)stateChange).put("state", entry);
|
|
|
+ return stateChange;
|
|
|
+ }
|
|
|
+
|
|
|
public String toString() {
|
|
|
- return JSONValue.toJSONString(root);
|
|
|
+ String jsonString = null;
|
|
|
+ try {
|
|
|
+ jsonString = mapper.writer(new MinimalPrettyPrinter()).writeValueAsString(root);
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ jsonString = "{\"ERR\", " + e.getMessage() + "}";
|
|
|
+ }
|
|
|
+ return jsonString;
|
|
|
}
|
|
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
- MergedLogSource src = new MergedLogSource(args);
|
|
|
- LogIterator iter = src.iterator();
|
|
|
- System.out.println(new JsonGenerator(iter));
|
|
|
+ MergedLogSource src = new MergedLogSource(args);
|
|
|
+ LogIterator iter = src.iterator();
|
|
|
+ System.out.println(new JsonGenerator(iter));
|
|
|
}
|
|
|
}
|