/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2002 * Copyright by ESO (in the framework of the ALMA collaboration) * and Cosylab 2002, All rights reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package alma.acs.logging.tools; import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.Pattern; import alma.acs.util.CmdLineArgs; import alma.acs.util.CmdLineOption; import alma.acs.util.CmdLineRegisteredOption; /** * A coommand line tool to perform some helpful operation * with the files of logs * * @author acaproni * */ public class LogAssistant { /** * The format of the date is the same as the ILogEntry without msecs */ public static final String TIME_FORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ss"; /** * The command to execute */ private char command; // -x, -p, -h /** * The start and end date for extraction */ private Date startDate=null, endDate=null; /** * The name of the filter file for extraction */ private String filterFileName=null; /** * The number of logs per file for splitting */ private Integer num=null; /** * The number of minutes per file while splitting */ private Integer minutes=null; /** * The name of the source file */ private String[] sourceFileNames=null; /** * The name of the file generated by the process * <P> * While splitting the process generates more file appending a * sequencial number to this string */ private String destFileName=null; /** * The converter to save the logs in the preferred format. */ private LogConverter converter; /** * The index and order of the cols to write if the output is not XML */ private String cols=null; /** * Constructor * * @param args The command line params */ public LogAssistant(String[] args) { // Parse the command line parseCommandLine(args); } public void work() throws Exception { if (checkState()) { if (command=='x') { extractLogs(); } else if (command=='p') { splitFile(); } } } /** * Parse the command line and fill the internal variables * Throws an IllegalStateException if an error arises while parsing * like for example invalid parameters. * * @param params The parameters in the command line * @throws IllegalStateException If the parameters in the command line are invalid */ private void parseCommandLine(String[] params) throws IllegalStateException { CmdLineArgs cmdLineArgs = new CmdLineArgs(); // help / usage is a special case CmdLineRegisteredOption helpCmd = new CmdLineRegisteredOption("-h","-help",0); cmdLineArgs.registerOption(helpCmd); if (params.length == 1) { cmdLineArgs.parseArgs(params); if (cmdLineArgs.isSpecified(helpCmd)) { command='h'; return; } } if (params.length<5) { // The param must be at least 5: // -command (-split) // at least one parameter for the command and its value (-time val) // source // destination throw new IllegalStateException("Wrong number of params"); } CmdLineRegisteredOption extractCmd = new CmdLineRegisteredOption("-x","-extract",0); cmdLineArgs.registerOption(extractCmd); CmdLineRegisteredOption splitCmd = new CmdLineRegisteredOption("-p","-split",0); cmdLineArgs.registerOption(splitCmd); CmdLineRegisteredOption csvOtuputFormat = new CmdLineRegisteredOption("-csv",0); cmdLineArgs.registerOption(csvOtuputFormat); CmdLineRegisteredOption txtOtuputFormat = new CmdLineRegisteredOption("-txt",0); cmdLineArgs.registerOption(txtOtuputFormat); CmdLineRegisteredOption xmlOtuputFormat = new CmdLineRegisteredOption("-xml",0); cmdLineArgs.registerOption(xmlOtuputFormat); CmdLineRegisteredOption twikiOtuputFormat = new CmdLineRegisteredOption("-twiki",0); cmdLineArgs.registerOption(twikiOtuputFormat); CmdLineRegisteredOption startTime = new CmdLineRegisteredOption("-s","-start",1); cmdLineArgs.registerOption(startTime); CmdLineRegisteredOption endTime = new CmdLineRegisteredOption("-e","-end",1); cmdLineArgs.registerOption(endTime); CmdLineRegisteredOption filterName = new CmdLineRegisteredOption("-f","-filter",1); cmdLineArgs.registerOption(filterName); CmdLineRegisteredOption time = new CmdLineRegisteredOption("-t","-time",1); cmdLineArgs.registerOption(time); CmdLineRegisteredOption number = new CmdLineRegisteredOption("-n","-num",1); cmdLineArgs.registerOption(number); CmdLineRegisteredOption columns = new CmdLineRegisteredOption("-l","-col",0); cmdLineArgs.registerOption(columns); CmdLineRegisteredOption dstFileOption = new CmdLineRegisteredOption("-dest",1); cmdLineArgs.registerOption(dstFileOption); CmdLineRegisteredOption sourceFilesOption = new CmdLineRegisteredOption("-src",1); cmdLineArgs.registerOption(sourceFilesOption); cmdLineArgs.parseArgs(params); // Command==Extract if (cmdLineArgs.isSpecified(extractCmd)) { command='x'; } // Command==split if (cmdLineArgs.isSpecified(splitCmd)) { command='p'; } // Start date if (cmdLineArgs.isSpecified(startTime)) { String[] val = cmdLineArgs.getValues(startTime); if (val==null || val.length<1) { throw new IllegalStateException("Start date missing/wrong "+TIME_FORMAT); } try { startDate=getDate(val[0]); } catch (ParseException e) { throw new IllegalStateException("Wrong date format "+TIME_FORMAT); } } // End date if (cmdLineArgs.isSpecified(endTime)) { String[] val = cmdLineArgs.getValues(endTime); if (val==null || val.length<1) { throw new IllegalStateException("End date missing/wrong "+TIME_FORMAT); } try { endDate=getDate(val[0]); } catch (ParseException e) { throw new IllegalStateException("Wrong date format "+TIME_FORMAT); } } // Filter name if (cmdLineArgs.isSpecified(filterName)) { String[] val = cmdLineArgs.getValues(filterName); if (val==null || val.length<1) { throw new IllegalStateException("Wrong or missing filter name"); } filterFileName=val[0]; } // Time if (cmdLineArgs.isSpecified(time)) { String[] val = cmdLineArgs.getValues(time); if (val==null || val.length<1) { throw new IllegalStateException("Wrong or missing time (minutes)"); } try { minutes=Integer.parseInt(val[0]); } catch (NumberFormatException e) { throw new IllegalStateException("Wrong format for the time (minutes)"); } } // Number if (cmdLineArgs.isSpecified(number)) { String[] val = cmdLineArgs.getValues(number); if (val==null || val.length<1) { throw new IllegalStateException("Wrong or missing time (minutes)"); } try { num=Integer.parseInt(val[0]); } catch (NumberFormatException e) { throw new IllegalStateException("Wrong format for the number of logs"); } } // Col if (cmdLineArgs.isSpecified(columns)) { String[] val = cmdLineArgs.getValues(columns); if (val==null || val.length<1) { throw new IllegalStateException("Wrong or missing time (minutes)"); } cols=val[0]; } // Output format int count=0; // How many output options? if (cmdLineArgs.isSpecified(csvOtuputFormat)) { System.out.println("Set output format to CSV"); converter=new CSVConverter(cols); count++; } if (cmdLineArgs.isSpecified(xmlOtuputFormat)) { System.out.println("Set output format to XML"); converter=new XMLConverter(); count++; } if (cmdLineArgs.isSpecified(txtOtuputFormat)) { System.out.println("Set output format to plain ASCII text"); converter=new TextConverter(cols); count++; } if (cmdLineArgs.isSpecified(twikiOtuputFormat)) { System.out.println("Set output format to Twiki table"); converter=new TwikiTableConverter(cols); count++; } if (count==0) { // No converter ==> Use XML by default converter=new XMLConverter(); System.out.println("No output format specified: using default XML."); } else if (count>1) { // Too many output formats throw new IllegalStateException("Too many output format specified."); } // SOURCES if (cmdLineArgs.isSpecified(sourceFilesOption)) { sourceFileNames = cmdLineArgs.getValues(sourceFilesOption); if (sourceFileNames==null || sourceFileNames.length<1) { throw new IllegalStateException("Wrong or missing source file names"); } } else { // This is not an error: if the param is missing, the // the tool read logs from the command line } // DESTINATION if (cmdLineArgs.isSpecified(dstFileOption)) { String[] val = cmdLineArgs.getValues(dstFileOption); if (val==null || val.length<1) { throw new IllegalStateException("Wrong or missing time (minutes)"); } destFileName=val[0]; } else { throw new IllegalStateException("No destination file in command line."); } } /** * Check the state of the variables. * This method checks if the internal variables are set in the right way * It is usually executed before running a command * * @return If the state is correct */ private boolean checkState() { if (command!='x' && command!='p' && command!='h') { System.out.println("Wrong command "+command); return false; } if (command=='x') { if (endDate==null && startDate==null && filterFileName==null) { System.out.println("Selected extraction withouth criteria"); System.out.println("Please, set start date and/or end date and/or a filter file name"); return false; } if (filterFileName!=null) { if (filterFileName.length()==0) { System.out.println("Invalid empty name for the filter"); return false; } File filterFile = new File(filterFileName); if (!filterFile.exists()) { System.err.println(filterFileName+" does not exist!"); return false; } if (!filterFile.canRead()) { System.out.println(filterFileName+" is unreadable"); return false; } // todo: print about using the filter } if (minutes!=null || num!=null) { System.out.println("Warning: minutes and number of logs are ignored while eXtracting"); } } else if (command=='p') { if (num==null && minutes==null) { System.out.println("Splitting selected without criteria"); System.out.println("Please, set the number of log or the time"); return false; } if (num!=null && minutes!=null) { System.out.println("Set only one between number of logs and time to sPlit"); return false; } if (startDate!=null || endDate!=null || filterFileName!=null) { System.out.println("Warning: start date, end date and the filter are ignored while sPlitting"); } } // Check if the input files exist and are readable if (sourceFileNames!=null) { for (String fileName: sourceFileNames) { if (fileName==null || fileName.isEmpty()) { System.out.println("Invalid source file name: "+fileName); return false; } File inF = new File(fileName); if (!inF.exists()) { System.err.println(fileName+" does not exist!"); return false; } if (!inF.canRead()) { System.out.println(fileName+" is unreadable"); return false; } } } return true; } /** * Parse the given string into a Date * * @param date The string representing the date * @return A Date obtained parsing the string * @throws ParseException If an error happen getting the date from the string */ private Date getDate(String date) throws ParseException { SimpleDateFormat df = new SimpleDateFormat(TIME_FORMAT); return df.parse(date); } /** * Extract the logs from the source to the destination file * */ private void extractLogs() throws Exception { LogFileExtractor extractor = new LogFileExtractor( sourceFileNames, destFileName, startDate, endDate, filterFileName, converter); extractor.extract(); } /** * Split the input log file in several files * */ private void splitFile() throws Exception { LogFileSplitter fileSplitter = new LogFileSplitter( sourceFileNames, destFileName, num, minutes, converter); fileSplitter.split(); } /** * Print a usage message on screen * * @param prgName The program name */ private static void usage(String prgName) { System.out.println("USAGE: "+prgName+" command command_params [options] -dest <FileName> [-src <FileName> <FileName> ....]"); System.out.println("command:"); System.out.println("\t-extract|-x: extract logs depending on the command_params criteria"); System.out.println("\tcommand_params for extraction (applied as AND):"); System.out.println("\t\t-start|-s <start_date>: selects all the logs generated after the given date"); System.out.println("\t\t-end|-e <end_date>: selects all the logs generated before the given date"); System.out.println("\t\t-filter|-f <filter.xml>: selects all the logs that matches the filters specified in filter.xml"); System.out.println("\t-split|-p: split the source file depending on the command params criteria"); System.out.println("\tcommand_params for splitting:"); System.out.println("\t\t-time|-t <min>: split by time in minutes"); System.out.println("\t\t-num|-n <num>: split by number of logs"); System.out.println("\t-help|-h: print this help\n"); System.out.println("options:"); System.out.println("\t-xml: write the output as XML (default)"); System.out.println("\t-csv: write the output as CSV"); System.out.println("\t-txt: write the output as plain ASCII text"); System.out.println("\t-twiki: write the output as Twiki table"); System.out.println("\t-col|-l columns: select the columns to write in the csv (not supported by XML)"); System.out.println("-dest <filename>: the name of the destionation file."); System.out.println("-src <filename>...: the name of the source files."); System.out.println(" Can be omitted if log files are provided on stdin."); System.out.println("\nSee ACS manual for further details.\n"); } /** * @param args */ public static void main(String[] args) { LogAssistant assistant = null; try { assistant = new LogAssistant(args); } catch (IllegalStateException ex) { System.err.println("Error in the parameters: " + ex.getMessage()); usage("acsLogAssistant"); return; } if (assistant.command=='h') { usage("acsLogAssistant"); return; } try { assistant.work(); } catch (Throwable t) { System.err.println("Exception working on logs: "+t.getMessage()); t.printStackTrace(System.err); } } }