2021-04-24 16:48:30 +02: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 fr.devinsy.logar.app.log;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Class LogParser.
|
|
|
|
*/
|
|
|
|
public final class LogParser
|
|
|
|
{
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(LogParser.class);
|
|
|
|
|
|
|
|
public static Pattern NGINX_ACCESSLOG_LINE_PATTERN = Pattern.compile(
|
|
|
|
"^(?<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.
|
|
|
|
*/
|
|
|
|
private LogParser()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* From access log.
|
|
|
|
*
|
|
|
|
* @param line
|
|
|
|
* the line
|
|
|
|
* @return the log
|
|
|
|
*
|
|
|
|
* log_format combined '$remote_addr - $remote_user [$time_local] '
|
|
|
|
* '"$request" $status $body_bytes_sent ' '"$http_referer"
|
|
|
|
* "$http_user_agent"';
|
|
|
|
*/
|
|
|
|
public static Log parseAccessLog(final String line)
|
|
|
|
{
|
|
|
|
Log result;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Matcher matcher = NGINX_ACCESSLOG_LINE_PATTERN.matcher(line);
|
|
|
|
if (matcher.matches())
|
|
|
|
{
|
|
|
|
String dateTimeValue = matcher.group("datetime");
|
|
|
|
LocalDateTime dateTime = LocalDateTime.parse(dateTimeValue, DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z").withLocale(Locale.ENGLISH));
|
|
|
|
|
|
|
|
result = new Log(line, dateTime);
|
|
|
|
|
|
|
|
result.setDatetimeValue(matcher.group("datetime"));
|
|
|
|
result.setIp(matcher.group("remoteAddress"));
|
|
|
|
result.setUser(matcher.group("remoteUser"));
|
|
|
|
result.setRequest(matcher.group("request"));
|
|
|
|
result.setStatus(matcher.group("status"));
|
|
|
|
result.setBodyByteSent(matcher.group("bodyBytesSent"));
|
|
|
|
result.setReferer(matcher.group("referer"));
|
|
|
|
result.setUserAgent(matcher.group("userAgent"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new IllegalArgumentException("Bad line format: " + line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (DateTimeParseException exception)
|
|
|
|
{
|
2021-04-28 05:15:15 +02:00
|
|
|
throw new IllegalArgumentException("Bad line format (date): " + line, exception);
|
2021-04-24 16:48:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
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)
|
|
|
|
{
|
2021-04-28 05:15:15 +02:00
|
|
|
throw new IllegalArgumentException("Bad line format (date): " + line, exception);
|
2021-04-24 16:48:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|