org.jgroups.tests.ParseMessagesFields Maven / Gradle / Ivy
package org.jgroups.tests;
import org.jgroups.Message;
import org.jgroups.stack.GossipData;
import org.jgroups.util.MessageBatch;
import java.io.*;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* While investigating network errors, we would like to look for timestamp and JGroups data.
* But when needed, we need to add more fields like source and destination ports.
*
* Example: tshark -q -i lo0 -Tfields -e frame.time_epoch -e udp.srcport -e udp.dstport -e data udp and port 9090
*
* Run: ParseMessages -instance org.jgroups.tests.ParseMessagesFields -Dfields="frame.time_epoch,udp.srcport,udp.dstport"
*/
public class ParseMessagesFields extends ParseMessages {
private static final DateTimeFormatter TIME_EPOCH_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss,SSS");
private static final ZoneId ZONE_ID=ZoneId.systemDefault();
private static String[] fields;
static {
String fieldsArgument = System.getProperty("fields");
if (fieldsArgument != null) {
fields = fieldsArgument.split(",");
}
}
@Override
protected InputStream createInputStream(InputStream in) {
return new BinaryToAsciiWithFieldsInputStream(in);
}
@Override
public void parse(InputStream in, BiConsumer msg_consumer,
BiConsumer batch_consumer, Consumer gossip_consumer,
boolean tcp, boolean gossip) {
parseWithFields(in, msg_consumer, batch_consumer, tcp, gossip);
}
public static class BinaryToAsciiWithFieldsInputStream extends ParseMessages.BinaryToAsciiInputStream {
public BinaryToAsciiWithFieldsInputStream(InputStream in) {
super(in);
}
public String readIntegerAsStr() throws IOException {
String str = "";
while (true) {
input[0] = (byte)in.read();
if (input[0] == '\t') {
break;
}
input[1] = (byte)in.read();
// tshark \t separator
if (input[1] == '\t') {
str += new String(new byte[]{input[0]});
break;
} else {
str += new String(input);
}
}
return str;
}
public String readEpochTime() throws IOException {
String timestamp="";
while (timestamp.length() != 20) {
input[0] = (byte)in.read();
if (input[0] == '\n' || input[0] == '\r') {
continue;
}
input[1] = (byte)in.read();
// end of file
if (input[0] == -1 || input[1] == -1) {
throw new EOFException();
}
timestamp+=new String(input);
}
// tshark \t separator
readPlainByte();
String[] time = timestamp.split("\\.");
long epochMilli = Long.valueOf(time[0]) * 1000;
long nanos = Long.valueOf(time[1]);
ZonedDateTime zonedDateTime = Instant.ofEpochMilli(epochMilli).plusNanos(nanos).atZone(ZONE_ID);
String epochTime = TIME_EPOCH_DATE_TIME_FORMATTER.format(zonedDateTime);
return epochTime;
}
public byte readPlainByte() throws IOException {
return (byte)in.read();
}
}
public void parseWithFields(InputStream input, BiConsumer msg_consumer,
BiConsumer batch_consumer, boolean tcp, boolean gossip) {
try {
for(;;) {
// parse fields
String[] fieldValues = new String[fields.length];
BinaryToAsciiWithFieldsInputStream cast = ((BinaryToAsciiWithFieldsInputStream) input);
for (int i = 0; i < fields.length; i++) {
String field = fields[i];
if ("frame.time_epoch".equals(field)) {
fieldValues[i] = cast.readEpochTime();
} else if (field.contains(".srcport")) {
fieldValues[i] = cast.readIntegerAsStr();
} else if (field.contains(".dstport")) {
fieldValues[i] = cast.readIntegerAsStr();
} else {
throw new RuntimeException(String.format("%s not implemented", field));
}
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// after the \t separator, the data field could be empty
for(;;) {
byte b = cast.readPlainByte();
if (b == '\n' || b == '\r' || b == -1) {
break;
}
outputStream.write(b);
}
if (outputStream.size() != 0) {
for (String fieldValue : fieldValues) {
System.out.print(fieldValue + " ");
}
super.parse(new BinaryToAsciiInputStream(new ByteArrayInputStream(outputStream.toByteArray())),
msg_consumer, batch_consumer, null, tcp, false);
}
}
} catch(EOFException ignored) {
//ignored.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy