HBASE-23362: [WalPrettyPrinter] print/filter by table name. (#898)

Signed-off-by: Wellington Chevreuil <wchevreuil@apache.org>
This commit is contained in:
Bharath Vissapragada 2019-12-04 02:03:33 -08:00 committed by Wellington Ramos Chevreuil
parent f2f01ffe98
commit 570cc3c4a4
1 changed files with 61 additions and 20 deletions

View File

@ -34,6 +34,7 @@ import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HBaseInterfaceAudience; import org.apache.hadoop.hbase.HBaseInterfaceAudience;
import org.apache.hadoop.hbase.PrivateCellUtil; import org.apache.hadoop.hbase.PrivateCellUtil;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.Tag; import org.apache.hadoop.hbase.Tag;
import org.apache.hadoop.hbase.regionserver.wal.ProtobufLogReader; import org.apache.hadoop.hbase.regionserver.wal.ProtobufLogReader;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
@ -43,7 +44,6 @@ import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability; import org.apache.yetus.audience.InterfaceStability;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.gson.Gson; import org.apache.hbase.thirdparty.com.google.gson.Gson;
import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine; import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLineParser; import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLineParser;
@ -70,10 +70,15 @@ import org.apache.hbase.thirdparty.org.apache.commons.cli.PosixParser;
public class WALPrettyPrinter { public class WALPrettyPrinter {
private static final Logger LOG = LoggerFactory.getLogger(WALPrettyPrinter.class); private static final Logger LOG = LoggerFactory.getLogger(WALPrettyPrinter.class);
// Output template for pretty printing.
private static final String outputTmpl =
"Sequence=%s, table=%s, region=%s, at write timestamp=%s";
private boolean outputValues; private boolean outputValues;
private boolean outputJSON; private boolean outputJSON;
// The following enable filtering by sequence, region, and row, respectively // The following enable filtering by sequence, region, and row, respectively
private long sequence; private long sequence;
private String table;
private String region; private String region;
private String row; private String row;
// enable in order to output a single list of transactions from several files // enable in order to output a single list of transactions from several files
@ -93,6 +98,7 @@ public class WALPrettyPrinter {
outputValues = false; outputValues = false;
outputJSON = false; outputJSON = false;
sequence = -1; sequence = -1;
table = null;
region = null; region = null;
row = null; row = null;
persistentOutput = false; persistentOutput = false;
@ -112,6 +118,9 @@ public class WALPrettyPrinter {
* @param sequence * @param sequence
* when nonnegative, serves as a filter; only log entries with this * when nonnegative, serves as a filter; only log entries with this
* sequence id will be printed * sequence id will be printed
* @param table
* when non null, serves as a filter. only entries corresponding to this
* table will be printed.
* @param region * @param region
* when not null, serves as a filter; only log entries from this * when not null, serves as a filter; only log entries from this
* region will be printed * region will be printed
@ -126,11 +135,12 @@ public class WALPrettyPrinter {
* PrettyPrinter's output. * PrettyPrinter's output.
*/ */
public WALPrettyPrinter(boolean outputValues, boolean outputJSON, public WALPrettyPrinter(boolean outputValues, boolean outputJSON,
long sequence, String region, String row, boolean persistentOutput, long sequence, String table, String region, String row, boolean persistentOutput,
PrintStream out) { PrintStream out) {
this.outputValues = outputValues; this.outputValues = outputValues;
this.outputJSON = outputJSON; this.outputJSON = outputJSON;
this.sequence = sequence; this.sequence = sequence;
this.table = table;
this.region = region; this.region = region;
this.row = row; this.row = row;
this.persistentOutput = persistentOutput; this.persistentOutput = persistentOutput;
@ -180,6 +190,13 @@ public class WALPrettyPrinter {
this.sequence = sequence; this.sequence = sequence;
} }
/**
* Sets the table filter. Only log entries for this table are printed.
* @param table table name to set.
*/
public void setTableFilter(String table) {
this.table = table;
}
/** /**
* sets the region by which output will be filtered * sets the region by which output will be filtered
* *
@ -216,12 +233,14 @@ public class WALPrettyPrinter {
* the case of JSON output. * the case of JSON output.
*/ */
public void beginPersistentOutput() { public void beginPersistentOutput() {
if (persistentOutput) if (persistentOutput) {
return; return;
}
persistentOutput = true; persistentOutput = true;
firstTxn = true; firstTxn = true;
if (outputJSON) if (outputJSON) {
out.print("["); out.print("[");
}
} }
/** /**
@ -229,11 +248,13 @@ public class WALPrettyPrinter {
* case of JSON output. * case of JSON output.
*/ */
public void endPersistentOutput() { public void endPersistentOutput() {
if (!persistentOutput) if (!persistentOutput) {
return; return;
}
persistentOutput = false; persistentOutput = false;
if (outputJSON) if (outputJSON) {
out.print("]"); out.print("]");
}
} }
/** /**
@ -297,37 +318,46 @@ public class WALPrettyPrinter {
Map<String, Object> txn = key.toStringMap(); Map<String, Object> txn = key.toStringMap();
long writeTime = key.getWriteTime(); long writeTime = key.getWriteTime();
// check output filters // check output filters
if (sequence >= 0 && ((Long) txn.get("sequence")) != sequence) if (table != null && !((TableName) txn.get("table")).toString().equals(table)) {
continue; continue;
if (region != null && !((String) txn.get("region")).equals(region)) }
if (sequence >= 0 && ((Long) txn.get("sequence")) != sequence) {
continue; continue;
}
if (region != null && !txn.get("region").equals(region)) {
continue;
}
// initialize list into which we will store atomic actions // initialize list into which we will store atomic actions
List<Map> actions = new ArrayList<>(); List<Map> actions = new ArrayList<>();
for (Cell cell : edit.getCells()) { for (Cell cell : edit.getCells()) {
// add atomic operation to txn // add atomic operation to txn
Map<String, Object> op = new HashMap<>(toStringMap(cell)); Map<String, Object> op = new HashMap<>(toStringMap(cell));
if (outputValues) op.put("value", Bytes.toStringBinary(CellUtil.cloneValue(cell))); if (outputValues) {
op.put("value", Bytes.toStringBinary(CellUtil.cloneValue(cell)));
}
// check row output filter // check row output filter
if (row == null || ((String) op.get("row")).equals(row)) { if (row == null || ((String) op.get("row")).equals(row)) {
actions.add(op); actions.add(op);
} }
op.put("total_size_sum", cell.heapSize()); op.put("total_size_sum", cell.heapSize());
} }
if (actions.isEmpty()) if (actions.isEmpty()) {
continue; continue;
}
txn.put("actions", actions); txn.put("actions", actions);
if (outputJSON) { if (outputJSON) {
// JSON output is a straightforward "toString" on the txn object // JSON output is a straightforward "toString" on the txn object
if (firstTxn) if (firstTxn) {
firstTxn = false; firstTxn = false;
else } else {
out.print(","); out.print(",");
}
// encode and print JSON // encode and print JSON
out.print(GSON.toJson(txn)); out.print(GSON.toJson(txn));
} else { } else {
// Pretty output, complete with indentation by atomic action // Pretty output, complete with indentation by atomic action
out.println("Sequence=" + txn.get("sequence") + " " out.println(String.format(outputTmpl,
+ ", region=" + txn.get("region") + " at write timestamp=" + new Date(writeTime)); txn.get("sequence"), txn.get("table"), txn.get("region"), new Date(writeTime)));
for (int i = 0; i < actions.size(); i++) { for (int i = 0; i < actions.size(); i++) {
Map op = actions.get(i); Map op = actions.get(i);
out.println("row=" + op.get("row") + out.println("row=" + op.get("row") +
@ -335,7 +365,9 @@ public class WALPrettyPrinter {
if (op.get("tag") != null) { if (op.get("tag") != null) {
out.println(" tag: " + op.get("tag")); out.println(" tag: " + op.get("tag"));
} }
if (outputValues) out.println(" value: " + op.get("value")); if (outputValues) {
out.println(" value: " + op.get("value"));
}
out.println("cell total size sum: " + op.get("total_size_sum")); out.println("cell total size sum: " + op.get("total_size_sum"));
} }
} }
@ -393,6 +425,7 @@ public class WALPrettyPrinter {
options.addOption("h", "help", false, "Output help message"); options.addOption("h", "help", false, "Output help message");
options.addOption("j", "json", false, "Output JSON"); options.addOption("j", "json", false, "Output JSON");
options.addOption("p", "printvals", false, "Print values"); options.addOption("p", "printvals", false, "Print values");
options.addOption("t", "table", true, "Table name to filter by.");
options.addOption("r", "region", true, options.addOption("r", "region", true,
"Region to filter by. Pass encoded region name; e.g. '9192caead6a5a20acb4454ffbc79fa14'"); "Region to filter by. Pass encoded region name; e.g. '9192caead6a5a20acb4454ffbc79fa14'");
options.addOption("s", "sequence", true, options.addOption("s", "sequence", true,
@ -412,16 +445,24 @@ public class WALPrettyPrinter {
System.exit(-1); System.exit(-1);
} }
// configure the pretty printer using command line options // configure the pretty printer using command line options
if (cmd.hasOption("p")) if (cmd.hasOption("p")) {
printer.enableValues(); printer.enableValues();
if (cmd.hasOption("j")) }
if (cmd.hasOption("j")) {
printer.enableJSON(); printer.enableJSON();
if (cmd.hasOption("r")) }
if (cmd.hasOption("t")) {
printer.setTableFilter(cmd.getOptionValue("t"));
}
if (cmd.hasOption("r")) {
printer.setRegionFilter(cmd.getOptionValue("r")); printer.setRegionFilter(cmd.getOptionValue("r"));
if (cmd.hasOption("s")) }
if (cmd.hasOption("s")) {
printer.setSequenceFilter(Long.parseLong(cmd.getOptionValue("s"))); printer.setSequenceFilter(Long.parseLong(cmd.getOptionValue("s")));
if (cmd.hasOption("w")) }
if (cmd.hasOption("w")) {
printer.setRowFilter(cmd.getOptionValue("w")); printer.setRowFilter(cmd.getOptionValue("w"));
}
if (cmd.hasOption("g")) { if (cmd.hasOption("g")) {
printer.setPosition(Long.parseLong(cmd.getOptionValue("g"))); printer.setPosition(Long.parseLong(cmd.getOptionValue("g")));
} }