Added list and stat commands.
This commit is contained in:
parent
eb2dfdda4e
commit
be4635d8cb
23 changed files with 2221 additions and 46 deletions
|
@ -25,6 +25,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.core.LogFilter;
|
||||||
import fr.devinsy.statoolinfos.core.StatoolInfos;
|
import fr.devinsy.statoolinfos.core.StatoolInfos;
|
||||||
import fr.devinsy.statoolinfos.util.BuildInformation;
|
import fr.devinsy.statoolinfos.util.BuildInformation;
|
||||||
import fr.devinsy.statoolinfos.util.Chrono;
|
import fr.devinsy.statoolinfos.util.Chrono;
|
||||||
|
@ -108,7 +109,13 @@ public final class StatoolInfosCLI
|
||||||
message.appendln(" statoolinfos crawl <fileordirectory> crawl all file from conf and input");
|
message.appendln(" statoolinfos crawl <fileordirectory> crawl all file from conf and input");
|
||||||
message.appendln(" statoolinfos format <fileordirectory> format in tiny way");
|
message.appendln(" statoolinfos format <fileordirectory> format in tiny way");
|
||||||
message.appendln(" statoolinfos htmlize <fileordirectory> generate web pages from conf");
|
message.appendln(" statoolinfos htmlize <fileordirectory> generate web pages from conf");
|
||||||
|
message.appendln(" statoolinfos list ip [-bot|-nobot] <fileordirectory> generate ip list from log file");
|
||||||
|
message.appendln(" statoolinfos list ua [-bot|-nobot] <fileordirectory> generate user agent list from log file");
|
||||||
|
message.appendln(" statoolinfos list visitors [-bot|-nobot] <fileordirectory> generate visitors (ip+ua) list from log file");
|
||||||
message.appendln(" statoolinfos probe <fileordirectory> generate metrics files from conf");
|
message.appendln(" statoolinfos probe <fileordirectory> generate metrics files from conf");
|
||||||
|
message.appendln(" statoolinfos stat ip [-bot|-nobot] <fileordirectory> generate stats about ip from log file");
|
||||||
|
message.appendln(" statoolinfos stat ua [-bot|-nobot] <fileordirectory> generate stats about user agent from log file");
|
||||||
|
message.appendln(" statoolinfos stat visitors [-bot|-nobot] <fileordirectory> generate stats about visitors (ip+ua) from log file");
|
||||||
message.appendln(" statoolinfos tagdate <fileordirectory> update the file.datetime file");
|
message.appendln(" statoolinfos tagdate <fileordirectory> update the file.datetime file");
|
||||||
|
|
||||||
System.out.println(message.toString());
|
System.out.println(message.toString());
|
||||||
|
@ -185,6 +192,38 @@ public final class StatoolInfosCLI
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the log filter option.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @return the log filter
|
||||||
|
*/
|
||||||
|
private static LogFilter parseLogFilterOption(final String source)
|
||||||
|
{
|
||||||
|
LogFilter result;
|
||||||
|
|
||||||
|
if (StringUtils.equals(source, "-all"))
|
||||||
|
{
|
||||||
|
result = LogFilter.ALL;
|
||||||
|
}
|
||||||
|
else if (StringUtils.equals(source, "-bot"))
|
||||||
|
{
|
||||||
|
result = LogFilter.BOT;
|
||||||
|
}
|
||||||
|
else if (StringUtils.equals(source, "-nobot"))
|
||||||
|
{
|
||||||
|
result = LogFilter.NOBOT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* This method launch CLI.
|
* This method launch CLI.
|
||||||
|
@ -313,6 +352,45 @@ public final class StatoolInfosCLI
|
||||||
}
|
}
|
||||||
System.out.println(chrono.format());
|
System.out.println(chrono.format());
|
||||||
}
|
}
|
||||||
|
else if (isMatching(args, "list", "ip", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
File source = new File(args[2]);
|
||||||
|
|
||||||
|
StatoolInfos.listIps(source, LogFilter.ALL);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "list", "ip", "(-all|-bot|-nobot)", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
LogFilter filter = parseLogFilterOption(args[2]);
|
||||||
|
File source = new File(args[3]);
|
||||||
|
|
||||||
|
StatoolInfos.listIps(source, filter);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "list", "(useragent|ua)", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
File source = new File(args[2]);
|
||||||
|
|
||||||
|
StatoolInfos.listUserAgents(source, LogFilter.ALL);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "list", "(useragent|ua)", "(-all|-bot|-nobot)", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
LogFilter filter = parseLogFilterOption(args[2]);
|
||||||
|
File source = new File(args[3]);
|
||||||
|
|
||||||
|
StatoolInfos.listUserAgents(source, filter);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "list", "visitors", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
File source = new File(args[2]);
|
||||||
|
|
||||||
|
StatoolInfos.listVisitors(source, LogFilter.ALL);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "list", "visitors", "(-all|-bot|-nobot)", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
LogFilter filter = parseLogFilterOption(args[2]);
|
||||||
|
File source = new File(args[3]);
|
||||||
|
|
||||||
|
StatoolInfos.listVisitors(source, filter);
|
||||||
|
}
|
||||||
else if (isMatching(args, "probe", "\\s*.+\\s*"))
|
else if (isMatching(args, "probe", "\\s*.+\\s*"))
|
||||||
{
|
{
|
||||||
Files inputs = convertPath(StringUtils.trim(args[1]));
|
Files inputs = convertPath(StringUtils.trim(args[1]));
|
||||||
|
@ -329,6 +407,44 @@ public final class StatoolInfosCLI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (isMatching(args, "stat", "ip", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
File source = new File(args[2]);
|
||||||
|
|
||||||
|
StatoolInfos.statIps(source, LogFilter.ALL);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "stat", "ip", "(-all|-bot|-nobot)", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
LogFilter filter = parseLogFilterOption(args[2]);
|
||||||
|
File source = new File(args[3]);
|
||||||
|
|
||||||
|
StatoolInfos.statIps(source, filter);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "stat", "(useragent|ua)", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
File source = new File(args[2]);
|
||||||
|
StatoolInfos.statUserAgents(source, LogFilter.ALL);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "stat", "(useragent|ua)", "(-all|-bot|-nobot)", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
LogFilter filter = parseLogFilterOption(args[2]);
|
||||||
|
File source = new File(args[3]);
|
||||||
|
|
||||||
|
StatoolInfos.statUserAgents(source, filter);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "stat", "visitors", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
File source = new File(args[2]);
|
||||||
|
|
||||||
|
StatoolInfos.statVisitors(source, LogFilter.ALL);
|
||||||
|
}
|
||||||
|
else if (isMatching(args, "stat", "visitors", "(-all|-bot|-nobot)", "\\s*\\S+\\s*"))
|
||||||
|
{
|
||||||
|
LogFilter filter = parseLogFilterOption(args[2]);
|
||||||
|
File source = new File(args[3]);
|
||||||
|
|
||||||
|
StatoolInfos.statVisitors(source, filter);
|
||||||
|
}
|
||||||
else if (isMatching(args, "tagdate", "\\s*.+\\s*"))
|
else if (isMatching(args, "tagdate", "\\s*.+\\s*"))
|
||||||
{
|
{
|
||||||
Files inputs = FilesUtils.searchEndingWith(new File(args[1]), ".properties");
|
Files inputs = FilesUtils.searchEndingWith(new File(args[1]), ".properties");
|
||||||
|
|
67
src/fr/devinsy/statoolinfos/core/LogFilter.java
Normal file
67
src/fr/devinsy/statoolinfos/core/LogFilter.java
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* 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.core;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.metrics.http.HttpAccessLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Enum LogFilter.
|
||||||
|
*/
|
||||||
|
public enum LogFilter
|
||||||
|
{
|
||||||
|
ALL,
|
||||||
|
BOT,
|
||||||
|
NOBOT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches.
|
||||||
|
*
|
||||||
|
* @param log
|
||||||
|
* the log
|
||||||
|
* @return true, if successful
|
||||||
|
*/
|
||||||
|
public boolean matches(final HttpAccessLog log)
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
if (log == null)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
else if (this == ALL)
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else if ((this == BOT) && (log.isBot()))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else if ((this == NOBOT) && (!log.isBot()))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -31,8 +32,18 @@ import fr.devinsy.statoolinfos.build.Builder;
|
||||||
import fr.devinsy.statoolinfos.crawl.Crawler;
|
import fr.devinsy.statoolinfos.crawl.Crawler;
|
||||||
import fr.devinsy.statoolinfos.htmlize.Htmlizer;
|
import fr.devinsy.statoolinfos.htmlize.Htmlizer;
|
||||||
import fr.devinsy.statoolinfos.metrics.Prober;
|
import fr.devinsy.statoolinfos.metrics.Prober;
|
||||||
|
import fr.devinsy.statoolinfos.metrics.http.HttpAccessLog;
|
||||||
|
import fr.devinsy.statoolinfos.metrics.http.HttpAccessLogAnalyzer;
|
||||||
import fr.devinsy.statoolinfos.properties.PathProperties;
|
import fr.devinsy.statoolinfos.properties.PathProperties;
|
||||||
import fr.devinsy.statoolinfos.properties.PathPropertyUtils;
|
import fr.devinsy.statoolinfos.properties.PathPropertyUtils;
|
||||||
|
import fr.devinsy.statoolinfos.stats.ip.IpStat;
|
||||||
|
import fr.devinsy.statoolinfos.stats.ip.IpStator;
|
||||||
|
import fr.devinsy.statoolinfos.stats.useragent.UserAgentStat;
|
||||||
|
import fr.devinsy.statoolinfos.stats.useragent.UserAgentStator;
|
||||||
|
import fr.devinsy.statoolinfos.stats.visitor.VisitorStat;
|
||||||
|
import fr.devinsy.statoolinfos.stats.visitor.VisitorStator;
|
||||||
|
import fr.devinsy.statoolinfos.util.Chrono;
|
||||||
|
import fr.devinsy.statoolinfos.util.LineIterator;
|
||||||
import fr.devinsy.strings.StringList;
|
import fr.devinsy.strings.StringList;
|
||||||
import fr.devinsy.strings.StringsUtils;
|
import fr.devinsy.strings.StringsUtils;
|
||||||
|
|
||||||
|
@ -148,6 +159,159 @@ public class StatoolInfos
|
||||||
Htmlizer.htmlize(configurationFile);
|
Htmlizer.htmlize(configurationFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List ips.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void listIps(final File source, final LogFilter filter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IpStator stator = new IpStator();
|
||||||
|
|
||||||
|
Chrono chrono = new Chrono().start();
|
||||||
|
LineIterator iterator = new LineIterator(source);
|
||||||
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
|
String line = iterator.next();
|
||||||
|
HttpAccessLog log = HttpAccessLogAnalyzer.parseNginxCombinedLog(line);
|
||||||
|
|
||||||
|
if (filter.matches(log))
|
||||||
|
{
|
||||||
|
stator.putLog(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IpStat stat : stator.getIps())
|
||||||
|
{
|
||||||
|
System.out.println(stat.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(String.format("%s %10d", "Ip count: ", stator.getIps().size()));
|
||||||
|
System.err.println(String.format("%s %10d", "Log count: ", stator.getLogCount()));
|
||||||
|
System.err.println(chrono.format());
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad format line detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (DateTimeParseException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad datetime format detected. Aborting…");
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
System.out.println("File error detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List user agents.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
*/
|
||||||
|
public static void listUserAgents(final File source, final LogFilter filter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UserAgentStator stator = new UserAgentStator();
|
||||||
|
|
||||||
|
Chrono chrono = new Chrono().start();
|
||||||
|
LineIterator iterator = new LineIterator(source);
|
||||||
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
|
String line = iterator.next();
|
||||||
|
HttpAccessLog log = HttpAccessLogAnalyzer.parseNginxCombinedLog(line);
|
||||||
|
|
||||||
|
if (filter.matches(log))
|
||||||
|
{
|
||||||
|
stator.putLog(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UserAgentStat stat : stator.getUserAgentStats().sortByLabel())
|
||||||
|
{
|
||||||
|
System.out.println(stat.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(String.format("%s %10d", "UserAgent count: ", stator.getUserAgentStats().size()));
|
||||||
|
System.err.println(String.format("%s %10d", "Log count: ", stator.getLogCount()));
|
||||||
|
System.err.println(chrono.format());
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad format line detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (DateTimeParseException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad datetime format detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
System.out.println("File error detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List visitors.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
*/
|
||||||
|
public static void listVisitors(final File source, final LogFilter filter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
VisitorStator stator = new VisitorStator();
|
||||||
|
|
||||||
|
Chrono chrono = new Chrono().start();
|
||||||
|
LineIterator iterator = new LineIterator(source);
|
||||||
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
|
String line = iterator.next();
|
||||||
|
HttpAccessLog log = HttpAccessLogAnalyzer.parseNginxCombinedLog(line);
|
||||||
|
|
||||||
|
if (filter.matches(log))
|
||||||
|
{
|
||||||
|
stator.putLog(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (VisitorStat stat : stator.getVisitorStats().sortByIp())
|
||||||
|
{
|
||||||
|
System.out.println(stat.getIp() + " " + stat.getUserAgent());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(String.format("%s %10d", "Visitor count: ", stator.getVisitorStats().size()));
|
||||||
|
System.err.println(String.format("%s %10d", "Log count: ", stator.getLogCount()));
|
||||||
|
System.err.println(chrono.format());
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad format line detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (DateTimeParseException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad datetime format detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
System.out.println("File error detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stat.
|
* Stat.
|
||||||
*
|
*
|
||||||
|
@ -163,6 +327,157 @@ public class StatoolInfos
|
||||||
Prober.probe(configurationFile);
|
Prober.probe(configurationFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stat ips.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
*/
|
||||||
|
public static void statIps(final File source, final LogFilter filter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IpStator stator = new IpStator();
|
||||||
|
|
||||||
|
Chrono chrono = new Chrono().start();
|
||||||
|
LineIterator iterator = new LineIterator(source);
|
||||||
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
|
String line = iterator.next();
|
||||||
|
HttpAccessLog log = HttpAccessLogAnalyzer.parseNginxCombinedLog(line);
|
||||||
|
if (filter.matches(log))
|
||||||
|
{
|
||||||
|
stator.putLog(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IpStat stat : stator.getIps().sortByCount().reverse())
|
||||||
|
{
|
||||||
|
System.out.println(stat.getCount() + " " + stat.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(String.format("%s %10d", "Ip count: ", stator.getIps().size()));
|
||||||
|
System.err.println(String.format("%s %10d", "Log count: ", stator.getLogCount()));
|
||||||
|
System.err.println(chrono.format());
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad format line detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (DateTimeParseException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad datetime format detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
System.out.println("File error detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stat user agents.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
*/
|
||||||
|
public static void statUserAgents(final File source, final LogFilter filter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UserAgentStator stator = new UserAgentStator();
|
||||||
|
|
||||||
|
Chrono chrono = new Chrono().start();
|
||||||
|
LineIterator iterator = new LineIterator(source);
|
||||||
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
|
String line = iterator.next();
|
||||||
|
HttpAccessLog log = HttpAccessLogAnalyzer.parseNginxCombinedLog(line);
|
||||||
|
if (filter.matches(log))
|
||||||
|
{
|
||||||
|
stator.putLog(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UserAgentStat stat : stator.getUserAgentStats().sortByCount().reverse())
|
||||||
|
{
|
||||||
|
System.out.println(stat.getCount() + " " + stat.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(String.format("%s %10d", "User Agent count: ", stator.getUserAgentStats().size()));
|
||||||
|
System.err.println(String.format("%s %10d", "Log count: ", stator.getLogCount()));
|
||||||
|
System.err.println(chrono.format());
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad format line detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (DateTimeParseException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad datetime format detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
System.out.println("File error detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stat visitors.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
*/
|
||||||
|
public static void statVisitors(final File source, final LogFilter filter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
VisitorStator stator = new VisitorStator();
|
||||||
|
|
||||||
|
Chrono chrono = new Chrono().start();
|
||||||
|
LineIterator iterator = new LineIterator(source);
|
||||||
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
|
String line = iterator.next();
|
||||||
|
HttpAccessLog log = HttpAccessLogAnalyzer.parseNginxCombinedLog(line);
|
||||||
|
if (filter.matches(log))
|
||||||
|
{
|
||||||
|
stator.putLog(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (VisitorStat stat : stator.getVisitorStats().sortByVisitCount().reverse())
|
||||||
|
{
|
||||||
|
System.out.println(String.format("%d %d %s %s", stat.getVisits().size(), stat.getLogCount(), stat.getIp(), stat.getUserAgent()));
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(String.format("%s %10d", "Visitor count: ", stator.getVisitorStats().size()));
|
||||||
|
System.err.println(String.format("%s %10d", "Log count: ", stator.getLogCount()));
|
||||||
|
System.err.println(chrono.format());
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad format line detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (DateTimeParseException exception)
|
||||||
|
{
|
||||||
|
System.out.println("Bad datetime format detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
System.out.println("File error detected. Aborting…");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag date.
|
* Tag date.
|
||||||
*
|
*
|
||||||
|
@ -207,5 +522,4 @@ public class StatoolInfos
|
||||||
StringsUtils.save(inputFile, lines);
|
StringsUtils.save(inputFile, lines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class HttpAccessLog
|
||||||
public static final Pattern IPV4_PATTERN = Pattern.compile("\\d{0,3}\\.\\d{0,3}\\.\\d{0,3}\\.\\d{0,3}");
|
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);
|
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 ip;
|
||||||
private String remoteUser;
|
private String remoteUser;
|
||||||
private LocalDateTime time;
|
private LocalDateTime time;
|
||||||
private String request;
|
private String request;
|
||||||
|
@ -55,7 +55,7 @@ public class HttpAccessLog
|
||||||
*/
|
*/
|
||||||
public HttpAccessLog()
|
public HttpAccessLog()
|
||||||
{
|
{
|
||||||
this.remoteAddress = null;
|
this.ip = null;
|
||||||
this.remoteUser = null;
|
this.remoteUser = null;
|
||||||
this.time = null;
|
this.time = null;
|
||||||
this.request = null;
|
this.request = null;
|
||||||
|
@ -80,16 +80,16 @@ public class HttpAccessLog
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getIp()
|
||||||
|
{
|
||||||
|
return this.ip;
|
||||||
|
}
|
||||||
|
|
||||||
public String getReferer()
|
public String getReferer()
|
||||||
{
|
{
|
||||||
return this.referer;
|
return this.referer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRemoteAddress()
|
|
||||||
{
|
|
||||||
return this.remoteAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemoteUser()
|
public String getRemoteUser()
|
||||||
{
|
{
|
||||||
return this.remoteUser;
|
return this.remoteUser;
|
||||||
|
@ -185,7 +185,7 @@ public class HttpAccessLog
|
||||||
{
|
{
|
||||||
boolean result;
|
boolean result;
|
||||||
|
|
||||||
if (StringsUtils.containsAnyIgnoreCase(this.userAgent.toString(), "bot", "monitoring", "crawler"))
|
if (StringsUtils.containsAnyIgnoreCase(this.userAgent.toString(), "bot", "crawler", "monitoring", "HeadlessChrome"))
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
@ -215,13 +215,13 @@ public class HttpAccessLog
|
||||||
{
|
{
|
||||||
boolean result;
|
boolean result;
|
||||||
|
|
||||||
if (this.remoteAddress == null)
|
if (this.ip == null)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = this.remoteAddress.contains(".");
|
result = this.ip.contains(".");
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
@ -236,13 +236,13 @@ public class HttpAccessLog
|
||||||
{
|
{
|
||||||
boolean result;
|
boolean result;
|
||||||
|
|
||||||
if (this.remoteAddress == null)
|
if (this.ip == null)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = this.remoteAddress.contains(":");
|
result = this.ip.contains(":");
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
@ -253,16 +253,16 @@ public class HttpAccessLog
|
||||||
this.bodyBytesSent = bodyBytesSent;
|
this.bodyBytesSent = bodyBytesSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setIp(final String ip)
|
||||||
|
{
|
||||||
|
this.ip = ip;
|
||||||
|
}
|
||||||
|
|
||||||
public void setReferer(final String referer)
|
public void setReferer(final String referer)
|
||||||
{
|
{
|
||||||
this.referer = referer;
|
this.referer = referer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRemoteAddress(final String remoteAddress)
|
|
||||||
{
|
|
||||||
this.remoteAddress = remoteAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemoteUser(final String remoteUser)
|
public void setRemoteUser(final String remoteUser)
|
||||||
{
|
{
|
||||||
this.remoteUser = remoteUser;
|
this.remoteUser = remoteUser;
|
||||||
|
@ -300,7 +300,7 @@ public class HttpAccessLog
|
||||||
|
|
||||||
StringList buffer = new StringList();
|
StringList buffer = new StringList();
|
||||||
|
|
||||||
buffer.append("[remoteAddress=").append(this.remoteAddress).append("]");
|
buffer.append("[ip=").append(this.ip).append("]");
|
||||||
buffer.append("[remoteUser=").append(this.remoteUser).append("]");
|
buffer.append("[remoteUser=").append(this.remoteUser).append("]");
|
||||||
buffer.append("[time=").append(this.time).append("]");
|
buffer.append("[time=").append(this.time).append("]");
|
||||||
buffer.append("[request=").append(this.request).append("]");
|
buffer.append("[request=").append(this.request).append("]");
|
||||||
|
|
|
@ -220,28 +220,28 @@ public class HttpAccessLogAnalyzer
|
||||||
this.counters.inc("metrics.http.devices." + device.toString().toLowerCase(), year, yearMonth, yearWeek, date);
|
this.counters.inc("metrics.http.devices." + device.toString().toLowerCase(), year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
// metrics.http.ip.* =
|
// metrics.http.ip.* =
|
||||||
this.ips.put(log.getRemoteAddress(), year, yearMonth, yearWeek, date);
|
this.ips.put(log.getIp(), year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
// metrics.http.ip.ipv4.* =
|
// metrics.http.ip.ipv4.* =
|
||||||
// metrics.http.ip.ipv6.* =
|
// metrics.http.ip.ipv6.* =
|
||||||
if (log.isIPv4())
|
if (log.isIPv4())
|
||||||
{
|
{
|
||||||
this.ipv4.put(log.getRemoteAddress(), year, yearMonth, yearWeek, date);
|
this.ipv4.put(log.getIp(), year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.ipv6.put(log.getRemoteAddress(), year, yearMonth, yearWeek, date);
|
this.ipv6.put(log.getIp(), year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
// metrics.http.ip.bots.*
|
// metrics.http.ip.bots.*
|
||||||
// metrics.http.ip.visitors.*
|
// metrics.http.ip.visitors.*
|
||||||
if (log.isBot())
|
if (log.isBot())
|
||||||
{
|
{
|
||||||
this.botIps.put(log.getRemoteAddress(), year, yearMonth, yearWeek, date);
|
this.botIps.put(log.getIp(), year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.visitorIps.put(log.getRemoteAddress(), year, yearMonth, yearWeek, date);
|
this.visitorIps.put(log.getIp(), year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
// metrics.http.visits.* =
|
// metrics.http.visits.* =
|
||||||
|
@ -320,7 +320,7 @@ public class HttpAccessLogAnalyzer
|
||||||
if (matcher.matches())
|
if (matcher.matches())
|
||||||
{
|
{
|
||||||
result = new HttpAccessLog();
|
result = new HttpAccessLog();
|
||||||
result.setRemoteAddress(matcher.group("remoteAddress"));
|
result.setIp(matcher.group("remoteAddress"));
|
||||||
result.setRemoteUser(matcher.group("remoteUser"));
|
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.setTime(LocalDateTime.parse(matcher.group("time"), DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z").withLocale(Locale.ENGLISH)));
|
||||||
result.setRequest(matcher.group("request"));
|
result.setRequest(matcher.group("request"));
|
||||||
|
|
|
@ -57,11 +57,51 @@ public class VisitCounters extends HashMap<String, Visits>
|
||||||
* the log
|
* the log
|
||||||
* @return the string
|
* @return the string
|
||||||
*/
|
*/
|
||||||
public String computeKey(final HttpAccessLog log)
|
private String computeKey(final HttpAccessLog log)
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
|
|
||||||
result = String.format("%s--%s", log.getRemoteAddress(), log.getUserAgent().toString());
|
result = computeKey(log.getIp(), log.getUserAgent().toString());
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute key.
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* the ip
|
||||||
|
* @param userAgent
|
||||||
|
* the user agent
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
|
private String computeKey(final String ip, final String userAgent)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = String.format("%s--%s", ip, userAgent);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the.
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* the ip
|
||||||
|
* @param userAgent
|
||||||
|
* the user agent
|
||||||
|
* @return the visits
|
||||||
|
*/
|
||||||
|
public Visits get(final String ip, final String userAgent)
|
||||||
|
{
|
||||||
|
Visits result;
|
||||||
|
|
||||||
|
String key = computeKey(ip, userAgent);
|
||||||
|
|
||||||
|
result = get(key);
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
|
60
src/fr/devinsy/statoolinfos/stats/ip/IpStat.java
Normal file
60
src/fr/devinsy/statoolinfos/stats/ip/IpStat.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.ip;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class IpStat.
|
||||||
|
*/
|
||||||
|
public final class IpStat
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(IpStat.class);
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
private long count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new ip stat.
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* the ip
|
||||||
|
*/
|
||||||
|
public IpStat(final String ip)
|
||||||
|
{
|
||||||
|
this.value = ip;
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCount()
|
||||||
|
{
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void inc()
|
||||||
|
{
|
||||||
|
this.count += 1;
|
||||||
|
}
|
||||||
|
}
|
139
src/fr/devinsy/statoolinfos/stats/ip/IpStatComparator.java
Normal file
139
src/fr/devinsy/statoolinfos/stats/ip/IpStatComparator.java
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.stats.ip;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.util.CompareUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class IpStatComparator.
|
||||||
|
*/
|
||||||
|
public class IpStatComparator implements Comparator<IpStat>
|
||||||
|
{
|
||||||
|
public enum Sorting
|
||||||
|
{
|
||||||
|
IP,
|
||||||
|
COUNT
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sorting sorting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new category stat comparator.
|
||||||
|
*
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
*/
|
||||||
|
public IpStatComparator(final Sorting sorting)
|
||||||
|
{
|
||||||
|
this.sorting = sorting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare.
|
||||||
|
*
|
||||||
|
* @param alpha
|
||||||
|
* the alpha
|
||||||
|
* @param bravo
|
||||||
|
* the bravo
|
||||||
|
* @return the int
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compare(final IpStat alpha, final IpStat bravo)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = compare(alpha, bravo, this.sorting);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare.
|
||||||
|
*
|
||||||
|
* @param alpha
|
||||||
|
* the alpha
|
||||||
|
* @param bravo
|
||||||
|
* the bravo
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
* @return the int
|
||||||
|
*/
|
||||||
|
public static int compare(final IpStat alpha, final IpStat bravo, final Sorting sorting)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (sorting == null)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (sorting)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case IP:
|
||||||
|
result = CompareUtils.compare(getIp(alpha), getIp(bravo));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COUNT:
|
||||||
|
result = CompareUtils.compare(getCount(alpha), getCount(bravo));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user count.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @return the user count
|
||||||
|
*/
|
||||||
|
public static Long getCount(final IpStat source)
|
||||||
|
{
|
||||||
|
Long result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = (long) source.getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public static String getIp(final IpStat source)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = source.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
80
src/fr/devinsy/statoolinfos/stats/ip/IpStatSet.java
Normal file
80
src/fr/devinsy/statoolinfos/stats/ip/IpStatSet.java
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.ip;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class IpStatSet.
|
||||||
|
*/
|
||||||
|
public final class IpStatSet extends HashMap<String, IpStat>
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -8411746796941831991L;
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(IpStatSet.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new ip stats.
|
||||||
|
*/
|
||||||
|
public IpStatSet()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put.
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* the ip
|
||||||
|
*/
|
||||||
|
public void put(final String ip)
|
||||||
|
{
|
||||||
|
IpStat stat = get(ip);
|
||||||
|
if (stat == null)
|
||||||
|
{
|
||||||
|
stat = new IpStat(ip);
|
||||||
|
this.put(ip, stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
stat.inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To list.
|
||||||
|
*
|
||||||
|
* @return the ip stats
|
||||||
|
*/
|
||||||
|
public IpStats toList()
|
||||||
|
{
|
||||||
|
IpStats result;
|
||||||
|
|
||||||
|
result = new IpStats(this.size());
|
||||||
|
|
||||||
|
for (IpStat stat : this.values())
|
||||||
|
{
|
||||||
|
result.add(stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
71
src/fr/devinsy/statoolinfos/stats/ip/IpStator.java
Normal file
71
src/fr/devinsy/statoolinfos/stats/ip/IpStator.java
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.ip;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.metrics.http.HttpAccessLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class IpStator.
|
||||||
|
*/
|
||||||
|
public final class IpStator
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(IpStator.class);
|
||||||
|
|
||||||
|
private long logCount;
|
||||||
|
private IpStatSet ips;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new user agent stator.
|
||||||
|
*/
|
||||||
|
public IpStator()
|
||||||
|
{
|
||||||
|
this.logCount = 0;
|
||||||
|
this.ips = new IpStatSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IpStats getIps()
|
||||||
|
{
|
||||||
|
IpStats result;
|
||||||
|
|
||||||
|
result = this.ips.toList();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLogCount()
|
||||||
|
{
|
||||||
|
return this.logCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the log.
|
||||||
|
*
|
||||||
|
* @param log
|
||||||
|
* the log
|
||||||
|
*/
|
||||||
|
public void putLog(final HttpAccessLog log)
|
||||||
|
{
|
||||||
|
this.logCount += 1;
|
||||||
|
this.ips.put(log.getIp());
|
||||||
|
}
|
||||||
|
}
|
119
src/fr/devinsy/statoolinfos/stats/ip/IpStats.java
Normal file
119
src/fr/devinsy/statoolinfos/stats/ip/IpStats.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.stats.ip;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class IpStats.
|
||||||
|
*/
|
||||||
|
public final class IpStats extends ArrayList<IpStat>
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -2725108375443481335L;
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(IpStats.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new ip user agent stats.
|
||||||
|
*/
|
||||||
|
public IpStats()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new ip stats.
|
||||||
|
*
|
||||||
|
* @param capacity
|
||||||
|
* the capacity
|
||||||
|
*/
|
||||||
|
public IpStats(final int capacity)
|
||||||
|
{
|
||||||
|
super(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse.
|
||||||
|
*
|
||||||
|
* @return the ip stats
|
||||||
|
*/
|
||||||
|
public IpStats reverse()
|
||||||
|
{
|
||||||
|
IpStats result;
|
||||||
|
|
||||||
|
Collections.reverse(this);
|
||||||
|
|
||||||
|
result = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort.
|
||||||
|
*
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
* @return the ip stats
|
||||||
|
*/
|
||||||
|
public IpStats sort(final IpStatComparator.Sorting sorting)
|
||||||
|
{
|
||||||
|
IpStats result;
|
||||||
|
|
||||||
|
sort(new IpStatComparator(sorting));
|
||||||
|
|
||||||
|
result = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort count.
|
||||||
|
*
|
||||||
|
* @return the ip stats
|
||||||
|
*/
|
||||||
|
public IpStats sortByCount()
|
||||||
|
{
|
||||||
|
IpStats result;
|
||||||
|
|
||||||
|
result = sort(IpStatComparator.Sorting.COUNT);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by ip.
|
||||||
|
*
|
||||||
|
* @return the ip stats
|
||||||
|
*/
|
||||||
|
public IpStats sortByIp()
|
||||||
|
{
|
||||||
|
IpStats result;
|
||||||
|
|
||||||
|
result = sort(IpStatComparator.Sorting.IP);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.useragent;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class UserAgentStat.
|
||||||
|
*/
|
||||||
|
public final class UserAgentStat
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(UserAgentStat.class);
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
private long count;
|
||||||
|
private long ipLinkCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new user agent stat.
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* the ip
|
||||||
|
* @param userAgent
|
||||||
|
* the user agent
|
||||||
|
*/
|
||||||
|
public UserAgentStat(final String userAgent)
|
||||||
|
{
|
||||||
|
this.value = userAgent;
|
||||||
|
this.count = 0;
|
||||||
|
this.ipLinkCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCount()
|
||||||
|
{
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getIpLinkCount()
|
||||||
|
{
|
||||||
|
return this.ipLinkCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void inc()
|
||||||
|
{
|
||||||
|
this.count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIpLinkCount(final long ipLinkCount)
|
||||||
|
{
|
||||||
|
this.ipLinkCount = ipLinkCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.stats.useragent;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.util.CompareUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class UserAgentStatComparator.
|
||||||
|
*/
|
||||||
|
public class UserAgentStatComparator implements Comparator<UserAgentStat>
|
||||||
|
{
|
||||||
|
public enum Sorting
|
||||||
|
{
|
||||||
|
USERAGENT,
|
||||||
|
COUNT
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sorting sorting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new category stat comparator.
|
||||||
|
*
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
*/
|
||||||
|
public UserAgentStatComparator(final Sorting sorting)
|
||||||
|
{
|
||||||
|
this.sorting = sorting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare.
|
||||||
|
*
|
||||||
|
* @param alpha
|
||||||
|
* the alpha
|
||||||
|
* @param bravo
|
||||||
|
* the bravo
|
||||||
|
* @return the int
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compare(final UserAgentStat alpha, final UserAgentStat bravo)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = compare(alpha, bravo, this.sorting);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare.
|
||||||
|
*
|
||||||
|
* @param alpha
|
||||||
|
* the alpha
|
||||||
|
* @param bravo
|
||||||
|
* the bravo
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
* @return the int
|
||||||
|
*/
|
||||||
|
public static int compare(final UserAgentStat alpha, final UserAgentStat bravo, final Sorting sorting)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (sorting == null)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (sorting)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case USERAGENT:
|
||||||
|
result = CompareUtils.compare(getUserAgent(alpha), getUserAgent(bravo));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COUNT:
|
||||||
|
result = CompareUtils.compare(getCount(alpha), getCount(bravo));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the count.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @return the count
|
||||||
|
*/
|
||||||
|
public static Long getCount(final UserAgentStat source)
|
||||||
|
{
|
||||||
|
Long result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = (long) source.getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user agent.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @return the user agent
|
||||||
|
*/
|
||||||
|
public static String getUserAgent(final UserAgentStat source)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = source.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.useragent;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class UserAgents.
|
||||||
|
*/
|
||||||
|
public final class UserAgentStatSet extends HashMap<String, UserAgentStat>
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -7943808966632477322L;
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(UserAgentStatSet.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new user agents.
|
||||||
|
*/
|
||||||
|
public UserAgentStatSet()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(final String userAgent)
|
||||||
|
{
|
||||||
|
UserAgentStat stat = get(userAgent);
|
||||||
|
if (stat == null)
|
||||||
|
{
|
||||||
|
stat = new UserAgentStat(userAgent);
|
||||||
|
this.put(userAgent, stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
stat.inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put.
|
||||||
|
*
|
||||||
|
* @param userAgent
|
||||||
|
* the user agent
|
||||||
|
*/
|
||||||
|
public void put(final UserAgentStat userAgent)
|
||||||
|
{
|
||||||
|
this.put(userAgent.getValue(), userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To list.
|
||||||
|
*
|
||||||
|
* @return the user agent stats
|
||||||
|
*/
|
||||||
|
public UserAgentStats toList()
|
||||||
|
{
|
||||||
|
UserAgentStats result;
|
||||||
|
|
||||||
|
result = new UserAgentStats(this.size());
|
||||||
|
|
||||||
|
for (UserAgentStat stat : this.values())
|
||||||
|
{
|
||||||
|
result.add(stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.useragent;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.metrics.http.HttpAccessLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class UserAgentStator.
|
||||||
|
*/
|
||||||
|
public final class UserAgentStator
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(UserAgentStator.class);
|
||||||
|
|
||||||
|
private long logCount;
|
||||||
|
private UserAgentStatSet userAgents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new user agent stator.
|
||||||
|
*/
|
||||||
|
public UserAgentStator()
|
||||||
|
{
|
||||||
|
this.logCount = 0;
|
||||||
|
this.userAgents = new UserAgentStatSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLogCount()
|
||||||
|
{
|
||||||
|
return this.logCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user agent stats.
|
||||||
|
*
|
||||||
|
* @return the user agent stats
|
||||||
|
*/
|
||||||
|
public UserAgentStats getUserAgentStats()
|
||||||
|
{
|
||||||
|
UserAgentStats result;
|
||||||
|
|
||||||
|
result = this.userAgents.toList();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the log.
|
||||||
|
*
|
||||||
|
* @param log
|
||||||
|
* the log
|
||||||
|
*/
|
||||||
|
public void putLog(final HttpAccessLog log)
|
||||||
|
{
|
||||||
|
String userAgent = log.getUserAgent().toString().trim();
|
||||||
|
|
||||||
|
this.logCount += 1;
|
||||||
|
this.userAgents.put(userAgent);
|
||||||
|
}
|
||||||
|
}
|
119
src/fr/devinsy/statoolinfos/stats/useragent/UserAgentStats.java
Normal file
119
src/fr/devinsy/statoolinfos/stats/useragent/UserAgentStats.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.stats.useragent;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class UserAgentStats.
|
||||||
|
*/
|
||||||
|
public final class UserAgentStats extends ArrayList<UserAgentStat>
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -6389473662022565639L;
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(UserAgentStats.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new user agent stats.
|
||||||
|
*/
|
||||||
|
public UserAgentStats()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new user agent stats.
|
||||||
|
*
|
||||||
|
* @param capacity
|
||||||
|
* the capacity
|
||||||
|
*/
|
||||||
|
public UserAgentStats(final int capacity)
|
||||||
|
{
|
||||||
|
super(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse.
|
||||||
|
*
|
||||||
|
* @return the user agent stats
|
||||||
|
*/
|
||||||
|
public UserAgentStats reverse()
|
||||||
|
{
|
||||||
|
UserAgentStats result;
|
||||||
|
|
||||||
|
Collections.reverse(this);
|
||||||
|
|
||||||
|
result = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort.
|
||||||
|
*
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
* @return the ip stats
|
||||||
|
*/
|
||||||
|
public UserAgentStats sort(final UserAgentStatComparator.Sorting sorting)
|
||||||
|
{
|
||||||
|
UserAgentStats result;
|
||||||
|
|
||||||
|
sort(new UserAgentStatComparator(sorting));
|
||||||
|
|
||||||
|
result = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by count.
|
||||||
|
*
|
||||||
|
* @return the user agent stats
|
||||||
|
*/
|
||||||
|
public UserAgentStats sortByCount()
|
||||||
|
{
|
||||||
|
UserAgentStats result;
|
||||||
|
|
||||||
|
result = sort(UserAgentStatComparator.Sorting.COUNT);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by ip.
|
||||||
|
*
|
||||||
|
* @return the user agent stats
|
||||||
|
*/
|
||||||
|
public UserAgentStats sortByLabel()
|
||||||
|
{
|
||||||
|
UserAgentStats result;
|
||||||
|
|
||||||
|
result = sort(UserAgentStatComparator.Sorting.USERAGENT);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
93
src/fr/devinsy/statoolinfos/stats/visitor/VisitorStat.java
Normal file
93
src/fr/devinsy/statoolinfos/stats/visitor/VisitorStat.java
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.visitor;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.metrics.http.Visits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class VisitorStat.
|
||||||
|
*/
|
||||||
|
public final class VisitorStat
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(VisitorStat.class);
|
||||||
|
|
||||||
|
private String ip;
|
||||||
|
private String userAgent;
|
||||||
|
private long logCount;
|
||||||
|
private Visits visits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new visitor stat.
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* the ip
|
||||||
|
* @param userAgent
|
||||||
|
* the user agent
|
||||||
|
*/
|
||||||
|
public VisitorStat(final String ip, final String userAgent)
|
||||||
|
{
|
||||||
|
this.ip = ip;
|
||||||
|
this.userAgent = userAgent;
|
||||||
|
this.logCount = 0;
|
||||||
|
this.visits = new Visits();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIp()
|
||||||
|
{
|
||||||
|
return this.ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLogCount()
|
||||||
|
{
|
||||||
|
return this.logCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserAgent()
|
||||||
|
{
|
||||||
|
return this.userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the visit count.
|
||||||
|
*
|
||||||
|
* @return the visit count
|
||||||
|
*/
|
||||||
|
public long getVisitCount()
|
||||||
|
{
|
||||||
|
long result;
|
||||||
|
|
||||||
|
result = this.visits.size();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Visits getVisits()
|
||||||
|
{
|
||||||
|
return this.visits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void inc()
|
||||||
|
{
|
||||||
|
this.logCount += 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package fr.devinsy.statoolinfos.stats.visitor;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.util.CompareUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class VisitorStatComparator.
|
||||||
|
*/
|
||||||
|
public class VisitorStatComparator implements Comparator<VisitorStat>
|
||||||
|
{
|
||||||
|
public enum Sorting
|
||||||
|
{
|
||||||
|
IP,
|
||||||
|
USERAGENT,
|
||||||
|
LOGCOUNT,
|
||||||
|
VISITCOUNT
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sorting sorting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new visitor stat comparator.
|
||||||
|
*
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
*/
|
||||||
|
public VisitorStatComparator(final Sorting sorting)
|
||||||
|
{
|
||||||
|
this.sorting = sorting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare.
|
||||||
|
*
|
||||||
|
* @param alpha
|
||||||
|
* the alpha
|
||||||
|
* @param bravo
|
||||||
|
* the bravo
|
||||||
|
* @return the int
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compare(final VisitorStat alpha, final VisitorStat bravo)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = compare(alpha, bravo, this.sorting);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare.
|
||||||
|
*
|
||||||
|
* @param alpha
|
||||||
|
* the alpha
|
||||||
|
* @param bravo
|
||||||
|
* the bravo
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
* @return the int
|
||||||
|
*/
|
||||||
|
public static int compare(final VisitorStat alpha, final VisitorStat bravo, final Sorting sorting)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (sorting == null)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (sorting)
|
||||||
|
{
|
||||||
|
case IP:
|
||||||
|
result = CompareUtils.compare(getIp(alpha), getIp(bravo));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case USERAGENT:
|
||||||
|
result = CompareUtils.compare(getUserAgent(alpha), getUserAgent(bravo));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOGCOUNT:
|
||||||
|
result = CompareUtils.compare(getLogCount(alpha), getLogCount(bravo));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VISITCOUNT:
|
||||||
|
result = CompareUtils.compare(getVisitCount(alpha), getVisitCount(bravo));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ip.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @return the ip
|
||||||
|
*/
|
||||||
|
public static String getIp(final VisitorStat source)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = source.getIp();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the count.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @return the count
|
||||||
|
*/
|
||||||
|
public static Long getLogCount(final VisitorStat source)
|
||||||
|
{
|
||||||
|
Long result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = (long) source.getLogCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user agent.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* the source
|
||||||
|
* @return the user agent
|
||||||
|
*/
|
||||||
|
public static String getUserAgent(final VisitorStat source)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = source.getUserAgent();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long getVisitCount(final VisitorStat source)
|
||||||
|
{
|
||||||
|
Long result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = (long) source.getVisitCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
118
src/fr/devinsy/statoolinfos/stats/visitor/VisitorStatSet.java
Normal file
118
src/fr/devinsy/statoolinfos/stats/visitor/VisitorStatSet.java
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.visitor;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.stats.useragent.UserAgentStat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class VisitorStatSet.
|
||||||
|
*/
|
||||||
|
public final class VisitorStatSet extends HashMap<String, VisitorStat>
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -3123113539922160408L;
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(VisitorStatSet.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new visitor stat set.
|
||||||
|
*/
|
||||||
|
public VisitorStatSet()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute key.
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* the ip
|
||||||
|
* @param userAgent
|
||||||
|
* the user agent
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
|
private String computeKey(final String ip, final String userAgent)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = ip + userAgent.trim();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put.
|
||||||
|
*
|
||||||
|
* @param userAgent
|
||||||
|
* the user agent
|
||||||
|
*/
|
||||||
|
public VisitorStat put(final String ip, final String userAgent)
|
||||||
|
{
|
||||||
|
VisitorStat result;
|
||||||
|
|
||||||
|
String key = computeKey(ip, userAgent);
|
||||||
|
|
||||||
|
result = get(key);
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
result = new VisitorStat(ip, userAgent);
|
||||||
|
this.put(key, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.inc();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put.
|
||||||
|
*
|
||||||
|
* @param userAgent
|
||||||
|
* the user agent
|
||||||
|
*/
|
||||||
|
public void put(final String ip, final UserAgentStat userAgent)
|
||||||
|
{
|
||||||
|
this.put(userAgent.getValue(), userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To list.
|
||||||
|
*
|
||||||
|
* @return the user agent stats
|
||||||
|
*/
|
||||||
|
public VisitorStats toList()
|
||||||
|
{
|
||||||
|
VisitorStats result;
|
||||||
|
|
||||||
|
result = new VisitorStats(this.size());
|
||||||
|
|
||||||
|
for (VisitorStat stat : this.values())
|
||||||
|
{
|
||||||
|
result.add(stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
85
src/fr/devinsy/statoolinfos/stats/visitor/VisitorStator.java
Normal file
85
src/fr/devinsy/statoolinfos/stats/visitor/VisitorStator.java
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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.stats.visitor;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.statoolinfos.metrics.http.HttpAccessLog;
|
||||||
|
import fr.devinsy.statoolinfos.metrics.http.HttpStatusCategory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class VisitorStator.
|
||||||
|
*/
|
||||||
|
public final class VisitorStator
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(VisitorStator.class);
|
||||||
|
|
||||||
|
private long logCount;
|
||||||
|
private VisitorStatSet visitors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new visitor stator.
|
||||||
|
*/
|
||||||
|
public VisitorStator()
|
||||||
|
{
|
||||||
|
this.logCount = 0;
|
||||||
|
this.visitors = new VisitorStatSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLogCount()
|
||||||
|
{
|
||||||
|
return this.logCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the visitors.
|
||||||
|
*
|
||||||
|
* @return the visitors
|
||||||
|
*/
|
||||||
|
public VisitorStats getVisitorStats()
|
||||||
|
{
|
||||||
|
VisitorStats result;
|
||||||
|
|
||||||
|
result = this.visitors.toList();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the log.
|
||||||
|
*
|
||||||
|
* @param log
|
||||||
|
* the log
|
||||||
|
*/
|
||||||
|
public void putLog(final HttpAccessLog log)
|
||||||
|
{
|
||||||
|
if (log != null)
|
||||||
|
{
|
||||||
|
this.logCount += 1;
|
||||||
|
VisitorStat stat = this.visitors.put(log.getIp(), log.getUserAgent().toString());
|
||||||
|
|
||||||
|
if (log.getStatus().getCategory() == HttpStatusCategory.SUCCESS)
|
||||||
|
{
|
||||||
|
stat.getVisits().add(log.getTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
149
src/fr/devinsy/statoolinfos/stats/visitor/VisitorStats.java
Normal file
149
src/fr/devinsy/statoolinfos/stats/visitor/VisitorStats.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.stats.visitor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class VisitorStats.
|
||||||
|
*/
|
||||||
|
public final class VisitorStats extends ArrayList<VisitorStat>
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 8866450468875949301L;
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(VisitorStats.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new visitor stats.
|
||||||
|
*/
|
||||||
|
public VisitorStats()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new visitor stats.
|
||||||
|
*
|
||||||
|
* @param capacity
|
||||||
|
* the capacity
|
||||||
|
*/
|
||||||
|
public VisitorStats(final int capacity)
|
||||||
|
{
|
||||||
|
super(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse.
|
||||||
|
*
|
||||||
|
* @return the visitor stats
|
||||||
|
*/
|
||||||
|
public VisitorStats reverse()
|
||||||
|
{
|
||||||
|
VisitorStats result;
|
||||||
|
|
||||||
|
Collections.reverse(this);
|
||||||
|
|
||||||
|
result = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort.
|
||||||
|
*
|
||||||
|
* @param sorting
|
||||||
|
* the sorting
|
||||||
|
* @return the visitor stats
|
||||||
|
*/
|
||||||
|
public VisitorStats sort(final VisitorStatComparator.Sorting sorting)
|
||||||
|
{
|
||||||
|
VisitorStats result;
|
||||||
|
|
||||||
|
sort(new VisitorStatComparator(sorting));
|
||||||
|
|
||||||
|
result = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by ip.
|
||||||
|
*
|
||||||
|
* @return the visitor stats
|
||||||
|
*/
|
||||||
|
public VisitorStats sortByIp()
|
||||||
|
{
|
||||||
|
VisitorStats result;
|
||||||
|
|
||||||
|
result = sort(VisitorStatComparator.Sorting.IP);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by count.
|
||||||
|
*
|
||||||
|
* @return the visitor stats
|
||||||
|
*/
|
||||||
|
public VisitorStats sortByLogCount()
|
||||||
|
{
|
||||||
|
VisitorStats result;
|
||||||
|
|
||||||
|
result = sort(VisitorStatComparator.Sorting.LOGCOUNT);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by label.
|
||||||
|
*
|
||||||
|
* @return the visitor stats
|
||||||
|
*/
|
||||||
|
public VisitorStats sortByUserAgent()
|
||||||
|
{
|
||||||
|
VisitorStats result;
|
||||||
|
|
||||||
|
result = sort(VisitorStatComparator.Sorting.USERAGENT);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by visit count.
|
||||||
|
*
|
||||||
|
* @return the visitor stats
|
||||||
|
*/
|
||||||
|
public VisitorStats sortByVisitCount()
|
||||||
|
{
|
||||||
|
VisitorStats result;
|
||||||
|
|
||||||
|
result = sort(VisitorStatComparator.Sorting.VISITCOUNT);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,11 @@ import java.time.ZoneOffset;
|
||||||
*/
|
*/
|
||||||
public class Chrono
|
public class Chrono
|
||||||
{
|
{
|
||||||
|
public static final long DEFAULT_MESSAGE_INTERVAL = 60;
|
||||||
|
|
||||||
private LocalDateTime start;
|
private LocalDateTime start;
|
||||||
|
private long previousDurationMessage;
|
||||||
|
private long messageInterval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new time keeper.
|
* Instantiates a new time keeper.
|
||||||
|
@ -35,6 +39,27 @@ public class Chrono
|
||||||
public Chrono()
|
public Chrono()
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
this.messageInterval = DEFAULT_MESSAGE_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check message.
|
||||||
|
*
|
||||||
|
* @param current
|
||||||
|
* the current
|
||||||
|
* @param max
|
||||||
|
* the max
|
||||||
|
*/
|
||||||
|
public void checkMessage(final long current, final long max)
|
||||||
|
{
|
||||||
|
long currentDuration = duration();
|
||||||
|
|
||||||
|
if ((currentDuration % this.messageInterval == 0) && (currentDuration != this.previousDurationMessage))
|
||||||
|
{
|
||||||
|
this.previousDurationMessage = currentDuration;
|
||||||
|
System.out.println(format());
|
||||||
|
System.out.println(String.format("%s %d/%d", format(), current, max));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,6 +108,18 @@ public class Chrono
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
this.start = null;
|
this.start = null;
|
||||||
|
this.previousDurationMessage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the check intervale.
|
||||||
|
*
|
||||||
|
* @param seconds
|
||||||
|
* the new check intervale
|
||||||
|
*/
|
||||||
|
public void setMessageInterval(final long seconds)
|
||||||
|
{
|
||||||
|
this.messageInterval = seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,6 +130,7 @@ public class Chrono
|
||||||
Chrono result;
|
Chrono result;
|
||||||
|
|
||||||
this.start = LocalDateTime.now();
|
this.start = LocalDateTime.now();
|
||||||
|
this.previousDurationMessage = 0L;
|
||||||
|
|
||||||
result = this;
|
result = this;
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class VisitCountersTest
|
||||||
|
|
||||||
//
|
//
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 23, 0));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 23, 0));
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
|
@ -84,14 +84,14 @@ public class VisitCountersTest
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 0));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 0));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 20));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 20));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
|
@ -124,21 +124,21 @@ public class VisitCountersTest
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 0));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 0));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 20));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 20));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 55));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 55));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
|
@ -171,21 +171,21 @@ public class VisitCountersTest
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 0));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 0));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 55));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 55));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 20));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 20));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
|
@ -218,21 +218,21 @@ public class VisitCountersTest
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 0));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 0));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 35));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 35));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HttpAccessLog log = new HttpAccessLog();
|
HttpAccessLog log = new HttpAccessLog();
|
||||||
log.setRemoteAddress("192.168.1.1");
|
log.setIp("192.168.1.1");
|
||||||
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
log.setUserAgent(new UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"));
|
||||||
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 20));
|
log.setTime(LocalDateTime.of(2020, 10, 20, 12, 20));
|
||||||
visitCounters.putVisit(log);
|
visitCounters.putVisit(log);
|
||||||
|
|
Loading…
Reference in a new issue