001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.procedure2.store.wal; 019 020import java.io.IOException; 021import java.io.PrintStream; 022import java.util.ArrayList; 023import java.util.List; 024import org.apache.hadoop.conf.Configuration; 025import org.apache.hadoop.conf.Configured; 026import org.apache.hadoop.fs.FSDataInputStream; 027import org.apache.hadoop.fs.FileStatus; 028import org.apache.hadoop.fs.FileSystem; 029import org.apache.hadoop.fs.Path; 030import org.apache.hadoop.hbase.HBaseConfiguration; 031import org.apache.hadoop.hbase.HBaseInterfaceAudience; 032import org.apache.hadoop.hbase.procedure2.Procedure; 033import org.apache.hadoop.hbase.procedure2.ProcedureUtil; 034import org.apache.hadoop.util.Tool; 035import org.apache.hadoop.util.ToolRunner; 036import org.apache.yetus.audience.InterfaceAudience; 037import org.apache.yetus.audience.InterfaceStability; 038 039import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine; 040import org.apache.hbase.thirdparty.org.apache.commons.cli.DefaultParser; 041import org.apache.hbase.thirdparty.org.apache.commons.cli.HelpFormatter; 042import org.apache.hbase.thirdparty.org.apache.commons.cli.Options; 043import org.apache.hbase.thirdparty.org.apache.commons.cli.ParseException; 044 045import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureWALEntry; 046import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureWALHeader; 047 048/** 049 * ProcedureWALPrettyPrinter prints the contents of a given ProcedureWAL file 050 * @see WALProcedureStore#main(String[]) if you want to check parse of a directory of WALs. 051 * @deprecated Since 2.3.0, will be removed in 4.0.0. Keep here only for rolling upgrading, now we 052 * use the new region based procedure store. 053 */ 054@Deprecated 055@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS) 056@InterfaceStability.Evolving 057public class ProcedureWALPrettyPrinter extends Configured implements Tool { 058 private final PrintStream out; 059 060 public ProcedureWALPrettyPrinter() { 061 out = System.out; 062 } 063 064 /** 065 * Reads a log file and outputs its contents. 066 * 067 * @param conf HBase configuration relevant to this log file 068 * @param p path of the log file to be read 069 * @throws IOException IOException 070 */ 071 public void processFile(final Configuration conf, final Path p) 072 throws IOException { 073 074 FileSystem fs = p.getFileSystem(conf); 075 if (!fs.exists(p)) { 076 System.err.println("ERROR, file doesnt exist: " + p); 077 return; 078 } 079 if (!fs.isFile(p)) { 080 System.err.println(p + " is not a file"); 081 return; 082 } 083 084 FileStatus logFile = fs.getFileStatus(p); 085 if (logFile.getLen() == 0) { 086 out.println("Zero length file: " + p); 087 return; 088 } 089 090 out.println("Opening procedure state-log: " + p); 091 ProcedureWALFile log = new ProcedureWALFile(fs, logFile); 092 processProcedureWALFile(log); 093 } 094 095 public void processProcedureWALFile(ProcedureWALFile log) throws IOException { 096 log.open(); 097 ProcedureWALHeader header = log.getHeader(); 098 printHeader(header); 099 100 FSDataInputStream stream = log.getStream(); 101 try { 102 boolean hasMore = true; 103 while (hasMore) { 104 ProcedureWALEntry entry = ProcedureWALFormat.readEntry(stream); 105 if (entry == null) { 106 out.println("No more entry, exiting with missing EOF"); 107 hasMore = false; 108 break; 109 } 110 switch (entry.getType()) { 111 case PROCEDURE_WAL_EOF: 112 hasMore = false; 113 break; 114 default: 115 printEntry(entry); 116 } 117 } 118 } catch (IOException e) { 119 out.println("got an exception while reading the procedure WAL " + e.getMessage()); 120 } 121 finally { 122 log.close(); 123 } 124 } 125 126 private void printEntry(final ProcedureWALEntry entry) throws IOException { 127 out.println("EntryType=" + entry.getType()); 128 int procCount = entry.getProcedureCount(); 129 for (int i = 0; i < procCount; i++) { 130 Procedure<?> proc = ProcedureUtil.convertToProcedure(entry.getProcedure(i)); 131 printProcedure(proc); 132 } 133 } 134 135 private void printProcedure(Procedure<?> proc) { 136 out.println(proc.toStringDetails()); 137 } 138 139 private void printHeader(ProcedureWALHeader header) { 140 out.println("ProcedureWALHeader: "); 141 out.println(" Version: " + header.getVersion()); 142 out.println(" Type: " + header.getType()); 143 out.println(" LogId: " + header.getLogId()); 144 out.println(" MinProcId: " + header.getMinProcId()); 145 out.println(); 146 } 147 148 /** 149 * Pass one or more log file names and formatting options and it will dump out 150 * a text version of the contents on <code>stdout</code>. 151 * 152 * @param args 153 * Command line arguments 154 * @throws IOException 155 * Thrown upon file system errors etc. 156 */ 157 @Override 158 public int run(final String[] args) throws IOException { 159 // create options 160 Options options = new Options(); 161 options.addOption("h", "help", false, "Output help message"); 162 options.addOption("f", "file", true, "File to print"); 163 164 final List<Path> files = new ArrayList<>(); 165 try { 166 CommandLine cmd = new DefaultParser().parse(options, args); 167 168 if (cmd.hasOption("f")) { 169 files.add(new Path(cmd.getOptionValue("f"))); 170 } 171 172 if (files.isEmpty() || cmd.hasOption("h")) { 173 HelpFormatter formatter = new HelpFormatter(); 174 formatter.printHelp("ProcedureWALPrettyPrinter ", options, true); 175 return(-1); 176 } 177 } catch (ParseException e) { 178 e.printStackTrace(); 179 HelpFormatter formatter = new HelpFormatter(); 180 formatter.printHelp("ProcedureWALPrettyPrinter ", options, true); 181 return(-1); 182 } 183 // get configuration, file system, and process the given files 184 for (Path file : files) { 185 processFile(getConf(), file); 186 } 187 return(0); 188 } 189 190 public static void main(String[] args) throws Exception { 191 final Configuration conf = HBaseConfiguration.create(); 192 int exitCode = ToolRunner.run(conf, new ProcedureWALPrettyPrinter(), args); 193 System.exit(exitCode); 194 } 195}