Step in probe devs.

This commit is contained in:
Christian P. MOMON 2021-02-11 02:36:03 +01:00
parent e4d122bbe4
commit 22addc634f
19 changed files with 2004 additions and 270 deletions

View file

@ -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();
} }
} }
} }

View file

@ -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.
* *

View file

@ -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.* =
}
}
}

View file

@ -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
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View file

@ -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;
}
}

View 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 dattente 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 dun 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 dinformation à 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;
}
}

View 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;
}
}
}

View file

@ -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()
{
}
}

View file

@ -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;

View file

@ -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);
}
}
} }

View file

@ -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);
}
} }

View 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;
}
}

View file

@ -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
}

View file

@ -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
}

View 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
}

View file

@ -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;
}