package org.araqne.logstorage.exporter.main; import java.io.File; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Level; import org.apache.log4j.PatternLayout; import org.araqne.logstorage.exporter.ExportOption; import org.araqne.logstorage.exporter.api.LogDatFileReader; import org.araqne.logstorage.exporter.api.LogWriter; import org.araqne.logstorage.exporter.impl.FileWildcardMatcher; import org.araqne.logstorage.exporter.impl.LogCsvWriter; import org.araqne.logstorage.exporter.impl.LogDatFileReaderImpl; import org.araqne.logstorage.exporter.impl.LogJsonWriter; import org.araqne.logstorage.exporter.impl.LogTxtWriter; public class Console { public static void main(String[] args) { ConsoleAppender ca = new ConsoleAppender(new PatternLayout()); ca.setThreshold(Level.INFO); org.apache.log4j.BasicConfigurator.configure(ca); ExportOption option = getOptions(args); Set<File> matchedFiles = new HashSet<File>(); for (String filePath : option.getFilePaths()) { matchedFiles.addAll(findMatchedFiles(new File(filePath))); } for (File f : matchedFiles) { System.out.println("=======" + f.getAbsolutePath() + "======="); LogWriter writer = null; LogDatFileReader reader = null; long writeCount = 0; File outputFile = getOutputFile(option, f.getName()); if (outputFile.exists()) { System.out.println("output file already exists, path: " + outputFile.getAbsolutePath()); continue; } try { reader = new LogDatFileReaderImpl(f, option.getPfxFile(), option.getPassword()); writer = newWriter(outputFile, option); long base = System.currentTimeMillis(); boolean isEnd = false; while (!isEnd && reader.hasNext()) { long now = System.currentTimeMillis(); List<Map<String, Object>> logs = reader.nextBlock(); if (logs == null) break; for (Map<String, Object> log : logs) { writer.write(log); writeCount++; if (writeCount == option.getLimitCount()) { isEnd = true; break; } } if (!option.isUseStandardOutput() && now - base > 1000) { System.out.println("input: " + f.getName() + ", output: " + outputFile.getName() + ", " + writeCount + " logs written"); base = now; } } } catch (Exception e) { e.printStackTrace(); System.out.println(e.getMessage()); } finally { if (reader != null) reader.close(); if (writer != null) writer.close(); } System.out.println("output count: " + formatNumber(writeCount)); if (!option.isUseStandardOutput()) System.out.println("output file path: " + outputFile.getAbsolutePath()); System.out.println("=================end================\n"); } } private static ExportOption getOptions(String[] args) { if (args.length < 1) { System.out.println("cannot find target file"); throw new IllegalArgumentException("invalid argument"); } Map<String, String> opts = getOpts(args); ExportOption option = new ExportOption(); if (opts.containsKey("-F")) option.setOutputType(opts.get("-F")); String outputType = option.getOutputType(); if (!(outputType.equalsIgnoreCase("txt") || outputType.equalsIgnoreCase("json") || outputType.equalsIgnoreCase("csv"))) throw new IllegalArgumentException("invalid output type"); if (opts.containsKey("-c")) { List<String> columns = new ArrayList<String>(); String[] split = opts.get("-c").split(","); columns = new ArrayList<String>(); for (int index = 0; index < split.length; index++) columns.add(split[index].trim()); option.setColumns(columns); } if (opts.containsKey("-k")) { String s = opts.get("-k"); int comma = s.indexOf(","); if (comma == -1) throw new IllegalArgumentException("invalid pfx parameter"); String pfxPath = s.substring(0, comma); File pfxFile = new File(pfxPath); if (!pfxFile.exists()) throw new IllegalStateException("not-found-pfx-file"); option.setPfxFile(pfxFile); option.setPassword(s.substring(comma + 1)); } if (opts.containsKey("-l")) option.setLimitCount(Long.valueOf(opts.get("-l"))); option.setUseStandardOutput(opts.containsKey("-O")); option.setUseCompress(opts.containsKey("-z")); if (opts.containsKey("-d")) { String outputPath = opts.get("-d"); File outputDir = new File(outputPath); if (!outputDir.exists() || !outputDir.isDirectory()) outputDir.mkdir(); option.setOutputDir(outputDir); } else option.setOutputDir(new File(System.getProperty("user.dir"))); Set<String> fileNames = new HashSet<String>(); for (int index = opts.keySet().size(); index < args.length; index++) { String fileName = args[index]; if (fileName.endsWith("dat")) fileNames.add(fileName); } option.setFilePaths(fileNames); return option; } public static File getOutputFile(ExportOption option, String inputFileName) { String outputFileName = inputFileName.substring(0, inputFileName.lastIndexOf(".")) + "." + option.getOutputType(); if (!option.isUseStandardOutput() && option.isUseCompress()) outputFileName += ".gz"; return new File(option.getOutputDir(), outputFileName); } private static LogWriter newWriter(File outputFile, ExportOption option) throws IOException { String outputType = option.getOutputType(); if (outputType.equalsIgnoreCase("txt")) return new LogTxtWriter(outputFile, option); else if (outputType.equalsIgnoreCase("json")) return new LogJsonWriter(outputFile, option); else if (outputType.equalsIgnoreCase("csv")) return new LogCsvWriter(outputFile, option); else throw new UnsupportedOperationException("invalid output type"); } private static Set<File> findMatchedFiles(File baseFile) { Set<String> fileNames = new HashSet<String>(); File parentFile = baseFile.getParentFile(); if (parentFile == null) parentFile = new File(System.getProperty("user.dir")); for (File file : parentFile.listFiles()) { if (file.getName().endsWith("dat")) fileNames.add(file.getName()); } Set<File> targetFiles = new HashSet<File>(); for (String fileName : FileWildcardMatcher.apply(fileNames, baseFile.getName())) { targetFiles.add(new File(parentFile, fileName)); } return targetFiles; } private static Map<String, String> getOpts(String[] args) { String name = null; String value = ""; Map<String, String> opts = new HashMap<String, String>(); for (String arg : args) { if (arg.startsWith("-")) { if (name != null) { opts.put(name, value); value = ""; } name = arg; } else { value = arg; if (name != null) { opts.put(name, value); name = null; } } } return opts; } private static String formatNumber(long writeCount) { DecimalFormat formatter = new DecimalFormat("###,###"); return formatter.format(writeCount); } }