Step in probe devs.
This commit is contained in:
parent
e4d122bbe4
commit
22addc634f
19 changed files with 2004 additions and 270 deletions
|
@ -254,6 +254,7 @@ public final class StatoolInfosCLI
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
logger.error("Error with [{}]: {}", input.getAbsoluteFile(), exception.getMessage());
|
logger.error("Error with [{}]: {}", input.getAbsoluteFile(), exception.getMessage());
|
||||||
|
exception.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,9 @@ import java.time.Period;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -142,6 +144,23 @@ public class StatoolInfosUtils
|
||||||
FileUtils.copyURLToFile(source, target, 5000, 5000);
|
FileUtils.copyURLToFile(source, target, 5000, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the week count of year.
|
||||||
|
*
|
||||||
|
* @param year
|
||||||
|
* the year
|
||||||
|
* @return the week count of year
|
||||||
|
*/
|
||||||
|
public static int getWeekCountOfYear(final int year)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = new GregorianCalendar(year, 11, 01).getActualMaximum(Calendar.WEEK_OF_YEAR);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current time in long format.
|
* Gets the current time in long format.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,283 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.core.StatoolInfosException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class HttpAccessLogProber.
|
||||||
|
*/
|
||||||
|
public class HttpAccessLogAnalyzer
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(HttpAccessLogAnalyzer.class);
|
||||||
|
|
||||||
|
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new http access log prober.
|
||||||
|
*/
|
||||||
|
private HttpAccessLogAnalyzer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the log.
|
||||||
|
*
|
||||||
|
* @param line
|
||||||
|
* the line
|
||||||
|
* @return the http log
|
||||||
|
*/
|
||||||
|
public static HttpLog parseLog(final String line)
|
||||||
|
{
|
||||||
|
HttpLog result;
|
||||||
|
|
||||||
|
//
|
||||||
|
// log_format combined '$remote_addr - $remote_user [$time_local] '
|
||||||
|
// '"$request" $status $body_bytes_sent '
|
||||||
|
// '"$http_referer" "$http_user_agent"';
|
||||||
|
String remoteAddressPattern = "(?<remoteAddress>[a-zA-F0-9\\\\:\\\\.]+)";
|
||||||
|
String remoteUserPattern = "(?<remoteUser>\\S+)";
|
||||||
|
String timePattern = "(?<time>[^\\]]+)";
|
||||||
|
String requestPattern = "(?<request>[^\"]*)";
|
||||||
|
String statusPattern = "(?<status>\\d+)";
|
||||||
|
String bodyBytesSentPattern = "(?<bodyBytesSent>\\d+)";
|
||||||
|
String refererPattern = "(?<referer>[^\"]*)";
|
||||||
|
String httpUserAgentPattern = "(?<httpUserAgent>[^\"]*)";
|
||||||
|
|
||||||
|
String combinedPattern = String.format("^%s - %s \\[%s\\] \"%s\" %s %s \"%s\" \"%s\".*$",
|
||||||
|
remoteAddressPattern, remoteUserPattern, timePattern, requestPattern, statusPattern, bodyBytesSentPattern,
|
||||||
|
refererPattern, httpUserAgentPattern);
|
||||||
|
|
||||||
|
// logger.info("pattern=[{}]", combinedPattern);
|
||||||
|
|
||||||
|
Pattern combined = Pattern.compile(combinedPattern);
|
||||||
|
|
||||||
|
Matcher matcher = combined.matcher(line);
|
||||||
|
if (matcher.matches())
|
||||||
|
{
|
||||||
|
result = new HttpLog();
|
||||||
|
result.setRemoteAddress(matcher.group("remoteAddress"));
|
||||||
|
result.setRemoteUser(matcher.group("remoteUser"));
|
||||||
|
result.setTime(LocalDateTime.parse(matcher.group("time"), DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z").withLocale(Locale.ENGLISH)));
|
||||||
|
result.setRequest(matcher.group("request"));
|
||||||
|
result.setStatus(HttpStatusTable.instance().get(matcher.group("status")));
|
||||||
|
result.setBodyBytesSent(Long.valueOf(matcher.group("bodyBytesSent")));
|
||||||
|
result.setReferer(matcher.group("referer"));
|
||||||
|
result.setHttpUserAgent(new UserAgent(matcher.group("httpUserAgent")));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Probe.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @param target
|
||||||
|
* the target
|
||||||
|
* @throws IOException
|
||||||
|
* Signals that an I/O exception has occurred.
|
||||||
|
* @throws StatoolInfosException
|
||||||
|
* the statool infos exception
|
||||||
|
*/
|
||||||
|
public static PathCounters probe(final File source, final File target) throws IOException, StatoolInfosException
|
||||||
|
{
|
||||||
|
PathCounters result = new PathCounters();
|
||||||
|
|
||||||
|
int errorCount = 0;
|
||||||
|
for (File file : source.getParentFile().listFiles())
|
||||||
|
{
|
||||||
|
// if (file.getName().startsWith(source.getName()))
|
||||||
|
if (file.getName().equals(source.getName()))
|
||||||
|
{
|
||||||
|
errorCount += probe(result, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Probe.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @param counters
|
||||||
|
* the counters
|
||||||
|
* @throws IOException
|
||||||
|
* Signals that an I/O exception has occurred.
|
||||||
|
* @throws StatoolInfosException
|
||||||
|
* the statool infos exception
|
||||||
|
*/
|
||||||
|
public static int probe(final PathCounters counters, final File source) throws IOException, StatoolInfosException
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
BufferedReader in = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
in = new BufferedReader(new InputStreamReader(new FileInputStream(source), DEFAULT_CHARSET_NAME));
|
||||||
|
|
||||||
|
boolean ended = false;
|
||||||
|
while (!ended)
|
||||||
|
{
|
||||||
|
String line = in.readLine();
|
||||||
|
|
||||||
|
if (line == null)
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
|
}
|
||||||
|
else if (StringUtils.isNotEmpty(line))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
probe(counters, line);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
result += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtils.closeQuietly(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Probe.
|
||||||
|
*
|
||||||
|
* @param counters
|
||||||
|
* the counters
|
||||||
|
* @param line
|
||||||
|
* the line
|
||||||
|
*/
|
||||||
|
public static void probe(final PathCounters counters, final String line)
|
||||||
|
{
|
||||||
|
HttpLog log = parseLog(line);
|
||||||
|
|
||||||
|
// logger.info("==================");
|
||||||
|
if (log == null)
|
||||||
|
{
|
||||||
|
logger.warn("LINE IS NOT MATCHING [{}]", line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// logger.info("LINE IS MATCHING [{}]", log);
|
||||||
|
// logger.info(log.getHttpUserAgent().toString());
|
||||||
|
|
||||||
|
// General HTTP access logs.
|
||||||
|
String year = log.getYear();
|
||||||
|
String yearMonth = log.getYearMonth();
|
||||||
|
String yearWeek = log.getYearWeek();
|
||||||
|
String date = log.getDate();
|
||||||
|
|
||||||
|
// metrics.http.hits
|
||||||
|
counters.inc("metrics.http.hits", year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
|
if (log.isIPv4())
|
||||||
|
{
|
||||||
|
counters.inc("metrics.http.hits.ipv4", year, yearMonth, yearWeek, date);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
counters.inc("metrics.http.hits.ipv6", year, yearMonth, yearWeek, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// metrics.http.files
|
||||||
|
if (log.getBodyBytesSent() != 0)
|
||||||
|
{
|
||||||
|
counters.inc("metrics.http.file", year, yearMonth, yearWeek, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// metrics.http.bytes
|
||||||
|
counters.inc(log.getBodyBytesSent(), "metrics.http.bytes", year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
|
// metrics.http.hits.bots.* =
|
||||||
|
if (log.isBot())
|
||||||
|
{
|
||||||
|
counters.inc("metrics.http.hits.bots", year, yearMonth, yearWeek, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// metrics.http.pages.* =
|
||||||
|
if (StringUtils.endsWithAny(log.getRequest(), ".html", ".htm", ".xhtml", ".cgi"))
|
||||||
|
{
|
||||||
|
counters.inc("metrics.http.pages", year, yearMonth, yearWeek, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// metrics.http.status.XXX
|
||||||
|
String status = String.valueOf(log.getStatus().getCode());
|
||||||
|
counters.inc("metrics.http.status." + status, year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
|
// metrics.http.os.XXXXX
|
||||||
|
UserAgentOS os = log.getHttpUserAgent().getOS();
|
||||||
|
counters.inc("metrics.http.browsers." + os.toString().toLowerCase(), year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
|
// metrics.http.browsers.XXXXX
|
||||||
|
UserAgentBrowser browser = log.getHttpUserAgent().getBrowser();
|
||||||
|
counters.inc("metrics.http.browsers." + browser.toString().toLowerCase(), year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
|
// metrics.http.devices.XXXXX =
|
||||||
|
UserAgentDevice device = log.getHttpUserAgent().getDevice();
|
||||||
|
counters.inc("metrics.http.devices." + device.toString().toLowerCase(), year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
|
// metrics.http.countries.XX =
|
||||||
|
|
||||||
|
// metrics.http.ip.* =
|
||||||
|
// metrics.http.ip.ipv4.* =
|
||||||
|
// metrics.http.ip.ipv6.* =
|
||||||
|
|
||||||
|
// metrics.http.visits.* =
|
||||||
|
|
||||||
|
// metrics.http.errors.* =
|
||||||
|
// metrics.http.errors.php.* =
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,240 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
|
|
||||||
*
|
|
||||||
* 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package fr.devinsy.statoolinfos.htmlize.probes;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import fr.devinsy.statoolinfos.core.StatoolInfosException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Class HttpAccessLogProber.
|
|
||||||
*/
|
|
||||||
public class HttpAccessLogProber
|
|
||||||
{
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(HttpAccessLogProber.class);
|
|
||||||
|
|
||||||
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiates a new http access log prober.
|
|
||||||
*/
|
|
||||||
private HttpAccessLogProber()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Probe.
|
|
||||||
*
|
|
||||||
* @param source
|
|
||||||
* the source
|
|
||||||
* @param target
|
|
||||||
* the target
|
|
||||||
* @throws IOException
|
|
||||||
* Signals that an I/O exception has occurred.
|
|
||||||
* @throws StatoolInfosException
|
|
||||||
* the statool infos exception
|
|
||||||
*/
|
|
||||||
public static void probe(final File source, final File target) throws IOException, StatoolInfosException
|
|
||||||
{
|
|
||||||
PathCounters counters;
|
|
||||||
|
|
||||||
counters = new PathCounters();
|
|
||||||
|
|
||||||
for (File file : source.getParentFile().listFiles())
|
|
||||||
{
|
|
||||||
if (file.getName().startsWith(source.getName()))
|
|
||||||
{
|
|
||||||
probe(counters, source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Probe.
|
|
||||||
*
|
|
||||||
* @param source
|
|
||||||
* the source
|
|
||||||
* @param counters
|
|
||||||
* the counters
|
|
||||||
* @throws IOException
|
|
||||||
* Signals that an I/O exception has occurred.
|
|
||||||
* @throws StatoolInfosException
|
|
||||||
* the statool infos exception
|
|
||||||
*/
|
|
||||||
public static void probe(final PathCounters counters, final File source) throws IOException, StatoolInfosException
|
|
||||||
{
|
|
||||||
BufferedReader in = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
in = new BufferedReader(new InputStreamReader(new FileInputStream(source), DEFAULT_CHARSET_NAME));
|
|
||||||
|
|
||||||
boolean ended = false;
|
|
||||||
while (!ended)
|
|
||||||
{
|
|
||||||
String line = in.readLine();
|
|
||||||
|
|
||||||
if (line == null)
|
|
||||||
{
|
|
||||||
ended = true;
|
|
||||||
}
|
|
||||||
else if (StringUtils.isNotEmpty(line))
|
|
||||||
{
|
|
||||||
probe(counters, line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IOUtils.closeQuietly(in);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Probe.
|
|
||||||
*
|
|
||||||
* @param counters
|
|
||||||
* the counters
|
|
||||||
* @param line
|
|
||||||
* the line
|
|
||||||
*/
|
|
||||||
public static void probe(final PathCounters counters, final String line)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
LocalDateTime date;
|
|
||||||
|
|
||||||
date = LocalDateTime.now();
|
|
||||||
|
|
||||||
String year = date.format(DateTimeFormatter.ofPattern("yyyy", Locale.FRANCE));
|
|
||||||
String month = date.format(DateTimeFormatter.ofPattern("yyyy-MM", Locale.FRANCE));
|
|
||||||
String week = date.format(DateTimeFormatter.ofPattern("yyyyWW", Locale.FRANCE));
|
|
||||||
String day = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
|
|
||||||
|
|
||||||
// General HTTP access logs.
|
|
||||||
|
|
||||||
// metrics.http.hits
|
|
||||||
counters.inc("metrics.http.hits", year);
|
|
||||||
counters.inc("metrics.http.hits", month);
|
|
||||||
counters.inc("metrics.http.hits", week);
|
|
||||||
counters.inc("metrics.http.hits", day);
|
|
||||||
|
|
||||||
// metrics.http.hits.ipv4
|
|
||||||
counters.inc("metrics.http.hits.ipv4", year);
|
|
||||||
counters.inc("metrics.http.hits.ipv4", month);
|
|
||||||
counters.inc("metrics.http.hits.ipv4", week);
|
|
||||||
counters.inc("metrics.http.hits.ipv4", day);
|
|
||||||
|
|
||||||
// metrics.http.hits.ipv6
|
|
||||||
counters.inc("metrics.http.hits.ipv6", year);
|
|
||||||
counters.inc("metrics.http.hits.ipv6", month);
|
|
||||||
counters.inc("metrics.http.hits.ipv6", week);
|
|
||||||
counters.inc("metrics.http.hits.ipv6", day);
|
|
||||||
|
|
||||||
// metrics.http.pages
|
|
||||||
counters.inc("metrics.http.pages", year);
|
|
||||||
counters.inc("metrics.http.pages", month);
|
|
||||||
counters.inc("metrics.http.pages", week);
|
|
||||||
counters.inc("metrics.http.pages", day);
|
|
||||||
|
|
||||||
// metrics.http.pages.ipv4
|
|
||||||
counters.inc("metrics.http.pages.ipv4", year);
|
|
||||||
counters.inc("metrics.http.pages.ipv4", month);
|
|
||||||
counters.inc("metrics.http.pages.ipv4", week);
|
|
||||||
counters.inc("metrics.http.pages.ipv4", day);
|
|
||||||
|
|
||||||
// metrics.http.pages.ipv6
|
|
||||||
counters.inc("metrics.http.pages.ipv6", year);
|
|
||||||
counters.inc("metrics.http.pages.ipv6", month);
|
|
||||||
counters.inc("metrics.http.pages.ipv6", week);
|
|
||||||
counters.inc("metrics.http.pages.ipv6", day);
|
|
||||||
|
|
||||||
// metrics.http.files
|
|
||||||
counters.inc("metrics.http.file", year);
|
|
||||||
counters.inc("metrics.http.file", month);
|
|
||||||
counters.inc("metrics.http.file", week);
|
|
||||||
counters.inc("metrics.http.file", day);
|
|
||||||
|
|
||||||
// metrics.http.files.ipv4
|
|
||||||
counters.inc("metrics.http.file.ipv4", year);
|
|
||||||
counters.inc("metrics.http.file.ipv4", month);
|
|
||||||
counters.inc("metrics.http.file.ipv4", week);
|
|
||||||
counters.inc("metrics.http.file.ipv4", day);
|
|
||||||
|
|
||||||
// metrics.http.files.ipv6
|
|
||||||
counters.inc("metrics.http.file.ipv6", year);
|
|
||||||
counters.inc("metrics.http.file.ipv6", month);
|
|
||||||
counters.inc("metrics.http.file.ipv6", week);
|
|
||||||
counters.inc("metrics.http.file.ipv6", day);
|
|
||||||
|
|
||||||
// metrics.http.bytes
|
|
||||||
counters.inc("metrics.http.bytes", year);
|
|
||||||
counters.inc("metrics.http.bytes", month);
|
|
||||||
counters.inc("metrics.http.bytes", week);
|
|
||||||
counters.inc("metrics.http.bytes", day);
|
|
||||||
|
|
||||||
// metrics.http.bytes.ipv4
|
|
||||||
counters.inc("metrics.http.bytes.ipv4", year);
|
|
||||||
counters.inc("metrics.http.bytes.ipv4", month);
|
|
||||||
counters.inc("metrics.http.bytes.ipv4", week);
|
|
||||||
counters.inc("metrics.http.bytes.ipv4", day);
|
|
||||||
|
|
||||||
// metrics.http.bytes.ipv6
|
|
||||||
counters.inc("metrics.http.bytes.ipv6", year);
|
|
||||||
counters.inc("metrics.http.bytes.ipv6", month);
|
|
||||||
counters.inc("metrics.http.bytes.ipv6", week);
|
|
||||||
counters.inc("metrics.http.bytes.ipv6", day);
|
|
||||||
|
|
||||||
// metrics.http.status.1xx
|
|
||||||
// metrics.http.status.2xx
|
|
||||||
// metrics.http.status.3xx
|
|
||||||
// metrics.http.status.4xx
|
|
||||||
// metrics.http.status.5xx
|
|
||||||
|
|
||||||
// metrics.http.ips
|
|
||||||
// metrics.http.ips.ipv4
|
|
||||||
// metrics.http.ips.ipv6
|
|
||||||
|
|
||||||
// General HTTP error logs.
|
|
||||||
// metrics.http.errors
|
|
||||||
// metrics.http.errors.php
|
|
||||||
|
|
||||||
// ==
|
|
||||||
|
|
||||||
// metrics.http.hits.bots
|
|
||||||
// metrics.http.hits.monitoring
|
|
||||||
// metrics.http.hits.
|
|
||||||
|
|
||||||
// metrics.http.monitoring
|
|
||||||
|
|
||||||
// metrics.http.visitors
|
|
||||||
// metrics.http.users
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
301
src/fr/devinsy/statoolinfos/htmlize/probes/HttpLog.java
Normal file
301
src/fr/devinsy/statoolinfos/htmlize/probes/HttpLog.java
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.strings.StringList;
|
||||||
|
import fr.devinsy.strings.StringsUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class HttpLog.
|
||||||
|
*/
|
||||||
|
public class HttpLog
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(HttpLog.class);
|
||||||
|
|
||||||
|
public static final Pattern IPV4_PATTERN = Pattern.compile("\\d{0,3}\\.\\d{0,3}\\.\\d{0,3}\\.\\d{0,3}");
|
||||||
|
public static final Pattern IPV6_PATTERN = Pattern.compile("([0-9a-f]{1,4}:{1,2}){4,7}([0-9a-f]){1,4}", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
|
private String remoteAddress;
|
||||||
|
private String remoteUser;
|
||||||
|
private LocalDateTime time;
|
||||||
|
private String request;
|
||||||
|
private HttpStatus status;
|
||||||
|
private long bodyBytesSent;
|
||||||
|
private String referer;
|
||||||
|
private UserAgent httpUserAgent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new http log.
|
||||||
|
*/
|
||||||
|
public HttpLog()
|
||||||
|
{
|
||||||
|
this.remoteAddress = null;
|
||||||
|
this.remoteUser = null;
|
||||||
|
this.time = null;
|
||||||
|
this.request = null;
|
||||||
|
this.status = null;
|
||||||
|
this.bodyBytesSent = 0;
|
||||||
|
this.referer = null;
|
||||||
|
this.httpUserAgent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBodyBytesSent()
|
||||||
|
{
|
||||||
|
return this.bodyBytesSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDate()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = this.time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAgent getHttpUserAgent()
|
||||||
|
{
|
||||||
|
return this.httpUserAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReferer()
|
||||||
|
{
|
||||||
|
return this.referer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemoteAddress()
|
||||||
|
{
|
||||||
|
return this.remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemoteUser()
|
||||||
|
{
|
||||||
|
return this.remoteUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequest()
|
||||||
|
{
|
||||||
|
return this.request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpStatus getStatus()
|
||||||
|
{
|
||||||
|
return this.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getTime()
|
||||||
|
{
|
||||||
|
return this.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the year.
|
||||||
|
*
|
||||||
|
* @return the year
|
||||||
|
*/
|
||||||
|
public String getYear()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
if (this.time == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = this.time.format(DateTimeFormatter.ofPattern("yyyy", Locale.FRANCE));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the year month.
|
||||||
|
*
|
||||||
|
* @return the year month
|
||||||
|
*/
|
||||||
|
public String getYearMonth()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
if (this.time == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = this.time.format(DateTimeFormatter.ofPattern("yyyy-MM", Locale.FRANCE));
|
||||||
|
}
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the year week.
|
||||||
|
*
|
||||||
|
* @return the year week
|
||||||
|
*/
|
||||||
|
public String getYearWeek()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
if (this.time == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
result = this.time.format(DateTimeFormatter.ofPattern("yyyy'W'ww", Locale.FRANCE));
|
||||||
|
}
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isBot()
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
result = StringsUtils.containsAnyIgnoreCase(this.httpUserAgent.toString(), "bot", "monitoring");
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if is ipv4.
|
||||||
|
*
|
||||||
|
* @return true, if is ipv4
|
||||||
|
*/
|
||||||
|
public boolean isIPv4()
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
if (this.remoteAddress == null)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = this.remoteAddress.contains(".");
|
||||||
|
}
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if is ipv6.
|
||||||
|
*
|
||||||
|
* @return true, if is ipv6
|
||||||
|
*/
|
||||||
|
public boolean isIPv6()
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
if (this.remoteAddress == null)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = this.remoteAddress.contains(":");
|
||||||
|
}
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBodyBytesSent(final long bodyBytesSent)
|
||||||
|
{
|
||||||
|
this.bodyBytesSent = bodyBytesSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHttpUserAgent(final UserAgent httpUserAgent)
|
||||||
|
{
|
||||||
|
this.httpUserAgent = httpUserAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReferer(final String referer)
|
||||||
|
{
|
||||||
|
this.referer = referer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteAddress(final String remoteAddress)
|
||||||
|
{
|
||||||
|
this.remoteAddress = remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteUser(final String remoteUser)
|
||||||
|
{
|
||||||
|
this.remoteUser = remoteUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequest(final String request)
|
||||||
|
{
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(final HttpStatus status)
|
||||||
|
{
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(final LocalDateTime time)
|
||||||
|
{
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To string.
|
||||||
|
*
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
StringList buffer = new StringList();
|
||||||
|
|
||||||
|
buffer.append("[remoteAddress=").append(this.remoteAddress).append("]");
|
||||||
|
buffer.append("[remoteUser=").append(this.remoteUser).append("]");
|
||||||
|
buffer.append("[time=").append(this.time).append("]");
|
||||||
|
buffer.append("[request=").append(this.request).append("]");
|
||||||
|
buffer.append("[status=").append(this.status.getCode()).append("]");
|
||||||
|
buffer.append("[bodyBytesSent=").append(this.bodyBytesSent).append("]");
|
||||||
|
buffer.append("[referer=").append(this.referer).append("]");
|
||||||
|
buffer.append("[httpUserAgent=").append(this.httpUserAgent).append("]");
|
||||||
|
|
||||||
|
result = buffer.toString();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
119
src/fr/devinsy/statoolinfos/htmlize/probes/HttpLogIterator.java
Normal file
119
src/fr/devinsy/statoolinfos/htmlize/probes/HttpLogIterator.java
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class HttpLogIterator.
|
||||||
|
*/
|
||||||
|
public class HttpLogIterator
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(HttpLogIterator.class);
|
||||||
|
|
||||||
|
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
|
||||||
|
|
||||||
|
private long errorCount;
|
||||||
|
private LineIterator iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new http log iterator.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @throws IOException
|
||||||
|
* Signals that an I/O exception has occurred.
|
||||||
|
*/
|
||||||
|
public HttpLogIterator(final File source) throws IOException
|
||||||
|
{
|
||||||
|
this.errorCount = 0;
|
||||||
|
this.iterator = new LineIterator(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close.
|
||||||
|
*/
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
this.iterator.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the error count.
|
||||||
|
*
|
||||||
|
* @return the error count
|
||||||
|
*/
|
||||||
|
public long getErrorCount()
|
||||||
|
{
|
||||||
|
return this.errorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for next.
|
||||||
|
*
|
||||||
|
* @return true, if successful
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public boolean hasNext() throws IOException
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
result = this.iterator.hasNext();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Next.
|
||||||
|
*
|
||||||
|
* @return the http log
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public HttpLog next() throws IOException
|
||||||
|
{
|
||||||
|
HttpLog result;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String line = this.iterator.next();
|
||||||
|
result = HttpAccessLogAnalyzer.parseLog(line);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
this.errorCount += 1;
|
||||||
|
if (this.iterator.hasNext())
|
||||||
|
{
|
||||||
|
result = next();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
87
src/fr/devinsy/statoolinfos/htmlize/probes/HttpStatus.java
Normal file
87
src/fr/devinsy/statoolinfos/htmlize/probes/HttpStatus.java
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class HttpStatus.
|
||||||
|
*/
|
||||||
|
public class HttpStatus
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(HttpStatus.class);
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
private String message;
|
||||||
|
private String description;
|
||||||
|
private HttpStatusCategory category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new http status.
|
||||||
|
*/
|
||||||
|
public HttpStatus(final int code, final String message, final String description)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
this.description = description;
|
||||||
|
this.category = HttpStatusCategory.valueOfCode(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpStatusCategory getCategory()
|
||||||
|
{
|
||||||
|
return this.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode()
|
||||||
|
{
|
||||||
|
return this.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription()
|
||||||
|
{
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage()
|
||||||
|
{
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(final HttpStatusCategory category)
|
||||||
|
{
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(final int code)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(final String description)
|
||||||
|
{
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(final String message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Enum HttpStatusCategory.
|
||||||
|
*/
|
||||||
|
public enum HttpStatusCategory
|
||||||
|
{
|
||||||
|
INFORMATIONAL,
|
||||||
|
SUCCESS,
|
||||||
|
REDIRECTION,
|
||||||
|
CLIENT_ERROR,
|
||||||
|
SERVER_ERROR,
|
||||||
|
INVALID;
|
||||||
|
|
||||||
|
public static boolean isClientError(final int code)
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
result = ((code / 100) == 4);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if is informational.
|
||||||
|
*
|
||||||
|
* @return true, if is informational
|
||||||
|
*/
|
||||||
|
public static boolean isInformational(final int code)
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
result = ((code / 100) == 1);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRedirection(final int code)
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
result = ((code / 100) == 3);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isServerError(final int code)
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
result = ((code / 100) == 5);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSuccess(final int code)
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
result = ((code / 100) == 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value of.
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* the code
|
||||||
|
* @return the http status category
|
||||||
|
*/
|
||||||
|
public static HttpStatusCategory valueOfCode(final int code)
|
||||||
|
{
|
||||||
|
HttpStatusCategory result;
|
||||||
|
|
||||||
|
if (isInformational(code))
|
||||||
|
{
|
||||||
|
result = HttpStatusCategory.INFORMATIONAL;
|
||||||
|
}
|
||||||
|
else if (isSuccess(code))
|
||||||
|
{
|
||||||
|
result = HttpStatusCategory.SUCCESS;
|
||||||
|
}
|
||||||
|
else if (isRedirection(code))
|
||||||
|
{
|
||||||
|
result = HttpStatusCategory.REDIRECTION;
|
||||||
|
}
|
||||||
|
else if (isClientError(code))
|
||||||
|
{
|
||||||
|
result = HttpStatusCategory.CLIENT_ERROR;
|
||||||
|
}
|
||||||
|
else if (isServerError(code))
|
||||||
|
{
|
||||||
|
result = HttpStatusCategory.SERVER_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = HttpStatusCategory.INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
149
src/fr/devinsy/statoolinfos/htmlize/probes/HttpStatusTable.java
Normal file
149
src/fr/devinsy/statoolinfos/htmlize/probes/HttpStatusTable.java
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class HttpStatusTable.
|
||||||
|
*/
|
||||||
|
public class HttpStatusTable
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(HttpStatusTable.class);
|
||||||
|
|
||||||
|
public static final Pattern HTTP_CODE_PATTERN = Pattern.compile("\\d{3}");
|
||||||
|
|
||||||
|
private static class SingletonHolder
|
||||||
|
{
|
||||||
|
private static final HttpStatusTable instance = new HttpStatusTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<Integer, HttpStatus> codes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new http status table.
|
||||||
|
*/
|
||||||
|
private HttpStatusTable()
|
||||||
|
{
|
||||||
|
this.codes = new HashMap<Integer, HttpStatus>();
|
||||||
|
|
||||||
|
put(100, "Continue", "Attente de la suite de la requête.");
|
||||||
|
put(101, "Switching Protocols", "Acceptation du changement de protocole.");
|
||||||
|
put(102, "Processing", "WebDAV RFC 25183,4: Traitement en cours (évite que le client dépasse le temps d’attente limite).");
|
||||||
|
put(103, "Early Hints", "RFC 82975 : (Expérimental) Dans l'attente de la réponse définitive, le serveur retourne des liens que le client peut commencer à télécharger.");
|
||||||
|
|
||||||
|
put(200, "OK", "Requête traitée avec succès. La réponse dépendra de la méthode de requête utilisée.");
|
||||||
|
put(201, "Created", "Requête traitée avec succès et création d’un document.");
|
||||||
|
put(202, "Accepted", "Requête traitée, mais sans garantie de résultat.");
|
||||||
|
put(203, "Non-Authoritative Information", "Information retournée, mais générée par une source non certifiée.");
|
||||||
|
put(204, "No Content", "Requête traitée avec succès mais pas d’information à renvoyer.");
|
||||||
|
put(205, "Reset Content", "Requête traitée avec succès, la page courante peut être effacée.");
|
||||||
|
put(206, "Partial Content", "Une partie seulement de la ressource a été transmise.");
|
||||||
|
put(207, "Multi-Status", "WebDAV : Réponse multiple.");
|
||||||
|
put(208, "Already Reported", "WebDAV : Le document a été envoyé précédemment dans cette collection.");
|
||||||
|
put(210, "Content Different", "WebDAV : La copie de la ressource côté client diffère de celle du serveur (contenu ou propriétés).");
|
||||||
|
put(226, "IM Used",
|
||||||
|
"RFC 32296 : Le serveur a accompli la requête pour la ressource, et la réponse est une représentation du résultat d'une ou plusieurs manipulations d'instances appliquées à l'instance actuelle.");
|
||||||
|
|
||||||
|
// put();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the.
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* the code
|
||||||
|
* @return the http status
|
||||||
|
*/
|
||||||
|
public HttpStatus get(final int code)
|
||||||
|
{
|
||||||
|
HttpStatus result;
|
||||||
|
|
||||||
|
result = this.codes.get(code);
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
result = put(code, "UNOFFICIAL", "n/a");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the.
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* the code
|
||||||
|
* @return the http status
|
||||||
|
*/
|
||||||
|
public HttpStatus get(final String code)
|
||||||
|
{
|
||||||
|
HttpStatus result;
|
||||||
|
|
||||||
|
if (HTTP_CODE_PATTERN.matcher(code).matches())
|
||||||
|
{
|
||||||
|
int value = Integer.valueOf(code);
|
||||||
|
result = get(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put.
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* the code
|
||||||
|
* @param message
|
||||||
|
* the message
|
||||||
|
* @param description
|
||||||
|
* the description
|
||||||
|
* @return the http status
|
||||||
|
*/
|
||||||
|
private HttpStatus put(final int code, final String message, final String description)
|
||||||
|
{
|
||||||
|
HttpStatus result;
|
||||||
|
|
||||||
|
result = new HttpStatus(code, message, description);
|
||||||
|
this.codes.put(code, result);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance.
|
||||||
|
*
|
||||||
|
* @return the http status table
|
||||||
|
*/
|
||||||
|
public static HttpStatusTable instance()
|
||||||
|
{
|
||||||
|
return SingletonHolder.instance;
|
||||||
|
}
|
||||||
|
}
|
125
src/fr/devinsy/statoolinfos/htmlize/probes/LineIterator.java
Normal file
125
src/fr/devinsy/statoolinfos/htmlize/probes/LineIterator.java
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class LineIterator.
|
||||||
|
*/
|
||||||
|
public class LineIterator
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(LineIterator.class);
|
||||||
|
|
||||||
|
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
|
||||||
|
|
||||||
|
private BufferedReader in;
|
||||||
|
private String nextLine;
|
||||||
|
private boolean ready;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new http log iterator.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @throws IOException
|
||||||
|
* Signals that an I/O exception has occurred.
|
||||||
|
*/
|
||||||
|
public LineIterator(final File source) throws IOException
|
||||||
|
{
|
||||||
|
this.in = new BufferedReader(new InputStreamReader(new FileInputStream(source), DEFAULT_CHARSET_NAME));
|
||||||
|
this.nextLine = null;
|
||||||
|
this.ready = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close.
|
||||||
|
*/
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
IOUtils.closeQuietly(this.in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for next.
|
||||||
|
*
|
||||||
|
* @return true, if successful
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public boolean hasNext() throws IOException
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
setReady();
|
||||||
|
|
||||||
|
if (this.nextLine == null)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Next.
|
||||||
|
*
|
||||||
|
* @return the http log
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public String next() throws IOException
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
setReady();
|
||||||
|
|
||||||
|
result = this.nextLine;
|
||||||
|
this.ready = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read next line.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void setReady() throws IOException
|
||||||
|
{
|
||||||
|
if (!this.ready)
|
||||||
|
{
|
||||||
|
this.nextLine = this.in.readLine();
|
||||||
|
this.ready = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class NGinxLogAnalyzer.
|
||||||
|
*/
|
||||||
|
public class NGinxLogAnalyzer
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(NGinxLogAnalyzer.class);
|
||||||
|
|
||||||
|
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new n ginx log analyzer.
|
||||||
|
*/
|
||||||
|
private NGinxLogAnalyzer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package fr.devinsy.statoolinfos.htmlize.probes;
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -70,6 +72,62 @@ public class PathCounter
|
||||||
this.counter += 1;
|
this.counter += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void inc(final long value)
|
||||||
|
{
|
||||||
|
this.counter += value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if is date.
|
||||||
|
*
|
||||||
|
* @return true, if is date
|
||||||
|
*/
|
||||||
|
public boolean isDate()
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$");
|
||||||
|
|
||||||
|
result = (pattern.matcher(this.timeMark).matches());
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if is year mark.
|
||||||
|
*
|
||||||
|
* @return true, if is year mark
|
||||||
|
*/
|
||||||
|
public boolean isYearMark()
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile("^\\d{4}$");
|
||||||
|
|
||||||
|
result = (pattern.matcher(this.timeMark).matches());
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if is year week.
|
||||||
|
*
|
||||||
|
* @return true, if is year week
|
||||||
|
*/
|
||||||
|
public boolean isYearWeek()
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile("^\\d{4}W\\d{2}$");
|
||||||
|
|
||||||
|
result = (pattern.matcher(this.timeMark).matches());
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public void setCounter(final long counter)
|
public void setCounter(final long counter)
|
||||||
{
|
{
|
||||||
this.counter = counter;
|
this.counter = counter;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 2020-2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
*
|
*
|
||||||
* This file is part of StatoolInfos, simple service statistics tool.
|
* This file is part of StatoolInfos, simple service statistics tool.
|
||||||
*
|
*
|
||||||
|
@ -18,14 +18,23 @@
|
||||||
*/
|
*/
|
||||||
package fr.devinsy.statoolinfos.htmlize.probes;
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.core.StatoolInfosUtils;
|
||||||
|
import fr.devinsy.strings.StringList;
|
||||||
|
import fr.devinsy.strings.StringSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class PathCounters.
|
* The Class PathCounters.
|
||||||
*/
|
*/
|
||||||
public class PathCounters extends HashMap<String, PathCounter>
|
public class PathCounters extends HashMap<String, PathCounter>
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = -7731827840828688703L;
|
private static final long serialVersionUID = 6881726853303684439L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new path counters.
|
* Instantiates a new path counters.
|
||||||
|
@ -75,6 +84,228 @@ public class PathCounters extends HashMap<String, PathCounter>
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the by prefix.
|
||||||
|
*
|
||||||
|
* @param prefix
|
||||||
|
* the prefix
|
||||||
|
* @return the by prefix
|
||||||
|
*/
|
||||||
|
public PathCounters getByPrefix(final String prefix)
|
||||||
|
{
|
||||||
|
PathCounters result;
|
||||||
|
|
||||||
|
result = new PathCounters();
|
||||||
|
|
||||||
|
for (PathCounter counter : this.values())
|
||||||
|
{
|
||||||
|
if (StringUtils.equals(counter.getPath(), prefix))
|
||||||
|
{
|
||||||
|
result.put(counter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the days values line.
|
||||||
|
*
|
||||||
|
* @param prefix
|
||||||
|
* the prefix
|
||||||
|
* @param year
|
||||||
|
* the year
|
||||||
|
* @return the days values line
|
||||||
|
*/
|
||||||
|
public String getDaysValuesLine(final String prefix, final String year)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
StringList line = new StringList();
|
||||||
|
|
||||||
|
LocalDate day = LocalDate.of(Integer.valueOf(year), 01, 01);
|
||||||
|
boolean ended = false;
|
||||||
|
while (!ended)
|
||||||
|
{
|
||||||
|
if (day.getYear() == Integer.valueOf(year))
|
||||||
|
{
|
||||||
|
String timeMark = day.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
|
||||||
|
PathCounter dayCounter = get(prefix, timeMark);
|
||||||
|
if (dayCounter != null)
|
||||||
|
{
|
||||||
|
line.append(dayCounter.getCounter());
|
||||||
|
}
|
||||||
|
line.append(',');
|
||||||
|
|
||||||
|
//
|
||||||
|
day = day.plusDays(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line.removeLast();
|
||||||
|
|
||||||
|
result = line.toString();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the months values line.
|
||||||
|
*
|
||||||
|
* @param prefix
|
||||||
|
* the prefix
|
||||||
|
* @param year
|
||||||
|
* the year
|
||||||
|
* @return the months values line
|
||||||
|
*/
|
||||||
|
public String getMonthsValuesLine(final String prefix, final String year)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
StringList line = new StringList();
|
||||||
|
for (int month = 1; month <= 12; month++)
|
||||||
|
{
|
||||||
|
String timeMark = String.format("%s-%02d", year, month);
|
||||||
|
PathCounter monthCounter = get(prefix, timeMark);
|
||||||
|
if (monthCounter != null)
|
||||||
|
{
|
||||||
|
line.append(monthCounter.getCounter());
|
||||||
|
}
|
||||||
|
line.append(',');
|
||||||
|
}
|
||||||
|
line.removeLast();
|
||||||
|
|
||||||
|
result = line.toString();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the prefixes.
|
||||||
|
*
|
||||||
|
* @return the prefixes
|
||||||
|
*/
|
||||||
|
public StringList getPrefixes()
|
||||||
|
{
|
||||||
|
StringList result;
|
||||||
|
|
||||||
|
StringSet paths = new StringSet();
|
||||||
|
for (PathCounter counter : this.values())
|
||||||
|
{
|
||||||
|
paths.put(counter.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
result = new StringList(paths).sort();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the weeks values line.
|
||||||
|
*
|
||||||
|
* @param prefix
|
||||||
|
* the prefix
|
||||||
|
* @param year
|
||||||
|
* the year
|
||||||
|
* @return the weeks values line
|
||||||
|
*/
|
||||||
|
public String getWeeksValuesLine(final String prefix, final String year)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
StringList line = new StringList();
|
||||||
|
|
||||||
|
int weekCount = StatoolInfosUtils.getWeekCountOfYear(Integer.valueOf(year));
|
||||||
|
|
||||||
|
for (int week = 1; week <= weekCount; week++)
|
||||||
|
{
|
||||||
|
String timeMark = String.format("%sW%02d", year, week);
|
||||||
|
PathCounter weekCounter = get(prefix, timeMark);
|
||||||
|
if (weekCounter != null)
|
||||||
|
{
|
||||||
|
line.append(weekCounter.getCounter());
|
||||||
|
}
|
||||||
|
line.append(',');
|
||||||
|
}
|
||||||
|
line.removeLast();
|
||||||
|
|
||||||
|
result = line.toString();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the years.
|
||||||
|
*
|
||||||
|
* @return the years
|
||||||
|
*/
|
||||||
|
public StringList getYears()
|
||||||
|
{
|
||||||
|
StringList result;
|
||||||
|
|
||||||
|
StringSet years = new StringSet();
|
||||||
|
for (PathCounter counter : this.values())
|
||||||
|
{
|
||||||
|
if (counter.getTimeMark().matches("\\d{4}"))
|
||||||
|
{
|
||||||
|
years.put(counter.getTimeMark());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = new StringList(years);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inc.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* the value
|
||||||
|
* @param path
|
||||||
|
* the path
|
||||||
|
* @param timeMark
|
||||||
|
* the time mark
|
||||||
|
*/
|
||||||
|
public void inc(final long value, final String path, final String timeMark)
|
||||||
|
{
|
||||||
|
PathCounter counter = get(path, timeMark);
|
||||||
|
if (counter == null)
|
||||||
|
{
|
||||||
|
counter = new PathCounter(path, timeMark);
|
||||||
|
put(counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
counter.inc(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inc.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* the value
|
||||||
|
* @param path
|
||||||
|
* the path
|
||||||
|
* @param timeMarks
|
||||||
|
* the time marks
|
||||||
|
*/
|
||||||
|
public void inc(final long value, final String path, final String... timeMarks)
|
||||||
|
{
|
||||||
|
for (String timeMark : timeMarks)
|
||||||
|
{
|
||||||
|
inc(value, path, timeMark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put.
|
* Put.
|
||||||
*
|
*
|
||||||
|
@ -89,9 +320,39 @@ public class PathCounters extends HashMap<String, PathCounter>
|
||||||
if (counter == null)
|
if (counter == null)
|
||||||
{
|
{
|
||||||
counter = new PathCounter(path, timeMark);
|
counter = new PathCounter(path, timeMark);
|
||||||
put(computeKey(path, timeMark), counter);
|
put(counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
counter.inc();
|
counter.inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inc.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* the path
|
||||||
|
* @param timeMarks
|
||||||
|
* the time marks
|
||||||
|
*/
|
||||||
|
public void inc(final String path, final String... timeMarks)
|
||||||
|
{
|
||||||
|
for (String timeMark : timeMarks)
|
||||||
|
{
|
||||||
|
inc(path, timeMark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put.
|
||||||
|
*
|
||||||
|
* @param counter
|
||||||
|
* the counter
|
||||||
|
*/
|
||||||
|
public void put(final PathCounter counter)
|
||||||
|
{
|
||||||
|
if (counter != null)
|
||||||
|
{
|
||||||
|
put(computeKey(counter.getPath(), counter.getTimeMark()), counter);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 2020-2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
*
|
*
|
||||||
* This file is part of StatoolInfos, simple service statistics tool.
|
* This file is part of StatoolInfos, simple service statistics tool.
|
||||||
*
|
*
|
||||||
|
@ -18,11 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package fr.devinsy.statoolinfos.htmlize.probes;
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -30,6 +30,8 @@ import org.slf4j.LoggerFactory;
|
||||||
import fr.devinsy.statoolinfos.core.Configuration;
|
import fr.devinsy.statoolinfos.core.Configuration;
|
||||||
import fr.devinsy.statoolinfos.core.Factory;
|
import fr.devinsy.statoolinfos.core.Factory;
|
||||||
import fr.devinsy.statoolinfos.core.StatoolInfosException;
|
import fr.devinsy.statoolinfos.core.StatoolInfosException;
|
||||||
|
import fr.devinsy.strings.StringList;
|
||||||
|
import fr.devinsy.strings.StringsUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class Prober.
|
* The Class Prober.
|
||||||
|
@ -59,36 +61,46 @@ public class Prober
|
||||||
*/
|
*/
|
||||||
public static void probe(final Configuration configuration) throws IOException, StatoolInfosException
|
public static void probe(final Configuration configuration) throws IOException, StatoolInfosException
|
||||||
{
|
{
|
||||||
BufferedReader in = null;
|
//
|
||||||
try
|
|
||||||
{
|
{
|
||||||
//
|
String sourceFileName = configuration.get("conf.probe.http.accesslogs.source");
|
||||||
|
String targetFileName = configuration.get("conf.probe.http.accesslogs.target");
|
||||||
|
|
||||||
|
logger.info("source=[{}]", sourceFileName);
|
||||||
|
logger.info("target=[{}]", targetFileName);
|
||||||
|
|
||||||
|
if (!StringUtils.isAllBlank(sourceFileName, targetFileName))
|
||||||
{
|
{
|
||||||
String sourceFileName = configuration.get("conf.probe.http.accesslogs.source");
|
PathCounters counters = HttpAccessLogAnalyzer.probe(new File(sourceFileName), new File(targetFileName));
|
||||||
String targetFileName = configuration.get("conf.probe.http.accesslogs.target");
|
|
||||||
if (!StringUtils.isAllBlank(sourceFileName, targetFileName))
|
writeMetrics(new File(targetFileName), counters);
|
||||||
|
|
||||||
|
// for (PathCounter counter : counters.values())
|
||||||
|
// {
|
||||||
|
// logger.info(counter.getPath() + " " +
|
||||||
|
// counter.getTimeMark() + " " + counter.getCounter());
|
||||||
|
// }
|
||||||
|
|
||||||
{
|
{
|
||||||
HttpAccessLogProber.probe(new File(sourceFileName), new File(targetFileName));
|
PathCounter counter = counters.get("metrics.http.hits", "2020");
|
||||||
|
logger.info("counter=" + counter.getCounter());
|
||||||
|
logger.info("size={}", counters.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// String sourceFileName =
|
|
||||||
// configuration.get("conf.probe.httperrorlogs.source");
|
|
||||||
// String targetFileName =
|
|
||||||
// configuration.get("conf.probe.httperrorlogs.target");
|
|
||||||
// if (!StringUtils.isAllBlank(sourceFileName, targetFileName))
|
|
||||||
// {
|
|
||||||
// HttpErrorLogProber.probe(sourceFileName, targetFileName);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IOUtils.closeQuietly(in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// String sourceFileName =
|
||||||
|
// configuration.get("conf.probe.httperrorlogs.source");
|
||||||
|
// String targetFileName =
|
||||||
|
// configuration.get("conf.probe.httperrorlogs.target");
|
||||||
|
// if (!StringUtils.isAllBlank(sourceFileName, targetFileName))
|
||||||
|
// {
|
||||||
|
// HttpErrorLogProber.probe(sourceFileName, targetFileName);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,10 +113,72 @@ public class Prober
|
||||||
*/
|
*/
|
||||||
public static void probe(final File configurationFile) throws StatoolInfosException, IOException
|
public static void probe(final File configurationFile) throws StatoolInfosException, IOException
|
||||||
{
|
{
|
||||||
logger.info("Htmlize {}", configurationFile.getAbsolutePath());
|
logger.info("Probe {}", configurationFile.getAbsolutePath());
|
||||||
|
|
||||||
Configuration configuration = Factory.loadConfiguration(configurationFile);
|
Configuration configuration = Factory.loadConfiguration(configurationFile);
|
||||||
|
|
||||||
probe(configuration);
|
probe(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write metrics.
|
||||||
|
*
|
||||||
|
* @param target
|
||||||
|
* the target
|
||||||
|
* @param counters
|
||||||
|
* the counters
|
||||||
|
* @throws UnsupportedEncodingException
|
||||||
|
* the unsupported encoding exception
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* the file not found exception
|
||||||
|
*/
|
||||||
|
public static void writeMetrics(final File target, final PathCounters counters) throws UnsupportedEncodingException, FileNotFoundException
|
||||||
|
{
|
||||||
|
StringList prefixes = counters.getPrefixes();
|
||||||
|
|
||||||
|
StringList metrics = new StringList();
|
||||||
|
for (String prefix : prefixes)
|
||||||
|
{
|
||||||
|
logger.info("====== {}", prefix);
|
||||||
|
|
||||||
|
PathCounters prefixCounters = counters.getByPrefix(prefix);
|
||||||
|
|
||||||
|
StringList years = prefixCounters.getYears().sort();
|
||||||
|
|
||||||
|
for (String year : years)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// Year.
|
||||||
|
PathCounter yearCounter = prefixCounters.get(prefix, year);
|
||||||
|
String line = String.format("%s.%s=%s", yearCounter.getPath(), yearCounter.getTimeMark(), yearCounter.getCounter());
|
||||||
|
metrics.appendln(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Months.
|
||||||
|
StringList line = new StringList();
|
||||||
|
line.append(prefix).append('.').append(year).append(".months=").append(prefixCounters.getMonthsValuesLine(prefix, year));
|
||||||
|
metrics.appendln(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Weeks.
|
||||||
|
StringList line = new StringList();
|
||||||
|
line.append(prefix).append('.').append(year).append(".weeks=").append(prefixCounters.getWeeksValuesLine(prefix, year));
|
||||||
|
metrics.appendln(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Days.
|
||||||
|
StringList line = new StringList();
|
||||||
|
line.append(prefix).append('.').append(year).append(".days=").append(prefixCounters.getDaysValuesLine(prefix, year));
|
||||||
|
metrics.appendln(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
metrics.appendln();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringsUtils.writeToFile(target, metrics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
197
src/fr/devinsy/statoolinfos/htmlize/probes/UserAgent.java
Normal file
197
src/fr/devinsy/statoolinfos/htmlize/probes/UserAgent.java
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.strings.StringList;
|
||||||
|
import fr.devinsy.strings.StringsUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class UserAgent.
|
||||||
|
*/
|
||||||
|
public class UserAgent
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(UserAgent.class);
|
||||||
|
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new user agent.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
*/
|
||||||
|
public UserAgent(final String source)
|
||||||
|
{
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the browser.
|
||||||
|
*
|
||||||
|
* @return the browser
|
||||||
|
*/
|
||||||
|
public UserAgentBrowser getBrowser()
|
||||||
|
{
|
||||||
|
UserAgentBrowser result;
|
||||||
|
|
||||||
|
if (StringUtils.containsIgnoreCase(this.source, "Firefox"))
|
||||||
|
{
|
||||||
|
result = UserAgentBrowser.FIREFOX;
|
||||||
|
}
|
||||||
|
else if (StringUtils.containsIgnoreCase(this.source, "Chrome"))
|
||||||
|
{
|
||||||
|
result = UserAgentBrowser.CHROME;
|
||||||
|
}
|
||||||
|
else if (StringUtils.containsIgnoreCase(this.source, "Lynx"))
|
||||||
|
{
|
||||||
|
result = UserAgentBrowser.LYNX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = UserAgentBrowser.OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the device.
|
||||||
|
*
|
||||||
|
* @return the device
|
||||||
|
*/
|
||||||
|
public UserAgentDevice getDevice()
|
||||||
|
{
|
||||||
|
UserAgentDevice result;
|
||||||
|
|
||||||
|
if (StringsUtils.containsAnyIgnoreCase(this.source, "iOS", "Android"))
|
||||||
|
{
|
||||||
|
result = UserAgentDevice.PHONE;
|
||||||
|
}
|
||||||
|
else if (StringsUtils.containsAnyIgnoreCase(this.source, "Playstation"))
|
||||||
|
{
|
||||||
|
result = UserAgentDevice.CONSOLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = UserAgentDevice.OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the os.
|
||||||
|
*
|
||||||
|
* @return the os
|
||||||
|
*/
|
||||||
|
public UserAgentOS getOS()
|
||||||
|
{
|
||||||
|
UserAgentOS result;
|
||||||
|
|
||||||
|
if (StringUtils.containsIgnoreCase(this.source, "Firefox"))
|
||||||
|
{
|
||||||
|
result = UserAgentOS.ANDROID;
|
||||||
|
}
|
||||||
|
else if (StringUtils.containsIgnoreCase(this.source, "Chrome"))
|
||||||
|
{
|
||||||
|
result = UserAgentOS.FREEBSD;
|
||||||
|
}
|
||||||
|
else if (StringUtils.containsIgnoreCase(this.source, "Lynx"))
|
||||||
|
{
|
||||||
|
result = UserAgentOS.GNULINUX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = UserAgentOS.OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type.
|
||||||
|
*
|
||||||
|
* @return the type
|
||||||
|
*/
|
||||||
|
public UserAgentType getType()
|
||||||
|
{
|
||||||
|
UserAgentType result;
|
||||||
|
|
||||||
|
// Source: http://www.useragentstring.com/pages/useragentstring.php.
|
||||||
|
StringList crawlerKeys = new StringList();
|
||||||
|
crawlerKeys.add("Accoona-AI-Agent");
|
||||||
|
crawlerKeys.add("AddSugarSpiderBot ");
|
||||||
|
crawlerKeys.add("AnyApexBot");
|
||||||
|
crawlerKeys.add("Arachmo");
|
||||||
|
crawlerKeys.add("B-l-i-t-z-B-O-T");
|
||||||
|
crawlerKeys.add("Baiduspider");
|
||||||
|
crawlerKeys.add("BecomeBot");
|
||||||
|
crawlerKeys.add("BeslistBot");
|
||||||
|
crawlerKeys.add("BillyBobBot");
|
||||||
|
crawlerKeys.add("Bimbot");
|
||||||
|
crawlerKeys.add("Bingbot");
|
||||||
|
crawlerKeys.add("BlitzBOT");
|
||||||
|
crawlerKeys.add("Chrome");
|
||||||
|
crawlerKeys.add("Firefox");
|
||||||
|
crawlerKeys.add("Lynx");
|
||||||
|
|
||||||
|
if (StringsUtils.containsAnyIgnoreCase(this.source, "Firefox", "Chrome", "Lynx", "MSIE", "Safari"))
|
||||||
|
{
|
||||||
|
result = UserAgentType.BROWSER;
|
||||||
|
}
|
||||||
|
else if (StringUtils.containsIgnoreCase(this.source, "Crawler"))
|
||||||
|
{
|
||||||
|
result = UserAgentType.CRAWLER;
|
||||||
|
}
|
||||||
|
else if (StringUtils.containsIgnoreCase(this.source, "Validator"))
|
||||||
|
{
|
||||||
|
result = UserAgentType.VALIDATOR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = UserAgentType.OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To string.
|
||||||
|
*
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = this.source;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Enum UserAgentBrowser.
|
||||||
|
*/
|
||||||
|
public enum UserAgentBrowser
|
||||||
|
{
|
||||||
|
CHROME,
|
||||||
|
CHROMIUM,
|
||||||
|
FIREFOX,
|
||||||
|
LYNX,
|
||||||
|
MSEDGE,
|
||||||
|
MSIE,
|
||||||
|
NETSCAPE,
|
||||||
|
OPERA,
|
||||||
|
SAFARI,
|
||||||
|
W3C,
|
||||||
|
OTHER
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Enum UserAgentDevice.
|
||||||
|
*/
|
||||||
|
public enum UserAgentDevice
|
||||||
|
{
|
||||||
|
CONSOLE,
|
||||||
|
PHONE,
|
||||||
|
TABLET,
|
||||||
|
PC,
|
||||||
|
OTHER
|
||||||
|
}
|
32
src/fr/devinsy/statoolinfos/htmlize/probes/UserAgentOS.java
Normal file
32
src/fr/devinsy/statoolinfos/htmlize/probes/UserAgentOS.java
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
public enum UserAgentOS
|
||||||
|
{
|
||||||
|
ANDROID,
|
||||||
|
FREEBSD,
|
||||||
|
GNULINUX,
|
||||||
|
IOS,
|
||||||
|
MSWINDOWS,
|
||||||
|
MACOS,
|
||||||
|
NETBSD,
|
||||||
|
OPENBSD,
|
||||||
|
OTHER
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.htmlize.probes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Enum UserAgentType.
|
||||||
|
*/
|
||||||
|
public enum UserAgentType
|
||||||
|
{
|
||||||
|
BROWSER,
|
||||||
|
CRAWLER,
|
||||||
|
CONSOLE,
|
||||||
|
FEED_READER,
|
||||||
|
LIBRARIE,
|
||||||
|
LINK_CHECKER,
|
||||||
|
VALIDATOR,
|
||||||
|
OTHER;
|
||||||
|
}
|
Loading…
Reference in a new issue