2021-02-27 05:08:26 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
|
|
|
*
|
|
|
|
* This file is part of Logar, simple tool to manage http log files.
|
|
|
|
*
|
|
|
|
* Logar 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.
|
|
|
|
*
|
|
|
|
* Logar 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 Logar. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
package org.april.logar.cli;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
|
|
|
import org.april.logar.util.BuildInformation;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
2021-05-01 17:26:28 +02:00
|
|
|
import fr.devinsy.logar.app.ExtractOptions;
|
2021-02-27 05:08:26 +01:00
|
|
|
import fr.devinsy.logar.app.Logar;
|
2021-05-01 17:26:28 +02:00
|
|
|
import fr.devinsy.logar.app.OnOffOption;
|
2021-02-27 05:08:26 +01:00
|
|
|
import fr.devinsy.strings.StringList;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Class <code>Logar</code> manages a Command Line Interface for Logar.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public final class LogarCLI
|
|
|
|
{
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(LogarCLI.class);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Instantiates a new log tool CLI.
|
|
|
|
*/
|
|
|
|
private LogarCLI()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Display help.
|
|
|
|
*/
|
|
|
|
public static void displayHelp()
|
|
|
|
{
|
|
|
|
StringList message = new StringList();
|
|
|
|
|
|
|
|
message.append("Logar CLI version ").appendln(BuildInformation.instance().version());
|
|
|
|
message.appendln("Usage:");
|
|
|
|
message.appendln(" logar [ -h | -help | --help ]");
|
2021-03-15 22:03:41 +01:00
|
|
|
message.appendln(" logar [ -v | -version | --version ]");
|
2021-05-01 17:26:28 +02:00
|
|
|
message.appendln(" logar anonymize <fileordirectory> [<mapfile>] anonymize ip and user");
|
|
|
|
message.appendln(" logar archive [-dry] <source> <target> archive previous month from /var/log/nginx/ tree");
|
|
|
|
message.appendln(" logar check <fileordirectory> check line format in log files");
|
|
|
|
message.appendln(" logar checksort <fileordirectory> check sort in log files");
|
|
|
|
message.appendln(" logar extract <fields> <fileordirectory> extract one or more fields (ip,user,datetime,useragent) from log files");
|
|
|
|
message.appendln(" logar sort <fileordirectory> sort log files by datetime");
|
|
|
|
message.appendln(" logar testconcate <fileordirectory> test line concate in log files");
|
2021-02-27 05:08:26 +01:00
|
|
|
|
|
|
|
logger.info(message.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Display version.
|
|
|
|
*/
|
|
|
|
public static void displayVersion()
|
|
|
|
{
|
|
|
|
StringList message = new StringList();
|
|
|
|
|
|
|
|
message.appendln(BuildInformation.instance().version());
|
|
|
|
|
|
|
|
logger.info(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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* 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.");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-03-15 22:03:41 +01:00
|
|
|
try
|
2021-02-27 05:08:26 +01:00
|
|
|
{
|
2021-03-15 22:03:41 +01:00
|
|
|
logger.info("{} Logar 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();
|
|
|
|
}
|
2021-04-22 02:36:11 +02:00
|
|
|
else if (isMatching(args, "anonymize", "\\s*\\S+\\s*"))
|
|
|
|
{
|
|
|
|
File source = new File(args[1]);
|
|
|
|
|
|
|
|
Logar.anonymize(source);
|
|
|
|
}
|
2021-03-15 22:03:41 +01:00
|
|
|
else if (isMatching(args, "anonymize", "\\s*\\S+\\s*", "\\s*\\S+\\s*"))
|
2021-02-27 05:08:26 +01:00
|
|
|
{
|
|
|
|
File source = new File(args[1]);
|
2021-04-22 02:36:11 +02:00
|
|
|
File map = new File(args[2]);
|
2021-02-27 05:08:26 +01:00
|
|
|
|
2021-04-22 02:36:11 +02:00
|
|
|
Logar.anonymize(source, map);
|
2021-02-27 05:08:26 +01:00
|
|
|
}
|
2021-03-15 22:03:41 +01:00
|
|
|
else if (isMatching(args, "archive", "\\s*\\S+\\s*", "\\s*\\S+\\s*"))
|
2021-02-27 05:08:26 +01:00
|
|
|
{
|
|
|
|
File source = new File(args[1]);
|
|
|
|
File target = new File(args[2]);
|
|
|
|
|
2021-05-01 17:26:28 +02:00
|
|
|
Logar.archive(source, target, OnOffOption.OFF);
|
2021-02-27 05:08:26 +01:00
|
|
|
}
|
2021-04-25 13:18:39 +02:00
|
|
|
else if (isMatching(args, "archive", "-dry", "\\s*\\S+\\s*", "\\s*\\S+\\s*"))
|
|
|
|
{
|
|
|
|
File source = new File(args[2]);
|
|
|
|
File target = new File(args[3]);
|
|
|
|
|
2021-05-01 17:26:28 +02:00
|
|
|
Logar.archive(source, target, OnOffOption.ON);
|
2021-04-25 13:18:39 +02:00
|
|
|
}
|
2021-04-22 02:36:11 +02:00
|
|
|
else if (isMatching(args, "check", "\\s*\\S+\\s*"))
|
|
|
|
{
|
|
|
|
File source = new File(args[1]);
|
|
|
|
|
2021-04-22 20:21:22 +02:00
|
|
|
Logar.checkLogFiles(source);
|
2021-04-22 02:36:11 +02:00
|
|
|
}
|
2021-03-15 22:03:41 +01:00
|
|
|
else if (isMatching(args, "checksort", "\\s*\\S+\\s*"))
|
2021-02-27 05:08:26 +01:00
|
|
|
{
|
2021-03-15 22:03:41 +01:00
|
|
|
File source = new File(args[1]);
|
|
|
|
|
2021-04-24 16:48:30 +02:00
|
|
|
Logar.checkSort(source);
|
2021-02-27 05:08:26 +01:00
|
|
|
}
|
2021-05-01 17:26:28 +02:00
|
|
|
else if (isMatching(args, "extract", "\\s*((ip)?(,)?(remoteuser)?(,)?(datetime)?(,)?(useragent)?)\\s*", "\\s*\\S+\\s*"))
|
2021-04-27 12:46:42 +02:00
|
|
|
{
|
2021-05-01 17:26:28 +02:00
|
|
|
ExtractOptions options = ExtractOptions.of(args[1]);
|
2021-04-27 12:46:42 +02:00
|
|
|
File source = new File(args[2]);
|
|
|
|
|
2021-05-01 17:26:28 +02:00
|
|
|
Logar.extract(source, options);
|
2021-04-27 12:46:42 +02:00
|
|
|
}
|
2021-04-22 02:36:11 +02:00
|
|
|
else if (isMatching(args, "sort", "\\s*\\S+\\s*"))
|
|
|
|
{
|
|
|
|
File source = new File(args[1]);
|
|
|
|
|
|
|
|
Logar.sort(source);
|
|
|
|
}
|
2021-04-24 16:48:30 +02:00
|
|
|
else if (isMatching(args, "testconcate", "\\s*\\S+\\s*"))
|
2021-02-27 05:08:26 +01:00
|
|
|
{
|
|
|
|
File source = new File(args[1]);
|
|
|
|
|
2021-04-24 16:48:30 +02:00
|
|
|
Logar.testConcate(source);
|
2021-02-27 05:08:26 +01:00
|
|
|
}
|
2021-03-15 22:03:41 +01:00
|
|
|
else
|
2021-02-27 05:08:26 +01:00
|
|
|
{
|
2021-03-15 22:03:41 +01:00
|
|
|
logger.info("Bad usage.");
|
|
|
|
displayHelp();
|
2021-02-27 05:08:26 +01:00
|
|
|
}
|
|
|
|
}
|
2021-03-15 22:03:41 +01:00
|
|
|
catch (Exception exception)
|
2021-02-27 05:08:26 +01:00
|
|
|
{
|
2021-03-15 22:03:41 +01:00
|
|
|
logger.error("Error: {}", exception.getMessage());
|
|
|
|
exception.printStackTrace();
|
2021-02-27 05:08:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
logger.info("Done.");
|
|
|
|
}
|
|
|
|
}
|