public void processFile(final Configuration conf, final Path p) throws IOException {
    FileSystem fs = p.getFileSystem(conf);
    if (!fs.exists(p)) {
      throw new FileNotFoundException(p.toString());
    }
    if (!fs.isFile(p)) {
      throw new IOException(p + " is not a file");
    }

    WALStreamReader log = WALFactory.createStreamReader(fs, p, conf, position > 0 ? position : -1);

    if (log instanceof AbstractProtobufWALReader) {
      List<String> writerClsNames = ((AbstractProtobufWALReader) log).getWriterClsNames();
      if (writerClsNames != null && writerClsNames.size() > 0) {
        out.print("Writer Classes: ");
        for (int i = 0; i < writerClsNames.size(); i++) {
          out.print(writerClsNames.get(i));
          if (i != writerClsNames.size() - 1) {
            out.print(" ");
          }
        }
        out.println();
      }

      String cellCodecClsName = ((AbstractProtobufWALReader) log).getCodecClsName();
      if (cellCodecClsName != null) {
        out.println("Cell Codec Class: " + cellCodecClsName);
      }
    }

    if (outputJSON && !persistentOutput) {
      out.print("[");
      firstTxn = true;
    }

    try {
      WAL.Entry entry;
      while ((entry = log.next()) != null) {
        WALKey key = entry.getKey();
        WALEdit edit = entry.getEdit();
        // begin building a transaction structure
        Map<String, Object> txn = key.toStringMap();
        long writeTime = key.getWriteTime();
        // check output filters
        if (!tableSet.isEmpty() && !tableSet.contains(txn.get("table").toString())) {
          continue;
        }
        if (sequence >= 0 && ((Long) txn.get("sequence")) != sequence) {
          continue;
        }
        if (region != null && !txn.get("region").equals(region)) {
          continue;
        }
        // initialize list into which we will store atomic actions
        List<Map<String, Object>> actions = new ArrayList<>();
        for (Cell cell : edit.getCells()) {
          assert cell instanceof ExtendedCell;
          // add atomic operation to txn
          Map<String, Object> op = new HashMap<>(
            toStringMap((ExtendedCell) cell, outputOnlyRowKey, rowPrefix, row, outputValues));
          if (op.isEmpty()) {
            continue;
          }
          actions.add(op);
        }
        if (actions.isEmpty()) {
          continue;
        }
        txn.put("actions", actions);
        if (outputJSON) {
          // JSON output is a straightforward "toString" on the txn object
          if (firstTxn) {
            firstTxn = false;
          } else {
            out.print(",");
          }
          // encode and print JSON
          out.print(GSON.toJson(txn));
        } else {
          // Pretty output, complete with indentation by atomic action
          if (!outputOnlyRowKey) {
            out.println(String.format(outputTmpl, txn.get("sequence"), txn.get("table"),
              txn.get("region"), new Date(writeTime)));
          }
          for (int i = 0; i < actions.size(); i++) {
            Map<String, Object> op = actions.get(i);
            printCell(out, op, outputValues, outputOnlyRowKey);
          }
        }
        if (!outputOnlyRowKey) {
          out.println("edit heap size: " + entry.getEdit().heapSize());
          out.println("position: " + log.getPosition());
        }
      }
    } finally {
      log.close();
    }
    if (outputJSON && !persistentOutput) {
      out.print("]");
    }
  }
reads a log file and outputs its contents, one transaction at a time, as specified by the
currently configured options the HBase configuration relevant to this log file the path of the
log file to be read may be unable to access the configured filesystem or requested file.
hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALPrettyPrinter.java