/* * Copyright (C) 2020-2021 Christian Pierre MOMON * * This file is part of StatoolInfos, simple service statistics tool. * * StatoolInfos is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * StatoolInfos 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with StatoolInfos. If not, see . */ package fr.devinsy.statoolinfos.cli; import java.io.File; import java.time.LocalDateTime; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import fr.devinsy.statoolinfos.core.BotFilter; import fr.devinsy.statoolinfos.core.StatoolInfos; import fr.devinsy.statoolinfos.util.BuildInformation; import fr.devinsy.statoolinfos.util.Chrono; import fr.devinsy.statoolinfos.util.Files; import fr.devinsy.statoolinfos.util.FilesUtils; import fr.devinsy.strings.StringList; /** * The Class StatoolInfosCLI manages a Command Line Interface for * StatoolInfos. * */ public final class StatoolInfosCLI { private static Logger logger = LoggerFactory.getLogger(StatoolInfosCLI.class); /** * Instantiates a new statool infos CLI. */ private StatoolInfosCLI() { } /** * Convert path. * * @param path * the path * @return the files */ public static Files convertPath(final String path) { Files result; result = new Files(); if (StringUtils.isNotBlank(path)) { File input = new File(path); if (input.exists()) { if (input.isFile()) { result.add(input); } else { for (File file : input.listFiles()) { if ((file.isFile()) && (file.getName().endsWith(".conf"))) { result.add(file); } } } } else { result.add(input); } } // return result; } /** * Display help. */ public static void displayHelp() { StringList message = new StringList(); message.append("StatoolInfos CLI version ").appendln(BuildInformation.instance().version()); message.appendln("Usage:"); message.appendln(" statoolinfos [ -h | -help | --help ]"); message.appendln(" statoolinfos [ -v | -version | --version ]"); message.appendln(); message.appendln(" statoolinfos build build property files from conf and input"); message.appendln(" statoolinfos clear remove property files from conf"); message.appendln(" statoolinfos crawl crawl all file from conf and input"); message.appendln(" statoolinfos htmlize generate web pages from conf"); message.appendln(" statoolinfos probe [|] generate metrics files from conf"); message.appendln(" statoolinfos uptime update uptime journal"); message.appendln(); message.appendln(" statoolinfos format format property files in tiny way"); message.appendln(" statoolinfos list ip [-bot|-nobot] generate ip list from log file"); message.appendln(" statoolinfos list ua [-bot|-nobot] generate user agent list from log file"); message.appendln(" statoolinfos list visitors [-bot|-nobot] generate visitors (ip+ua) list from log file"); message.appendln(" statoolinfos stat ip [-bot|-nobot] generate stats about ip from log file"); message.appendln(" statoolinfos stat ua [-bot|-nobot] generate stats about user agent from log file"); message.appendln(" statoolinfos stat visitors [-bot|-nobot] generate stats about visitors (ip+ua) from log file"); message.appendln(" statoolinfos tagdate update the file.datetime file"); System.out.print(message.toString()); } /** * Display version. */ public static void displayVersion() { StringList message = new StringList(); message.appendln(BuildInformation.instance().version()); System.out.print(message.toString()); } /** * Checks if is matching. * * @param args * the args * @param regexps * the regexps * @return true, if is matching */ public static boolean isMatching(final String[] args, final String... regexps) { boolean result; if ((args.length == 0) && (regexps == null)) { result = true; } else if ((args.length != 0) && (regexps == null)) { result = false; } else if (args.length != regexps.length) { result = false; } else { boolean ended = false; int index = 0; result = false; while (!ended) { if (index < args.length) { String arg = args[index]; String regexp = regexps[index]; if (arg.matches(regexp)) { index += 1; } else { ended = true; result = false; } } else { ended = true; result = true; } } } // return result; } /** * Parses the log filter option. * * @param source * the source * @return the log filter */ private static BotFilter parseLogFilterOption(final String source) { BotFilter result; if (StringUtils.equals(source, "-all")) { result = BotFilter.ALL; } else if (StringUtils.equals(source, "-bot")) { result = BotFilter.BOT; } else if (StringUtils.equals(source, "-nobot")) { result = BotFilter.NOBOT; } else { result = null; } // return result; } /** * * This method launch CLI. * * @param args * necessary arguments */ public static void run(final String[] args) { // Set default catch. Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(final Thread thread, final Throwable exception) { String message; if (exception instanceof OutOfMemoryError) { message = "Java ran out of memory!\n\n"; } else { message = String.format("An error occured: %1s(%2s)", exception.getClass(), exception.getMessage()); } logger.error("uncaughtException ", exception); logger.error(message); logger.info("Oups, an unexpected error occured. Please try again."); } }); logger.debug("{} StatoolInfos call: {}", LocalDateTime.now(), new StringList(args).toStringSeparatedBy(" ")); if (isMatching(args)) { logger.info("No parameter."); displayHelp(); } else if (isMatching(args, "(-h|--h|--help)")) { displayHelp(); } else if (isMatching(args, "(-v|-version|--version)")) { displayVersion(); } else if (isMatching(args, "build", "\\s*.+\\.conf\\s*")) { File configurationFile = new File(StringUtils.trim(args[1])); try { StatoolInfos.build(configurationFile); } catch (Exception exception) { logger.error("Error with [{}]: {}", configurationFile.getAbsoluteFile(), exception.getMessage()); } } else if (isMatching(args, "clear", "\\s*.+\\.conf\\s*")) { File configurationFile = new File(StringUtils.trim(args[1])); try { StatoolInfos.clear(configurationFile); } catch (Exception exception) { logger.error("Error with [{}]: {}", configurationFile.getAbsoluteFile(), exception.getMessage()); } } else if (isMatching(args, "crawl", "\\s*.+\\.conf\\s*")) { Chrono chrono = new Chrono().start(); File configurationFile = new File(StringUtils.trim(args[1])); try { StatoolInfos.crawl(configurationFile); } catch (Exception exception) { logger.error("Error with [{}]: {}", configurationFile.getAbsoluteFile(), exception.getMessage()); exception.printStackTrace(); } System.out.println(chrono.format()); } else if (isMatching(args, "format", "\\s*.+\\s*")) { Files inputs = FilesUtils.searchEndingWith(new File(args[1]), ".properties"); for (File input : inputs) { try { StatoolInfos.format(input); } catch (Exception exception) { logger.error("Error with [{}]: {}", input.getAbsoluteFile(), exception.getMessage()); exception.printStackTrace(); } } } else if (isMatching(args, "htmlize", "\\s*.+\\.conf\\s*")) { Chrono chrono = new Chrono().start(); File configurationFile = new File(StringUtils.trim(args[1])); try { StatoolInfos.htmlize(configurationFile); } catch (Exception exception) { logger.error("Error with [{}]: {}", configurationFile.getAbsoluteFile(), exception.getMessage()); exception.printStackTrace(); } System.out.println(chrono.format()); } else if (isMatching(args, "list", "ip", "\\s*\\S+\\s*")) { File source = new File(args[2]); StatoolInfos.listIps(source, BotFilter.ALL); } else if (isMatching(args, "list", "ip", "(-all|-bot|-nobot)", "\\s*\\S+\\s*")) { BotFilter filter = parseLogFilterOption(args[2]); File source = new File(args[3]); StatoolInfos.listIps(source, filter); } else if (isMatching(args, "list", "(useragent|ua)", "\\s*\\S+\\s*")) { File source = new File(args[2]); StatoolInfos.listUserAgents(source, BotFilter.ALL); } else if (isMatching(args, "list", "(useragent|ua)", "(-all|-bot|-nobot)", "\\s*\\S+\\s*")) { BotFilter filter = parseLogFilterOption(args[2]); File source = new File(args[3]); StatoolInfos.listUserAgents(source, filter); } else if (isMatching(args, "list", "visitors", "\\s*\\S+\\s*")) { File source = new File(args[2]); StatoolInfos.listVisitors(source, BotFilter.ALL); } else if (isMatching(args, "list", "visitors", "(-all|-bot|-nobot)", "\\s*\\S+\\s*")) { BotFilter filter = parseLogFilterOption(args[2]); File source = new File(args[3]); StatoolInfos.listVisitors(source, filter); } else if (isMatching(args, "probe", "\\s*.+\\.conf\\s*")) { File configurationFile = new File(StringUtils.trim(args[1])); try { StatoolInfos.probe(configurationFile); } catch (Exception exception) { logger.error("Error with [{}]: {}", configurationFile.getAbsoluteFile(), exception.getMessage()); exception.printStackTrace(); } } else if (isMatching(args, "probe", "\\s*.+/\\s*")) { File configurationFile = new File(StringUtils.trim(args[1])); if (configurationFile.isDirectory()) { Files inputs = FilesUtils.searchEndingWith(configurationFile, ".conf"); for (File input : inputs) { try { StatoolInfos.probe(input); } catch (Exception exception) { logger.error("Error with [{}]: {}", input.getAbsoluteFile(), exception.getMessage()); exception.printStackTrace(); } } } else { System.out.println("Parameter is not a directory."); } } else if (isMatching(args, "stat", "ip", "\\s*\\S+\\s*")) { File source = new File(args[2]); StatoolInfos.statIps(source, BotFilter.ALL); } else if (isMatching(args, "stat", "ip", "(-all|-bot|-nobot)", "\\s*\\S+\\s*")) { BotFilter filter = parseLogFilterOption(args[2]); File source = new File(args[3]); StatoolInfos.statIps(source, filter); } else if (isMatching(args, "stat", "(useragent|ua)", "\\s*\\S+\\s*")) { File source = new File(args[2]); StatoolInfos.statUserAgents(source, BotFilter.ALL); } else if (isMatching(args, "stat", "(useragent|ua)", "(-all|-bot|-nobot)", "\\s*\\S+\\s*")) { BotFilter filter = parseLogFilterOption(args[2]); File source = new File(args[3]); StatoolInfos.statUserAgents(source, filter); } else if (isMatching(args, "stat", "visitors", "\\s*\\S+\\s*")) { File source = new File(args[2]); StatoolInfos.statVisitors(source, BotFilter.ALL); } else if (isMatching(args, "stat", "visitors", "(-all|-bot|-nobot)", "\\s*\\S+\\s*")) { BotFilter filter = parseLogFilterOption(args[2]); File source = new File(args[3]); StatoolInfos.statVisitors(source, filter); } else if (isMatching(args, "tagdate", "\\s*.+\\s*")) { Files inputs = FilesUtils.searchEndingWith(new File(args[1]), ".properties"); for (File input : inputs) { try { StatoolInfos.tagDate(input); } catch (Exception exception) { logger.error("Error with [{}]: {}", input.getAbsoluteFile(), exception.getMessage()); exception.printStackTrace(); } } } else if (isMatching(args, "uptime", "\\s*.+\\.conf\\s*")) { Chrono chrono = new Chrono().start(); File configurationFile = new File(StringUtils.trim(args[1])); try { StatoolInfos.uptime(configurationFile); } catch (Exception exception) { logger.error("Error with [{}]: {}", configurationFile.getAbsoluteFile(), exception.getMessage()); exception.printStackTrace(); } System.out.println(chrono.format()); } else { System.out.println("Bad usage."); displayHelp(); } } }