View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.procedure2.store.wal;
19  
20  import java.io.IOException;
21  import java.io.PrintStream;
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import org.apache.commons.cli.CommandLine;
26  import org.apache.commons.cli.CommandLineParser;
27  import org.apache.commons.cli.HelpFormatter;
28  import org.apache.commons.cli.Options;
29  import org.apache.commons.cli.ParseException;
30  import org.apache.commons.cli.PosixParser;
31  import org.apache.hadoop.conf.Configuration;
32  import org.apache.hadoop.fs.FSDataInputStream;
33  import org.apache.hadoop.fs.FileStatus;
34  import org.apache.hadoop.fs.FileSystem;
35  import org.apache.hadoop.fs.Path;
36  import org.apache.hadoop.hbase.HBaseConfiguration;
37  import org.apache.hadoop.hbase.HBaseInterfaceAudience;
38  import org.apache.hadoop.hbase.classification.InterfaceAudience;
39  import org.apache.hadoop.hbase.classification.InterfaceStability;
40  import org.apache.hadoop.hbase.procedure2.Procedure;
41  import org.apache.hadoop.hbase.protobuf.generated.ProcedureProtos.ProcedureWALEntry;
42  import org.apache.hadoop.hbase.protobuf.generated.ProcedureProtos.ProcedureWALHeader;
43  
44  /**
45   * ProcedureWALPrettyPrinter prints the contents of a given ProcedureWAL file
46   */
47  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS)
48  @InterfaceStability.Evolving
49  public class ProcedureWALPrettyPrinter {
50    private PrintStream out;
51  
52    public ProcedureWALPrettyPrinter() {
53      out = System.out;
54    }
55  
56    /**
57     * Reads a log file and outputs its contents.
58     *
59     * @param conf   HBase configuration relevant to this log file
60     * @param p       path of the log file to be read
61     * @throws IOException  IOException
62     */
63    public void processFile(final Configuration conf, final Path p)
64        throws IOException {
65  
66      FileSystem fs = p.getFileSystem(conf);
67      if (!fs.exists(p)) {
68        System.err.println("ERROR, file doesnt exist: " + p);
69        return;
70      }
71      if (!fs.isFile(p)) {
72        System.err.println(p + " is not a file");
73        return;
74      }
75  
76      FileStatus logFile = fs.getFileStatus(p);
77      if (logFile.getLen() == 0) {
78        out.println("Zero length file: " + p);
79        return;
80      }
81  
82      out.println("Opening procedure state-log: " + p);
83      ProcedureWALFile log = new ProcedureWALFile(fs, logFile);
84      processProcedureWALFile(log);
85    }
86  
87    public void processProcedureWALFile(ProcedureWALFile log) throws IOException {
88  
89      log.open();
90      ProcedureWALHeader header = log.getHeader();
91      printHeader(header);
92  
93      FSDataInputStream stream = log.getStream();
94      try {
95        boolean hasMore = true;
96        while (hasMore) {
97          ProcedureWALEntry entry = ProcedureWALFormat.readEntry(stream);
98          if (entry == null) {
99            out.print("No more entry, exiting with missing EOF");
100           hasMore = false;
101           break;
102         }
103         switch (entry.getType()) {
104           case PROCEDURE_WAL_EOF:
105             hasMore = false;
106             break;
107           default:
108             printEntry(entry);
109         }
110       }
111     } catch (IOException e) {
112       out.print("got an exception while reading the procedure WAL " + e.getMessage());
113     }
114     finally {
115       log.close();
116     }
117   }
118 
119   private void printEntry(ProcedureWALEntry entry) throws IOException {
120     out.println("EntryType=" + entry.getType());
121     int procCount = entry.getProcedureCount();
122     for (int i = 0; i < procCount; i++) {
123       Procedure<?> proc = Procedure.convert(entry.getProcedure(i));
124       printProcedure(proc);
125     }
126   }
127 
128   private void printProcedure(Procedure<?> proc) {
129     out.println(proc.toStringDetails());
130   }
131 
132   private void printHeader(ProcedureWALHeader header) {
133     out.println("ProcedureWALHeader: ");
134     out.println("  Version: " + header.getVersion());
135     out.println("  Type: " + header.getType());
136     out.println("  LogId: " + header.getLogId());
137     out.println("  MinProcId: " + header.getMinProcId());
138     out.println();
139   }
140 
141   public static void main(String[] args) throws IOException {
142     run(args);
143   }
144 
145   /**
146    * Pass one or more log file names and formatting options and it will dump out
147    * a text version of the contents on <code>stdout</code>.
148    *
149    * @param args
150    *          Command line arguments
151    * @throws IOException
152    *           Thrown upon file system errors etc.
153    */
154   public static void run(String[] args) throws IOException {
155     // create options
156     Options options = new Options();
157     options.addOption("h", "help", false, "Output help message");
158     options.addOption("f", "file", true, "File to print");
159 
160     List<Path> files = new ArrayList<Path>();
161 
162     ProcedureWALPrettyPrinter printer = new ProcedureWALPrettyPrinter();
163     CommandLineParser parser = new PosixParser();
164     try {
165       CommandLine cmd = parser.parse(options, args);
166 
167       if (cmd.hasOption("f")) {
168         files.add(new Path(cmd.getOptionValue("f")));
169       }
170 
171       if (files.size() == 0 || cmd.hasOption("h")) {
172         HelpFormatter formatter = new HelpFormatter();
173         formatter.printHelp("ProcedureWALPrettyPrinter ", options, true);
174         System.exit(-1);
175       }
176 
177     } catch (ParseException e) {
178       e.printStackTrace();
179       HelpFormatter formatter = new HelpFormatter();
180       formatter.printHelp("ProcedureWALPrettyPrinter ", options, true);
181       System.exit(-1);
182     }
183     // get configuration, file system, and process the given files
184     Configuration conf = HBaseConfiguration.create();
185     for (Path file : files) {
186       printer.processFile(conf, file);
187     }
188   }
189 }