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

Reapplied with missing delta for branch-1

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 Andrew Purtell
parent d77da0dcfc
commit 85b43a7059
No known key found for this signature in database
GPG Key ID: 8597754DD5365CCD
2 changed files with 75 additions and 27 deletions

View File

@ -67,7 +67,7 @@ public class HLogPrettyPrinter extends WALPrettyPrinter {
* Basic constructor that simply initializes values to reasonable defaults. * Basic constructor that simply initializes values to reasonable defaults.
*/ */
public HLogPrettyPrinter() { public HLogPrettyPrinter() {
this(false, false, -1l, null, null, false, System.out); this(false, false, -1l, null, null, null, false, System.out);
} }
/** /**
@ -82,6 +82,9 @@ public class HLogPrettyPrinter extends 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 not null, serves as a filter; only log entries from 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
@ -96,9 +99,9 @@ public class HLogPrettyPrinter extends WALPrettyPrinter {
* PrettyPrinter's output. * PrettyPrinter's output.
*/ */
public HLogPrettyPrinter(boolean outputValues, boolean outputJSON, public HLogPrettyPrinter(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) {
super(outputValues, outputJSON, sequence, region, row, persistentOutput, out); super(outputValues, outputJSON, sequence, table, region, row, persistentOutput, out);
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {

View File

@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil; 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.TableName;
import org.apache.hadoop.hbase.Tag; import org.apache.hadoop.hbase.Tag;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.FSUtils; import org.apache.hadoop.hbase.util.FSUtils;
@ -51,6 +52,8 @@ import org.apache.hadoop.hbase.regionserver.wal.ProtobufLogReader;
// imports for things that haven't moved yet. // imports for things that haven't moved yet.
import org.apache.hadoop.hbase.regionserver.wal.WALEdit; import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
import org.apache.hbase.thirdparty.com.google.gson.Gson; import org.apache.hbase.thirdparty.com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
@ -69,10 +72,17 @@ import org.apache.hbase.thirdparty.com.google.gson.Gson;
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS) @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS)
@InterfaceStability.Evolving @InterfaceStability.Evolving
public class WALPrettyPrinter { public class WALPrettyPrinter {
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
@ -92,6 +102,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;
@ -111,6 +122,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
@ -125,12 +139,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 long sequence, String table, String region, String row, boolean persistentOutput,
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 +194,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
* *
@ -207,12 +228,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("[");
}
} }
/** /**
@ -220,11 +243,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("]");
}
} }
/** /**
@ -288,16 +313,23 @@ 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<Map>(); List<Map<String, Object>> actions = new ArrayList<Map<String, Object>>();
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<String, Object>(toStringMap(cell)); Map<String, Object> op = new HashMap<>(toStringMap(cell));
if (outputValues) op.put("value", Bytes.toStringBinary(cell.getValue())); 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);
@ -305,29 +337,33 @@ public class WALPrettyPrinter {
op.put("total_size_sum", CellUtil.estimatedHeapSizeOf(cell)); op.put("total_size_sum", CellUtil.estimatedHeapSizeOf(cell));
} }
if (actions.size() == 0) 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<String, Object> op = actions.get(i);
out.println("row=" + op.get("row") + out.println("row=" + op.get("row") +
", column=" + op.get("family") + ":" + op.get("qualifier")); ", column=" + op.get("family") + ":" + op.get("qualifier"));
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"));
} }
} }
@ -386,6 +422,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,
@ -405,21 +442,29 @@ 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")));
} }
} catch (ParseException e) { } catch (ParseException e) {
e.printStackTrace(); LOG.error("Failed to parse commandLine arguments", e);
HelpFormatter formatter = new HelpFormatter(); HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("HFile filename(s) ", options, true); formatter.printHelp("HFile filename(s) ", options, true);
System.exit(-1); System.exit(-1);