Improved line parser code.
This commit is contained in:
parent
1178ab11a4
commit
c59a00a695
11 changed files with 593 additions and 185 deletions
|
@ -35,7 +35,9 @@ import org.slf4j.LoggerFactory;
|
||||||
import fr.devinsy.logar.app.anonymizer.Anonymizer;
|
import fr.devinsy.logar.app.anonymizer.Anonymizer;
|
||||||
import fr.devinsy.logar.app.log.Log;
|
import fr.devinsy.logar.app.log.Log;
|
||||||
import fr.devinsy.logar.app.log.LogFile;
|
import fr.devinsy.logar.app.log.LogFile;
|
||||||
import fr.devinsy.logar.app.log.LogParser;
|
import fr.devinsy.logar.app.log.LogType;
|
||||||
|
import fr.devinsy.logar.app.log.parser.AccessLogParser;
|
||||||
|
import fr.devinsy.logar.app.log.parser.LineParser;
|
||||||
import fr.devinsy.logar.stats.UserAgentStator;
|
import fr.devinsy.logar.stats.UserAgentStator;
|
||||||
import fr.devinsy.logar.util.Chrono;
|
import fr.devinsy.logar.util.Chrono;
|
||||||
import fr.devinsy.logar.util.Files;
|
import fr.devinsy.logar.util.Files;
|
||||||
|
@ -64,8 +66,9 @@ public final class Logar
|
||||||
*
|
*
|
||||||
* @param source
|
* @param source
|
||||||
* the source
|
* the source
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void anonymize(final File source)
|
public static void anonymize(final File source) throws IOException
|
||||||
{
|
{
|
||||||
anonymize(source, null);
|
anonymize(source, null);
|
||||||
}
|
}
|
||||||
|
@ -77,8 +80,9 @@ public final class Logar
|
||||||
* the source
|
* the source
|
||||||
* @param mapFile
|
* @param mapFile
|
||||||
* the map file
|
* the map file
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void anonymize(final File source, final File mapFile)
|
public static void anonymize(final File source, final File mapFile) throws IOException
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
|
@ -150,6 +154,7 @@ public final class Logar
|
||||||
YearMonth targetYearMonth = YearMonth.now().minusMonths(1);
|
YearMonth targetYearMonth = YearMonth.now().minusMonths(1);
|
||||||
Stats counter = new Stats();
|
Stats counter = new Stats();
|
||||||
|
|
||||||
|
LineParser lineParser = new AccessLogParser();
|
||||||
for (File directory : Files.of(source).removeHidden().keepDirectoryType().sortByName())
|
for (File directory : Files.of(source).removeHidden().keepDirectoryType().sortByName())
|
||||||
{
|
{
|
||||||
String targetFileName = String.format("%s-access-%s.log.gz", directory.getName(), targetYearMonth.toString());
|
String targetFileName = String.format("%s-access-%s.log.gz", directory.getName(), targetYearMonth.toString());
|
||||||
|
@ -179,7 +184,7 @@ public final class Logar
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log log = LogParser.parseAccessLog(line);
|
Log log = lineParser.parse(line);
|
||||||
counter.incSuccessLineCount();
|
counter.incSuccessLineCount();
|
||||||
|
|
||||||
if (YearMonth.from(log.getDatetime()).equals(targetYearMonth))
|
if (YearMonth.from(log.getDatetime()).equals(targetYearMonth))
|
||||||
|
@ -268,6 +273,7 @@ public final class Logar
|
||||||
{
|
{
|
||||||
if ((!file.isDirectory()) && (file.getName().contains("error")))
|
if ((!file.isDirectory()) && (file.getName().contains("error")))
|
||||||
{
|
{
|
||||||
|
LineParser lineParser = LogFile.getParser(file);
|
||||||
// logger.info(file.getName());
|
// logger.info(file.getName());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -279,7 +285,7 @@ public final class Logar
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log log = LogParser.parseErrorLog(line);
|
Log log = lineParser.parse(line);
|
||||||
counter.incSuccessLineCount();
|
counter.incSuccessLineCount();
|
||||||
|
|
||||||
if (YearMonth.from(log.getDatetime()).equals(targetYearMonth))
|
if (YearMonth.from(log.getDatetime()).equals(targetYearMonth))
|
||||||
|
@ -325,8 +331,9 @@ public final class Logar
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* the source
|
* the source
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void checkLogFile(final File file)
|
public static void checkLogFile(final File file) throws IOException
|
||||||
{
|
{
|
||||||
if (file == null)
|
if (file == null)
|
||||||
{
|
{
|
||||||
|
@ -339,7 +346,7 @@ public final class Logar
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
System.out.println("== Check parse log for [" + file.getName() + "]");
|
System.out.println("== Check parse log for [" + file.getName() + "]");
|
||||||
boolean isAccessFile = file.getName().contains("access");
|
LineParser parser = LogFile.getParser(file);
|
||||||
|
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
int badLineCount = 0;
|
int badLineCount = 0;
|
||||||
|
@ -353,14 +360,7 @@ public final class Logar
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (isAccessFile)
|
parser.parse(line).getDatetime();
|
||||||
{
|
|
||||||
LogParser.parseAccessLog(line).getDatetime();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogParser.parseErrorLog(line).getDatetime();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException exception)
|
catch (IllegalArgumentException exception)
|
||||||
{
|
{
|
||||||
|
@ -393,8 +393,9 @@ public final class Logar
|
||||||
*
|
*
|
||||||
* @param source
|
* @param source
|
||||||
* the source
|
* the source
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void checkLogFiles(final File source)
|
public static void checkLogFiles(final File source) throws IOException
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
|
@ -464,7 +465,7 @@ public final class Logar
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
System.out.println("== Check sort for [" + file.getName() + "]");
|
System.out.println("== Check sort for [" + file.getName() + "]");
|
||||||
boolean isAccessFile = file.getName().contains("access");
|
LineParser lineParser = LogFile.getParser(file);
|
||||||
LocalDateTime currentDate = null;
|
LocalDateTime currentDate = null;
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
int badLineCount = 0;
|
int badLineCount = 0;
|
||||||
|
@ -474,14 +475,7 @@ public final class Logar
|
||||||
String line = iterator.next();
|
String line = iterator.next();
|
||||||
lineCount += 1;
|
lineCount += 1;
|
||||||
LocalDateTime date;
|
LocalDateTime date;
|
||||||
if (isAccessFile)
|
date = lineParser.parse(line).getDatetime();
|
||||||
{
|
|
||||||
date = LogParser.parseAccessLog(line).getDatetime();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
date = LogParser.parseErrorLog(line).getDatetime();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((currentDate != null) && (date.isBefore(currentDate)))
|
if ((currentDate != null) && (date.isBefore(currentDate)))
|
||||||
{
|
{
|
||||||
|
@ -530,6 +524,7 @@ public final class Logar
|
||||||
System.err.println("== Extract userAgent for [" + file.getName() + "]");
|
System.err.println("== Extract userAgent for [" + file.getName() + "]");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
LineParser lineParser = LogFile.getParser(file);
|
||||||
LineIterator iterator = new LineIterator(file);
|
LineIterator iterator = new LineIterator(file);
|
||||||
while (iterator.hasNext())
|
while (iterator.hasNext())
|
||||||
{
|
{
|
||||||
|
@ -537,7 +532,7 @@ public final class Logar
|
||||||
// System.out.println(line);
|
// System.out.println(line);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log log = LogParser.parseAccessLog(line);
|
Log log = lineParser.parse(line);
|
||||||
|
|
||||||
StringList extract = new StringList();
|
StringList extract = new StringList();
|
||||||
if (options.getIp().isOn())
|
if (options.getIp().isOn())
|
||||||
|
@ -582,6 +577,36 @@ public final class Logar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @throws IOException
|
||||||
|
* Signals that an I/O exception has occurred.
|
||||||
|
*/
|
||||||
|
public static void identify(final File source) throws IOException
|
||||||
|
{
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
System.out.println("Undefined source.");
|
||||||
|
}
|
||||||
|
else if (!source.exists())
|
||||||
|
{
|
||||||
|
System.out.println("Missing source to sort.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Files files = FilesUtils.search(source, LOGFILE_PATTERN).removeHidden().sortByName();
|
||||||
|
for (File file : files)
|
||||||
|
{
|
||||||
|
String type = LogFile.getType(file);
|
||||||
|
|
||||||
|
System.out.println(StringUtils.rightPad(type, 20) + file.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort.
|
* Sort.
|
||||||
*
|
*
|
||||||
|
@ -602,7 +627,7 @@ public final class Logar
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Files files = FilesUtils.searchEndingWith(source, LOGFILE_PATTERN).removeHidden().sortByName();
|
Files files = FilesUtils.search(source, LOGFILE_PATTERN).removeHidden().sortByName();
|
||||||
|
|
||||||
for (File file : files)
|
for (File file : files)
|
||||||
{
|
{
|
||||||
|
@ -652,6 +677,7 @@ public final class Logar
|
||||||
int badLineCount = 0;
|
int badLineCount = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
LineParser lineParser = LogFile.getParser(file);
|
||||||
UserAgentStator stator = new UserAgentStator();
|
UserAgentStator stator = new UserAgentStator();
|
||||||
LineIterator iterator = new LineIterator(file);
|
LineIterator iterator = new LineIterator(file);
|
||||||
Chrono chrono = new Chrono().start();
|
Chrono chrono = new Chrono().start();
|
||||||
|
@ -669,7 +695,7 @@ public final class Logar
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log log = LogParser.parseAccessLog(line);
|
Log log = lineParser.parse(line);
|
||||||
stator.putLog(log);
|
stator.putLog(log);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException exception)
|
catch (IllegalArgumentException exception)
|
||||||
|
@ -724,8 +750,9 @@ public final class Logar
|
||||||
*
|
*
|
||||||
* @param source
|
* @param source
|
||||||
* the source
|
* the source
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void testConcate(final File source)
|
public static void testConcate(final File source) throws IOException
|
||||||
{
|
{
|
||||||
Files files = FilesUtils.searchEndingWith(source, ".log", ".log.gz").keepFileType().removeContaining("-anon.log").sortByName();
|
Files files = FilesUtils.searchEndingWith(source, ".log", ".log.gz").keepFileType().removeContaining("-anon.log").sortByName();
|
||||||
|
|
||||||
|
@ -740,8 +767,9 @@ public final class Logar
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* the file
|
* the file
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void testConcateFile(final File file)
|
public static void testConcateFile(final File file) throws IOException
|
||||||
{
|
{
|
||||||
if (file == null)
|
if (file == null)
|
||||||
{
|
{
|
||||||
|
@ -754,7 +782,7 @@ public final class Logar
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
System.out.println("== Test concate log for [" + file.getName() + "]");
|
System.out.println("== Test concate log for [" + file.getName() + "]");
|
||||||
boolean isAccessFile = file.getName().contains("access");
|
LineParser lineParser = LogFile.getParser(file);
|
||||||
|
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
int badLineCount = 0;
|
int badLineCount = 0;
|
||||||
|
@ -768,18 +796,14 @@ public final class Logar
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log source;
|
Log source = lineParser.parse(line);
|
||||||
Log target;
|
Log target = new Log(source);
|
||||||
if (isAccessFile)
|
if (lineParser.getType() == LogType.ACCESS)
|
||||||
{
|
{
|
||||||
source = LogParser.parseAccessLog(line);
|
|
||||||
target = new Log(source);
|
|
||||||
target.concateAccessLog();
|
target.concateAccessLog();
|
||||||
}
|
}
|
||||||
else
|
else if (lineParser.getType() == LogType.ERROR)
|
||||||
{
|
{
|
||||||
source = LogParser.parseErrorLog(line);
|
|
||||||
target = new Log(source);
|
|
||||||
target.concateErrorLog();
|
target.concateErrorLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,9 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import fr.devinsy.logar.app.log.Log;
|
import fr.devinsy.logar.app.log.Log;
|
||||||
import fr.devinsy.logar.app.log.LogParser;
|
import fr.devinsy.logar.app.log.LogFile;
|
||||||
|
import fr.devinsy.logar.app.log.LogType;
|
||||||
|
import fr.devinsy.logar.app.log.parser.LineParser;
|
||||||
import fr.devinsy.logar.util.LineIterator;
|
import fr.devinsy.logar.util.LineIterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,8 +67,9 @@ public final class Anonymizer
|
||||||
*
|
*
|
||||||
* @param source
|
* @param source
|
||||||
* the source
|
* the source
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void anonymize(final File source)
|
public void anonymize(final File source) throws IOException
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +86,7 @@ public final class Anonymizer
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
System.out.println("== Anonymize log for [" + source.getName() + "]");
|
System.out.println("== Anonymize log for [" + source.getName() + "]");
|
||||||
boolean isAccessFile = source.getName().contains("access");
|
LineParser lineParser = LogFile.getParser(source);
|
||||||
|
|
||||||
File target;
|
File target;
|
||||||
if (source.getName().endsWith(".log.gz"))
|
if (source.getName().endsWith(".log.gz"))
|
||||||
|
@ -106,10 +109,10 @@ public final class Anonymizer
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Log log = lineParser.parse(line);
|
||||||
Log anon;
|
Log anon;
|
||||||
if (isAccessFile)
|
if (lineParser.getType() == LogType.ACCESS)
|
||||||
{
|
{
|
||||||
Log log = LogParser.parseAccessLog(line);
|
|
||||||
// logger.info("line={}", line);
|
// logger.info("line={}", line);
|
||||||
// logger.info("log =[{}][{}][{}]", log.getIp(),
|
// logger.info("log =[{}][{}][{}]", log.getIp(),
|
||||||
// log.getUser(), log.getDatetime());
|
// log.getUser(), log.getDatetime());
|
||||||
|
@ -137,8 +140,6 @@ public final class Anonymizer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log log = LogParser.parseErrorLog(line);
|
|
||||||
|
|
||||||
anon = anonymizeError(log);
|
anon = anonymizeError(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,11 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import fr.devinsy.cmdexec.CmdExecException;
|
import fr.devinsy.cmdexec.CmdExecException;
|
||||||
import fr.devinsy.cmdexec.CmdExecUtils;
|
import fr.devinsy.cmdexec.CmdExecUtils;
|
||||||
|
import fr.devinsy.logar.app.log.parser.AccessLogParser;
|
||||||
|
import fr.devinsy.logar.app.log.parser.ApacheErrorLogParser;
|
||||||
|
import fr.devinsy.logar.app.log.parser.EmptyLogParser;
|
||||||
|
import fr.devinsy.logar.app.log.parser.LineParser;
|
||||||
|
import fr.devinsy.logar.app.log.parser.NginxErrorLogParser;
|
||||||
import fr.devinsy.logar.util.LineIterator;
|
import fr.devinsy.logar.util.LineIterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,77 +53,41 @@ public final class LogFile
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load access log.
|
* Gets the parser.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* the file
|
* the file
|
||||||
* @return the logs
|
* @return the parser
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* Signals that an I/O exception has occurred.
|
|
||||||
*/
|
*/
|
||||||
public static Logs loadAccessLog(final File file) throws IOException
|
public static LineParser getParser(final File file) throws IOException
|
||||||
{
|
{
|
||||||
Logs result;
|
LineParser result;
|
||||||
|
|
||||||
result = loadAccessLog(file, LogMode.NORMAL);
|
if (file.getName().contains("access"))
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load access log.
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* the file
|
|
||||||
* @param mode
|
|
||||||
* the mode
|
|
||||||
* @return the logs
|
|
||||||
* @throws IOException
|
|
||||||
* Signals that an I/O exception has occurred.
|
|
||||||
*/
|
|
||||||
public static Logs loadAccessLog(final File file, final LogMode mode) throws IOException
|
|
||||||
{
|
|
||||||
Logs result;
|
|
||||||
|
|
||||||
result = new Logs();
|
|
||||||
|
|
||||||
LineIterator iterator = new LineIterator(file);
|
|
||||||
while (iterator.hasNext())
|
|
||||||
{
|
{
|
||||||
String line = iterator.next();
|
result = new AccessLogParser();
|
||||||
Log log = LogParser.parseAccessLog(line);
|
}
|
||||||
if (mode == LogMode.REDUCED)
|
else if (file.getName().contains("error"))
|
||||||
|
{
|
||||||
|
String line = readFirstLine(file);
|
||||||
|
|
||||||
|
if (line == null)
|
||||||
{
|
{
|
||||||
log.reduce();
|
result = new EmptyLogParser();
|
||||||
|
}
|
||||||
|
else if (line.startsWith("["))
|
||||||
|
{
|
||||||
|
result = new ApacheErrorLogParser();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = new NginxErrorLogParser();
|
||||||
}
|
}
|
||||||
result.add(log);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load error log.
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* the file
|
|
||||||
* @return the logs
|
|
||||||
* @throws IOException
|
|
||||||
* Signals that an I/O exception has occurred.
|
|
||||||
*/
|
|
||||||
public static Logs loadErrorLog(final File file) throws IOException
|
|
||||||
{
|
|
||||||
Logs result;
|
|
||||||
|
|
||||||
result = new Logs();
|
|
||||||
|
|
||||||
LineIterator iterator = new LineIterator(file);
|
|
||||||
while (iterator.hasNext())
|
|
||||||
{
|
{
|
||||||
String line = iterator.next();
|
throw new IllegalArgumentException("Bad named file (missing access or error).");
|
||||||
Log log = LogParser.parseErrorLog(line);
|
|
||||||
result.add(log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -126,7 +95,34 @@ public final class LogFile
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load log file.
|
* Gets the type.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* the file
|
||||||
|
* @return the type
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static String getType(final File file) throws IOException
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
LineParser parser = getParser(file);
|
||||||
|
|
||||||
|
if (parser == null)
|
||||||
|
{
|
||||||
|
result = "*/*";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = parser.getMime();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the log file.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* the file
|
* the file
|
||||||
|
@ -134,18 +130,18 @@ public final class LogFile
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* Signals that an I/O exception has occurred.
|
* Signals that an I/O exception has occurred.
|
||||||
*/
|
*/
|
||||||
public static Logs loadLogFile(final File file) throws IOException
|
public static Logs parseLogFile(final File file) throws IOException
|
||||||
{
|
{
|
||||||
Logs result;
|
Logs result;
|
||||||
|
|
||||||
result = loadLogFile(file, LogMode.NORMAL);
|
result = parseLogFile(file, LogMode.NORMAL);
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load log file.
|
* Parses the log file.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* the file
|
* the file
|
||||||
|
@ -155,7 +151,7 @@ public final class LogFile
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* Signals that an I/O exception has occurred.
|
* Signals that an I/O exception has occurred.
|
||||||
*/
|
*/
|
||||||
public static Logs loadLogFile(final File file, final LogMode mode) throws IOException
|
public static Logs parseLogFile(final File file, final LogMode mode) throws IOException
|
||||||
{
|
{
|
||||||
Logs result;
|
Logs result;
|
||||||
|
|
||||||
|
@ -165,17 +161,55 @@ public final class LogFile
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (file.getName().contains("access"))
|
LineParser lineParser = getParser(file);
|
||||||
|
|
||||||
|
result = new Logs();
|
||||||
|
LineIterator iterator = new LineIterator(file);
|
||||||
|
while (iterator.hasNext())
|
||||||
{
|
{
|
||||||
result = loadAccessLog(file, mode);
|
String line = iterator.next();
|
||||||
|
Log log = lineParser.parse(line);
|
||||||
|
if (mode == LogMode.REDUCED)
|
||||||
|
{
|
||||||
|
log.reduce();
|
||||||
|
}
|
||||||
|
result.add(log);
|
||||||
}
|
}
|
||||||
else if (file.getName().contains("error"))
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read first line.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* the file
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
|
private static String readFirstLine(final File file) throws IOException
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
LineIterator iterator = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
iterator = new LineIterator(file);
|
||||||
|
if (iterator.hasNext())
|
||||||
{
|
{
|
||||||
result = loadErrorLog(file);
|
result = iterator.next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Bad named file (missing access or error).");
|
result = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (iterator != null)
|
||||||
|
{
|
||||||
|
iterator.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +266,7 @@ public final class LogFile
|
||||||
{
|
{
|
||||||
File workFile = new File(file.getParent(), file.getName() + ".tmp");
|
File workFile = new File(file.getParent(), file.getName() + ".tmp");
|
||||||
|
|
||||||
Logs logs = loadLogFile(file, LogMode.REDUCED);
|
Logs logs = parseLogFile(file, LogMode.REDUCED);
|
||||||
logs.sortByDatetime();
|
logs.sortByDatetime();
|
||||||
saveLogs(workFile, logs);
|
saveLogs(workFile, logs);
|
||||||
|
|
||||||
|
|
29
src/fr/devinsy/logar/app/log/LogType.java
Normal file
29
src/fr/devinsy/logar/app/log/LogType.java
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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 fr.devinsy.logar.app.log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Enum LogType.
|
||||||
|
*/
|
||||||
|
public enum LogType
|
||||||
|
{
|
||||||
|
ACCESS,
|
||||||
|
ERROR,
|
||||||
|
WILDCARD;
|
||||||
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with Logar. If not, see <http://www.gnu.org/licenses/>.
|
* along with Logar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package fr.devinsy.logar.app.log;
|
package fr.devinsy.logar.app.log.parser;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
@ -28,25 +28,54 @@ import java.util.regex.Pattern;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.logar.app.log.Log;
|
||||||
|
import fr.devinsy.logar.app.log.LogType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class LogParser.
|
* The Class NginxAccessLogParser.
|
||||||
*/
|
*/
|
||||||
public final class LogParser
|
public final class AccessLogParser implements LineParser
|
||||||
{
|
{
|
||||||
private static Logger logger = LoggerFactory.getLogger(LogParser.class);
|
private static Logger logger = LoggerFactory.getLogger(AccessLogParser.class);
|
||||||
|
|
||||||
public static Pattern NGINX_ACCESSLOG_LINE_PATTERN = Pattern.compile(
|
public static Pattern COMBINED_ACCESSLOG_LINE_PATTERN = Pattern.compile(
|
||||||
"^(?<remoteAddress>[a-zA-F0-9\\\\:\\\\.]+) - (?<remoteUser>[^\\[]+) \\[(?<datetime>[^\\]]+)\\] \"(?<request>[^\"]*)\" (?<status>\\d+) (?<bodyBytesSent>\\d+) \"(?<referer>[^\"]*)\" \"(?<userAgent>[^\"]*)\".*$");
|
"^(?<remoteAddress>[a-zA-F0-9\\\\:\\\\.]+) - (?<remoteUser>[^\\[]+) \\[(?<datetime>[^\\]]+)\\] \"(?<request>[^\"]*)\" (?<status>\\d+) (?<bodyBytesSent>\\d+) \"(?<referer>[^\"]*)\" \"(?<userAgent>[^\"]*)\".*$");
|
||||||
|
|
||||||
public static Pattern NGINX_ERRORLOG_LINE_PATTERN = Pattern.compile("^(?<datetime>\\S+\\s\\S+)\\s\\[(?<level>[^\\]]*)\\]\\s(?<message>.*)$");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new log parser.
|
* Instantiates a new log parser.
|
||||||
*/
|
*/
|
||||||
private LogParser()
|
public AccessLogParser()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#type()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getMime()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = "Access/*";
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#getType()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public LogType getType()
|
||||||
|
{
|
||||||
|
LogType result;
|
||||||
|
|
||||||
|
result = LogType.ACCESS;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From access log.
|
* From access log.
|
||||||
*
|
*
|
||||||
|
@ -58,13 +87,14 @@ public final class LogParser
|
||||||
* '"$request" $status $body_bytes_sent ' '"$http_referer"
|
* '"$request" $status $body_bytes_sent ' '"$http_referer"
|
||||||
* "$http_user_agent"';
|
* "$http_user_agent"';
|
||||||
*/
|
*/
|
||||||
public static Log parseAccessLog(final String line)
|
@Override
|
||||||
|
public Log parse(final String line)
|
||||||
{
|
{
|
||||||
Log result;
|
Log result;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Matcher matcher = NGINX_ACCESSLOG_LINE_PATTERN.matcher(line);
|
Matcher matcher = COMBINED_ACCESSLOG_LINE_PATTERN.matcher(line);
|
||||||
if (matcher.matches())
|
if (matcher.matches())
|
||||||
{
|
{
|
||||||
String dateTimeValue = matcher.group("datetime");
|
String dateTimeValue = matcher.group("datetime");
|
||||||
|
@ -94,60 +124,4 @@ public final class LogParser
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the access log light.
|
|
||||||
*
|
|
||||||
* @param line
|
|
||||||
* the line
|
|
||||||
* @return the log
|
|
||||||
*/
|
|
||||||
public static Log parseAccessLogLight(final String line)
|
|
||||||
{
|
|
||||||
Log result;
|
|
||||||
|
|
||||||
result = parseAccessLog(line);
|
|
||||||
result.reduce();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From error log.
|
|
||||||
*
|
|
||||||
* @param line
|
|
||||||
* the line
|
|
||||||
* @return the log
|
|
||||||
*/
|
|
||||||
public static Log parseErrorLog(final String line)
|
|
||||||
{
|
|
||||||
Log result;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Matcher matcher = NGINX_ERRORLOG_LINE_PATTERN.matcher(line);
|
|
||||||
if (matcher.matches())
|
|
||||||
{
|
|
||||||
String value = matcher.group("datetime");
|
|
||||||
LocalDateTime date = LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withLocale(Locale.ENGLISH));
|
|
||||||
|
|
||||||
result = new Log(line, date);
|
|
||||||
result.setDatetimeValue(matcher.group("datetime"));
|
|
||||||
result.setLevel(matcher.group("level"));
|
|
||||||
result.setMessage(matcher.group("message"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Bad line format: " + line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (DateTimeParseException exception)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Bad line format (date): " + line, exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
113
src/fr/devinsy/logar/app/log/parser/ApacheErrorLogParser.java
Normal file
113
src/fr/devinsy/logar/app/log/parser/ApacheErrorLogParser.java
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* 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 fr.devinsy.logar.app.log.parser;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.logar.app.log.Log;
|
||||||
|
import fr.devinsy.logar.app.log.LogType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class ApacheErrorLogParser.
|
||||||
|
*/
|
||||||
|
public final class ApacheErrorLogParser implements LineParser
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(ApacheErrorLogParser.class);
|
||||||
|
|
||||||
|
public static Pattern APACHE_ERRORLOG_LINE_PATTERN = Pattern.compile("^\\[(?<datetime>[^\\]]+)\\]\\s\\[(?<level>[^\\]]*)\\]\\s(?<message>.*)$");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new nginx error log parser.
|
||||||
|
*/
|
||||||
|
public ApacheErrorLogParser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#type()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getMime()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = "Error/Apache";
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#getType()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public LogType getType()
|
||||||
|
{
|
||||||
|
LogType result;
|
||||||
|
|
||||||
|
result = LogType.ERROR;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#parse(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Log parse(final String line)
|
||||||
|
{
|
||||||
|
Log result;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Matcher matcher = APACHE_ERRORLOG_LINE_PATTERN.matcher(line);
|
||||||
|
if (matcher.matches())
|
||||||
|
{
|
||||||
|
String value = matcher.group("datetime");
|
||||||
|
// Example: Mon Nov 22 06:15:13.773450 2021
|
||||||
|
LocalDateTime date = LocalDateTime.parse(value, DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss.SSSSSS yyyy").withLocale(Locale.ENGLISH));
|
||||||
|
|
||||||
|
result = new Log(line, date);
|
||||||
|
result.setDatetimeValue(matcher.group("datetime"));
|
||||||
|
result.setLevel(matcher.group("level"));
|
||||||
|
result.setMessage(matcher.group("message"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Bad line format: " + line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (DateTimeParseException exception)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Bad line format (date): " + line, exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
82
src/fr/devinsy/logar/app/log/parser/EmptyLogParser.java
Normal file
82
src/fr/devinsy/logar/app/log/parser/EmptyLogParser.java
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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 fr.devinsy.logar.app.log.parser;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.logar.app.log.Log;
|
||||||
|
import fr.devinsy.logar.app.log.LogType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class EmptyLogParser.
|
||||||
|
*/
|
||||||
|
public final class EmptyLogParser implements LineParser
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(EmptyLogParser.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new empty log parser.
|
||||||
|
*/
|
||||||
|
public EmptyLogParser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#type()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getMime()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = "*/*";
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#getType()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public LogType getType()
|
||||||
|
{
|
||||||
|
LogType result;
|
||||||
|
|
||||||
|
result = LogType.WILDCARD;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#parse(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Log parse(final String line)
|
||||||
|
{
|
||||||
|
Log result;
|
||||||
|
|
||||||
|
result = null;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
34
src/fr/devinsy/logar/app/log/parser/LineParser.java
Normal file
34
src/fr/devinsy/logar/app/log/parser/LineParser.java
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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 fr.devinsy.logar.app.log.parser;
|
||||||
|
|
||||||
|
import fr.devinsy.logar.app.log.Log;
|
||||||
|
import fr.devinsy.logar.app.log.LogType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Interface LineParser.
|
||||||
|
*/
|
||||||
|
public interface LineParser
|
||||||
|
{
|
||||||
|
String getMime();
|
||||||
|
|
||||||
|
LogType getType();
|
||||||
|
|
||||||
|
Log parse(String line);
|
||||||
|
}
|
112
src/fr/devinsy/logar/app/log/parser/NginxErrorLogParser.java
Normal file
112
src/fr/devinsy/logar/app/log/parser/NginxErrorLogParser.java
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* 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 fr.devinsy.logar.app.log.parser;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.logar.app.log.Log;
|
||||||
|
import fr.devinsy.logar.app.log.LogType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class NginxErrorLogParser.
|
||||||
|
*/
|
||||||
|
public final class NginxErrorLogParser implements LineParser
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(NginxErrorLogParser.class);
|
||||||
|
|
||||||
|
public static Pattern NGINX_ERRORLOG_LINE_PATTERN = Pattern.compile("^(?<datetime>\\S+\\s\\S+)\\s\\[(?<level>[^\\]]*)\\]\\s(?<message>.*)$");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new nginx error log parser.
|
||||||
|
*/
|
||||||
|
public NginxErrorLogParser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#type()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getMime()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = "Error/Nginx";
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#getType()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public LogType getType()
|
||||||
|
{
|
||||||
|
LogType result;
|
||||||
|
|
||||||
|
result = LogType.ERROR;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.devinsy.logar.app.log.parser.LineParser#parse(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Log parse(final String line)
|
||||||
|
{
|
||||||
|
Log result;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Matcher matcher = NGINX_ERRORLOG_LINE_PATTERN.matcher(line);
|
||||||
|
if (matcher.matches())
|
||||||
|
{
|
||||||
|
String value = matcher.group("datetime");
|
||||||
|
LocalDateTime date = LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withLocale(Locale.ENGLISH));
|
||||||
|
|
||||||
|
result = new Log(line, date);
|
||||||
|
result.setDatetimeValue(matcher.group("datetime"));
|
||||||
|
result.setLevel(matcher.group("level"));
|
||||||
|
result.setMessage(matcher.group("message"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Bad line format: " + line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (DateTimeParseException exception)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Bad line format (date): " + line, exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,6 +61,7 @@ public final class LogarCLI
|
||||||
message.appendln(" logar check <fileordirectory> check line format in log files");
|
message.appendln(" logar check <fileordirectory> check line format in log files");
|
||||||
message.appendln(" logar checksort <fileordirectory> check sort 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 extract <fields> <fileordirectory> extract one or more fields (ip,user,datetime,useragent) from log files");
|
||||||
|
message.appendln(" logar identify <fileordirectory> display type of log files");
|
||||||
message.appendln(" logar sort <fileordirectory> sort log files by datetime");
|
message.appendln(" logar sort <fileordirectory> sort log files by datetime");
|
||||||
message.appendln(" logar testconcate <fileordirectory> test line concate in log files");
|
message.appendln(" logar testconcate <fileordirectory> test line concate in log files");
|
||||||
|
|
||||||
|
@ -232,6 +233,12 @@ public final class LogarCLI
|
||||||
|
|
||||||
Logar.extract(source, options);
|
Logar.extract(source, options);
|
||||||
}
|
}
|
||||||
|
else if (isMatching(args, "identify", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
File source = new File(args[1]);
|
||||||
|
|
||||||
|
Logar.identify(source);
|
||||||
|
}
|
||||||
else if (isMatching(args, "sort", "\\s*\\S+\\s*"))
|
else if (isMatching(args, "sort", "\\s*\\S+\\s*"))
|
||||||
{
|
{
|
||||||
File source = new File(args[1]);
|
File source = new File(args[1]);
|
||||||
|
|
|
@ -33,10 +33,8 @@ public final class UserAgent
|
||||||
private long ipLinkCount;
|
private long ipLinkCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new user agent stat.
|
* Instantiates a new user agent.
|
||||||
*
|
*
|
||||||
* @param ip
|
|
||||||
* the ip
|
|
||||||
* @param userAgent
|
* @param userAgent
|
||||||
* the user agent
|
* the user agent
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue