Compare commits
No commits in common. "20a58e2b1d103c339d981017bbfe64b8a7b373d2" and "8f8eeb437dee6810ee116af6aa619c2e4a3b179b" have entirely different histories.
20a58e2b1d
...
8f8eeb437d
|
@ -15,6 +15,7 @@
|
||||||
<classpathentry kind="lib" path="lib/hsqldb-2.3.0.jar"/>
|
<classpathentry kind="lib" path="lib/hsqldb-2.3.0.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/UnitTesting/junit-4.12.jar" sourcepath="lib/UnitTesting/junit-4.12-sources.jar"/>
|
<classpathentry kind="lib" path="lib/UnitTesting/junit-4.12.jar" sourcepath="lib/UnitTesting/junit-4.12-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/commons-cli-1.4.jar" sourcepath="lib/commons-cli-1.4-sources.jar"/>
|
<classpathentry kind="lib" path="lib/commons-cli-1.4.jar" sourcepath="lib/commons-cli-1.4-sources.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/commons-io-2.7.jar" sourcepath="lib/commons-io-2.7-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/commons-lang3-3.11.jar" sourcepath="lib/commons-lang3-3.11-sources.jar"/>
|
<classpathentry kind="lib" path="lib/commons-lang3-3.11.jar" sourcepath="lib/commons-lang3-3.11-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/commons-text-1.9.jar" sourcepath="lib/commons-text-1.9-sources.jar"/>
|
<classpathentry kind="lib" path="lib/commons-text-1.9.jar" sourcepath="lib/commons-text-1.9-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/tika-core-1.24.1.jar" sourcepath="lib/tika-core-1.24.1-sources.jar"/>
|
<classpathentry kind="lib" path="lib/tika-core-1.24.1.jar" sourcepath="lib/tika-core-1.24.1-sources.jar"/>
|
||||||
|
@ -27,6 +28,5 @@
|
||||||
<classpathentry kind="lib" path="lib/Logs/log4j-api-2.17.1.jar" sourcepath="lib/Logs/log4j-api-2.17.1-sources.jar"/>
|
<classpathentry kind="lib" path="lib/Logs/log4j-api-2.17.1.jar" sourcepath="lib/Logs/log4j-api-2.17.1-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/Logs/log4j-core-2.17.1.jar" sourcepath="lib/Logs/log4j-core-2.17.1-sources.jar"/>
|
<classpathentry kind="lib" path="lib/Logs/log4j-core-2.17.1.jar" sourcepath="lib/Logs/log4j-core-2.17.1-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/Logs/log4j-slf4j-impl-2.17.1.jar" sourcepath="lib/Logs/log4j-slf4j-impl-2.17.1-sources.jar"/>
|
<classpathentry kind="lib" path="lib/Logs/log4j-slf4j-impl-2.17.1.jar" sourcepath="lib/Logs/log4j-slf4j-impl-2.17.1-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/commons-io-2.11.0.jar" sourcepath="lib/commons-io-2.11.0-sources.jar"/>
|
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
104
README.md
|
@ -19,6 +19,7 @@ I am glad to use the beautiful artwork of David Revoy (http://www.peppercarrot.c
|
||||||
* Source: https://framagit.org/Deevad/cat-avatar-generator
|
* Source: https://framagit.org/Deevad/cat-avatar-generator
|
||||||
* Originally inspired of the code for "MonsterID" by Andreas Gohr http://www.splitbrain.org/go/monsterid.
|
* Originally inspired of the code for "MonsterID" by Andreas Gohr http://www.splitbrain.org/go/monsterid.
|
||||||
|
|
||||||
|
|
||||||
### Cicle-icons
|
### Cicle-icons
|
||||||
|
|
||||||
I am glad to use the generous artwork of ElegantThemes.com :
|
I am glad to use the generous artwork of ElegantThemes.com :
|
||||||
|
@ -89,19 +90,15 @@ Usage:
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Generate metrics files
|
### Generate metrics files
|
||||||
|
|
||||||
### Basics
|
|
||||||
|
|
||||||
Create a configuration file `/srv/statoolInfos/conf/foo.bar.org.conf`:
|
Create a configuration file `/srv/statoolInfos/conf/foo.bar.org.conf`:
|
||||||
|
|
||||||
```
|
```
|
||||||
conf.probe.types=<metrictype1>, <metrictype2>
|
conf.probe.types=HttpAccessLog, HttpErrorLog
|
||||||
conf.probe.metrictype1param1.file=<value>
|
conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
|
||||||
conf.probe.metrictype1param2.file=<value>
|
conf.probe.httperrorlog.file=/var/log/apache2/foo.bar.org-error.log*
|
||||||
conf.probe.metrictype2param1.file=<value>
|
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org.metrics
|
||||||
conf.probe.metrictype2param2.file=<value>
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Generate the metric file for the first time:
|
Generate the metric file for the first time:
|
||||||
|
@ -117,92 +114,3 @@ Create a cron file to update the metric file everyday:
|
||||||
```
|
```
|
||||||
|
|
||||||
Warning: in previous day mode, the metrics generated are overwrited for the last month, the last week and the last day. So, six weeks in logs are required.
|
Warning: in previous day mode, the metrics generated are overwrited for the last month, the last week and the last day. So, six weeks in logs are required.
|
||||||
|
|
||||||
|
|
||||||
### Web metrics
|
|
||||||
|
|
||||||
Configuration template:
|
|
||||||
|
|
||||||
```
|
|
||||||
conf.probe.types=HttpAccessLog, HttpErrorLog
|
|
||||||
conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
|
|
||||||
conf.probe.httperrorlog.file=/var/log/apache2/foo.bar.org-error.log*
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
|
|
||||||
# Custom access log pattern with Java regex.
|
|
||||||
# Default: "^(?<remoteAddress>[a-zA-F0-9\\\\:\\\\.]+) - (?<remoteUser>[^\\[]+) \\[(?<time>[^\\]]+)\\] \"(?<request>.*)\" (?<status>\\d+) (?<bodyBytesSent>\\d+) \"(?<referer>.*)\" \"(?<userAgent>[^\"]*)\".*$"
|
|
||||||
conf.probe.httpaccesslog.pattern=
|
|
||||||
```
|
|
||||||
|
|
||||||
### Minetest metrics
|
|
||||||
|
|
||||||
Configuration template:
|
|
||||||
|
|
||||||
```
|
|
||||||
conf.probe.types=Minetest
|
|
||||||
conf.probe.minetest.logs=/home/cpm/Projets/StatoolInfos/EnvTest/minetest/minetest.log*
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mumble metrics
|
|
||||||
|
|
||||||
Configuration template:
|
|
||||||
|
|
||||||
```
|
|
||||||
conf.probe.types=Mumble
|
|
||||||
conf.probe.mumble.logs=/var/log/mumble-server/mumble-server.log*
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
```
|
|
||||||
|
|
||||||
### PrivateBin metrics (experimental)
|
|
||||||
|
|
||||||
Warning: works fine if database, image and comment options are disabled.
|
|
||||||
|
|
||||||
Configuration template:
|
|
||||||
|
|
||||||
```
|
|
||||||
conf.probe.types=PrivateBin
|
|
||||||
conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
|
|
||||||
conf.probe.privatebin.data=/var/www/paste.libre-service.eu/data/
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
```
|
|
||||||
|
|
||||||
### Framdadate metrics (coming soon)
|
|
||||||
|
|
||||||
Configuration template:
|
|
||||||
|
|
||||||
```
|
|
||||||
conf.probe.types=Framadate
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
```
|
|
||||||
### Gitea metrics (coming soon)
|
|
||||||
|
|
||||||
Configuration template:
|
|
||||||
|
|
||||||
```
|
|
||||||
conf.probe.types=Gitea
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
```
|
|
||||||
|
|
||||||
### LibreQR metrics (coming soon)
|
|
||||||
|
|
||||||
Configuration template:
|
|
||||||
|
|
||||||
```
|
|
||||||
conf.probe.types=LibreQR
|
|
||||||
conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
|
|
||||||
conf.probe.libreqr.data=/var/www/qrcode.libre-service.eu/data/
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
```
|
|
||||||
|
|
||||||
### Nextcloud metrics (coming soon)
|
|
||||||
|
|
||||||
Configuration template:
|
|
||||||
|
|
||||||
```
|
|
||||||
conf.probe.types=Nextcloud
|
|
||||||
conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
|
|
||||||
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#Build Number for ANT. Do not edit!
|
#Build Number for ANT. Do not edit!
|
||||||
#Sun Jan 23 03:49:04 CET 2022
|
#Thu Dec 23 01:59:59 CET 2021
|
||||||
build.number=1
|
build.number=2
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
product.name=statoolinfos
|
product.name=statoolinfos
|
||||||
product.revision.major=0
|
product.revision.major=0
|
||||||
product.revision.minor=5
|
product.revision.minor=4
|
||||||
product.revision.snapshot=
|
product.revision.snapshot=
|
||||||
|
|
BIN
lib/commons-io-2.7-sources.jar
Normal file
BIN
lib/commons-io-2.7.jar
Normal file
|
@ -1,19 +1,19 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Optional environment settings:
|
# Optional environment settings:
|
||||||
# export LOG4J_CONFIGURATION_FILE="toto.properties"
|
# export LOG4J_CONFIGURATION_FILE="toto.properties"
|
||||||
# export LOG4J_LEVEL=ERROR
|
# export LOG4J_LEVEL=ERROR
|
||||||
# https://logging.apache.org/log4j/log4j-2.11.2/manual/configuration.html#System_Properties
|
# https://logging.apache.org/log4j/log4j-2.11.2/manual/configuration.html#System_Properties
|
||||||
|
|
||||||
# Java check.
|
# Java check.
|
||||||
javaCheck=`which java`
|
javaCheck=`which java`
|
||||||
if [[ "$javaCheck" =~ ^/.* ]]; then
|
if [[ "$javaCheck" =~ ^/.* ]]; then
|
||||||
#echo "Java requirement............... OK"
|
#echo "Java requirement............... OK"
|
||||||
|
|
||||||
# Optional system properties:
|
# Optional system properties:
|
||||||
# LOGFILE="-Dlog4j2.configurationFile=../../log4j2.properties"
|
# LOGFILE="-Dlog4j2.configurationFile=../../log4j2.properties"
|
||||||
# LOGLEVEL="-Dlog4j2.level=ERROR"
|
# LOGLEVEL="-Dlog4j2.level=ERROR"
|
||||||
# https://logging.apache.org/log4j/log4j-2.11.2/manual/configuration.html#System_Properties
|
# https://logging.apache.org/log4j/log4j-2.11.2/manual/configuration.html#System_Properties
|
||||||
|
|
||||||
java -Djava.awt.headless=true $LOGFILE $LOGLEVEL -jar "$(dirname "$0")"/statoolinfos.jar $@
|
java -Djava.awt.headless=true $LOGFILE $LOGLEVEL -jar "$(dirname "$0")"/statoolinfos.jar $@
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 2020 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.
|
||||||
*
|
*
|
||||||
|
@ -81,60 +81,6 @@ public class Federation extends PathPropertyList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the organizations active.
|
|
||||||
*
|
|
||||||
* @return the organizations active
|
|
||||||
*/
|
|
||||||
public Organizations getActiveOrganizations()
|
|
||||||
{
|
|
||||||
Organizations result;
|
|
||||||
|
|
||||||
result = this.organizations.filterActiveFor(getTechnicalName());
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the active services.
|
|
||||||
*
|
|
||||||
* @return the active services
|
|
||||||
*/
|
|
||||||
public long getActiveServiceCount()
|
|
||||||
{
|
|
||||||
long result;
|
|
||||||
|
|
||||||
result = 0;
|
|
||||||
for (Organization organization : getActiveOrganizations())
|
|
||||||
{
|
|
||||||
result += organization.getActiveServiceCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the active services.
|
|
||||||
*
|
|
||||||
* @return the active services
|
|
||||||
*/
|
|
||||||
public Services getActiveServices()
|
|
||||||
{
|
|
||||||
Services result;
|
|
||||||
|
|
||||||
result = new Services();
|
|
||||||
|
|
||||||
for (Organization organization : getActiveOrganizations())
|
|
||||||
{
|
|
||||||
result.addAll(organization.getActiveServices());
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the contact email.
|
* Gets the contact email.
|
||||||
*
|
*
|
||||||
|
@ -450,7 +396,7 @@ public class Federation extends PathPropertyList
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
for (Organization organization : getActiveOrganizations())
|
for (Organization organization : this.organizations)
|
||||||
{
|
{
|
||||||
result += organization.getServiceCount();
|
result += organization.getServiceCount();
|
||||||
}
|
}
|
||||||
|
@ -459,26 +405,6 @@ public class Federation extends PathPropertyList
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the all services.
|
|
||||||
*
|
|
||||||
* @return the all services
|
|
||||||
*/
|
|
||||||
public Services getServices()
|
|
||||||
{
|
|
||||||
Services result;
|
|
||||||
|
|
||||||
result = new Services();
|
|
||||||
|
|
||||||
for (Organization organization : getActiveOrganizations())
|
|
||||||
{
|
|
||||||
result.addAll(organization.getServices());
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the all services.
|
* Gets the all services.
|
||||||
*
|
*
|
||||||
|
@ -510,7 +436,7 @@ public class Federation extends PathPropertyList
|
||||||
|
|
||||||
result = new Softwares();
|
result = new Softwares();
|
||||||
|
|
||||||
for (Service service : getServices())
|
for (Service service : getServicesAll())
|
||||||
{
|
{
|
||||||
if (StringUtils.isNotBlank(service.getSoftwareName()))
|
if (StringUtils.isNotBlank(service.getSoftwareName()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 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.
|
||||||
*
|
*
|
||||||
|
@ -42,17 +42,6 @@ import fr.devinsy.statoolinfos.util.URLUtils;
|
||||||
public class Organization extends PathPropertyList
|
public class Organization extends PathPropertyList
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = -2709210934548224213L;
|
private static final long serialVersionUID = -2709210934548224213L;
|
||||||
|
|
||||||
/**
|
|
||||||
* The Enum Status.
|
|
||||||
*/
|
|
||||||
public enum Status
|
|
||||||
{
|
|
||||||
ACTIVE,
|
|
||||||
IDLE,
|
|
||||||
AWAY
|
|
||||||
}
|
|
||||||
|
|
||||||
private Federation federation;
|
private Federation federation;
|
||||||
private Services services;
|
private Services services;
|
||||||
private File inputFile;
|
private File inputFile;
|
||||||
|
@ -86,51 +75,6 @@ public class Organization extends PathPropertyList
|
||||||
this.crawlJournal = new CrawlJournal();
|
this.crawlJournal = new CrawlJournal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the active services.
|
|
||||||
*
|
|
||||||
* @return the active services
|
|
||||||
*/
|
|
||||||
public Services getActiveServices()
|
|
||||||
{
|
|
||||||
Services result;
|
|
||||||
|
|
||||||
result = new Services();
|
|
||||||
|
|
||||||
for (Service service : this.services)
|
|
||||||
{
|
|
||||||
if (service.isActive())
|
|
||||||
{
|
|
||||||
result.add(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the service active count.
|
|
||||||
*
|
|
||||||
* @return the service active count
|
|
||||||
*/
|
|
||||||
public int getActiveServiceCount()
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
result = 0;
|
|
||||||
for (Service service : this.services)
|
|
||||||
{
|
|
||||||
if (service.isActive())
|
|
||||||
{
|
|
||||||
result += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the age.
|
* Gets the age.
|
||||||
*
|
*
|
||||||
|
@ -495,44 +439,6 @@ public class Organization extends PathPropertyList
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the status member of.
|
|
||||||
*
|
|
||||||
* @param entityName
|
|
||||||
* the entity name
|
|
||||||
* @return the status member of
|
|
||||||
*/
|
|
||||||
public Status getMemberStatusOf(final String entityName)
|
|
||||||
{
|
|
||||||
Status result;
|
|
||||||
|
|
||||||
String value = get("organization.memberof." + entityName + ".status");
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(value))
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
else if (StringUtils.equalsIgnoreCase(value, "ACTIVE"))
|
|
||||||
{
|
|
||||||
result = Status.ACTIVE;
|
|
||||||
}
|
|
||||||
else if (StringUtils.equalsIgnoreCase(value, "IDLE"))
|
|
||||||
{
|
|
||||||
result = Status.IDLE;
|
|
||||||
}
|
|
||||||
else if (StringUtils.equalsIgnoreCase(value, "AWAY"))
|
|
||||||
{
|
|
||||||
result = Status.AWAY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the metric month values all.
|
* Gets the metric month values all.
|
||||||
*
|
*
|
||||||
|
@ -710,6 +616,21 @@ public class Organization extends PathPropertyList
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the service active count.
|
||||||
|
*
|
||||||
|
* @return the service active count
|
||||||
|
*/
|
||||||
|
public int getServiceActiveCount()
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = this.services.getBy(Service.Status.OK).size();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the service count.
|
* Gets the service count.
|
||||||
*
|
*
|
||||||
|
@ -745,42 +666,6 @@ public class Organization extends PathPropertyList
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the status.
|
|
||||||
*
|
|
||||||
* @return the status
|
|
||||||
*/
|
|
||||||
public Status getStatus()
|
|
||||||
{
|
|
||||||
Status result;
|
|
||||||
|
|
||||||
String value = get("organization.status.level", "organization.status");
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(value))
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
else if (StringUtils.equalsIgnoreCase(value, "ACTIVE"))
|
|
||||||
{
|
|
||||||
result = Status.ACTIVE;
|
|
||||||
}
|
|
||||||
else if (StringUtils.equalsIgnoreCase(value, "IDLE"))
|
|
||||||
{
|
|
||||||
result = Status.IDLE;
|
|
||||||
}
|
|
||||||
else if (StringUtils.equalsIgnoreCase(value, "AWAY"))
|
|
||||||
{
|
|
||||||
result = Status.AWAY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the technical guide website.
|
* Gets the technical guide website.
|
||||||
*
|
*
|
||||||
|
@ -975,83 +860,6 @@ public class Organization extends PathPropertyList
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if is active.
|
|
||||||
*
|
|
||||||
* @return true, if is active
|
|
||||||
*/
|
|
||||||
public boolean isActive()
|
|
||||||
{
|
|
||||||
boolean result;
|
|
||||||
|
|
||||||
if (getStatus() == Status.ACTIVE)
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if is away.
|
|
||||||
*
|
|
||||||
* @return true, if is away
|
|
||||||
*/
|
|
||||||
public boolean isAway()
|
|
||||||
{
|
|
||||||
boolean result;
|
|
||||||
|
|
||||||
Status status = getStatus();
|
|
||||||
|
|
||||||
if (status == Status.AWAY)
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if is away for.
|
|
||||||
*
|
|
||||||
* @param entityName
|
|
||||||
* the entity name
|
|
||||||
* @return true, if is away for
|
|
||||||
*/
|
|
||||||
public boolean isAwayFor(final String entityName)
|
|
||||||
{
|
|
||||||
boolean result;
|
|
||||||
|
|
||||||
Status memberStatus = getMemberStatusOf(entityName);
|
|
||||||
LocalDate endDate = getDate("organization.memberof." + entityName + ".enddate");
|
|
||||||
|
|
||||||
if (memberStatus == Status.AWAY)
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else if ((endDate == null) || (endDate.isAfter(LocalDate.now())))
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if is default.
|
* Checks if is default.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 2020 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.
|
||||||
*
|
*
|
||||||
|
@ -36,31 +36,6 @@ public class Organizations extends ArrayList<Organization>
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter member of.
|
|
||||||
*
|
|
||||||
* @param entityName
|
|
||||||
* the entity name
|
|
||||||
* @return the organizations
|
|
||||||
*/
|
|
||||||
public Organizations filterActiveFor(final String entityName)
|
|
||||||
{
|
|
||||||
Organizations result;
|
|
||||||
|
|
||||||
result = new Organizations();
|
|
||||||
|
|
||||||
for (Organization organization : this)
|
|
||||||
{
|
|
||||||
if ((!organization.isAway()) && (!organization.isAwayFor(entityName)))
|
|
||||||
{
|
|
||||||
result.add(organization);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter by social network.
|
* Filter by social network.
|
||||||
*
|
*
|
||||||
|
@ -110,18 +85,18 @@ public class Organizations extends ArrayList<Organization>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the active service count.
|
* Gets the service active count.
|
||||||
*
|
*
|
||||||
* @return the active service count
|
* @return the service active count
|
||||||
*/
|
*/
|
||||||
public int getActiveServiceCount()
|
public int getServiceActiveCount()
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
for (Organization organization : this)
|
for (Organization organization : this)
|
||||||
{
|
{
|
||||||
result += organization.getActiveServiceCount();
|
result += organization.getServiceCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 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.
|
||||||
*
|
*
|
||||||
|
@ -489,8 +489,7 @@ public class Service extends PathPropertyList
|
||||||
|
|
||||||
MonthValues values = getMetricMonthValues("metrics.service.users");
|
MonthValues values = getMetricMonthValues("metrics.service.users");
|
||||||
|
|
||||||
YearMonth previousMonth = YearMonth.now().minusMonths(1);
|
values = values.extract(YearMonth.now().minusMonths(1), YearMonth.now().minusMonths(1));
|
||||||
values = values.extract(previousMonth, previousMonth);
|
|
||||||
|
|
||||||
result = (long) values.sum();
|
result = (long) values.sum();
|
||||||
|
|
||||||
|
@ -507,7 +506,7 @@ public class Service extends PathPropertyList
|
||||||
{
|
{
|
||||||
long result;
|
long result;
|
||||||
|
|
||||||
MonthValues values = getMetricMonthValues("metrics.http.visits");
|
MonthValues values = getMetricMonthValues("metrics.http.visits.humans");
|
||||||
|
|
||||||
values = values.extract(YearMonth.now().minusMonths(1), YearMonth.now().minusMonths(1));
|
values = values.extract(YearMonth.now().minusMonths(1), YearMonth.now().minusMonths(1));
|
||||||
|
|
||||||
|
@ -860,59 +859,6 @@ public class Service extends PathPropertyList
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if is active.
|
|
||||||
*
|
|
||||||
* @return true, if is active
|
|
||||||
*/
|
|
||||||
public boolean isActive()
|
|
||||||
{
|
|
||||||
boolean result;
|
|
||||||
|
|
||||||
if (((getStatus() == Service.Status.OK) || (getStatus() == Status.WARNING) || (getStatus() == Status.ERROR)) && (!isAway()))
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if is away.
|
|
||||||
*
|
|
||||||
* @return true, if is away
|
|
||||||
*/
|
|
||||||
public boolean isAway()
|
|
||||||
{
|
|
||||||
boolean result;
|
|
||||||
|
|
||||||
if (getEndDate() == null)
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LocalDate endDate = getDate("service.enddate");
|
|
||||||
|
|
||||||
if ((endDate == null) || (endDate.isAfter(LocalDate.now())))
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if is registration client.
|
* Checks if is registration client.
|
||||||
*
|
*
|
||||||
|
|
|
@ -65,32 +65,6 @@ public class StatoolInfosUtils
|
||||||
public static final DateTimeFormatter PATTERN_SHORTDATE = DateTimeFormatter.ofPattern("dd/MM/yyyy", Locale.FRANCE);
|
public static final DateTimeFormatter PATTERN_SHORTDATE = DateTimeFormatter.ofPattern("dd/MM/yyyy", Locale.FRANCE);
|
||||||
public static final DateTimeFormatter PATTERN_LONGDATE = DateTimeFormatter.ofPattern("dd/MM/yyyy HH':'mm", Locale.FRANCE);
|
public static final DateTimeFormatter PATTERN_LONGDATE = DateTimeFormatter.ofPattern("dd/MM/yyyy HH':'mm", Locale.FRANCE);
|
||||||
|
|
||||||
/**
|
|
||||||
* Default if zero.
|
|
||||||
*
|
|
||||||
* @param value
|
|
||||||
* the value
|
|
||||||
* @param defaultValue
|
|
||||||
* the default value
|
|
||||||
* @return the string
|
|
||||||
*/
|
|
||||||
public static String defaultIfZero(final long value, final String defaultValue)
|
|
||||||
{
|
|
||||||
String result;
|
|
||||||
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
result = defaultValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = String.valueOf(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Epoch to local date time.
|
* Epoch to local date time.
|
||||||
*
|
*
|
||||||
|
|
|
@ -117,24 +117,21 @@ public class Crawler
|
||||||
logger.error("ERROR: crawl failed for [{}]: {}", url.toString(), exception.getMessage());
|
logger.error("ERROR: crawl failed for [{}]: {}", url.toString(), exception.getMessage());
|
||||||
this.journal.add(url, parentURL, CrawlStatus.CONNECTERROR);
|
this.journal.add(url, parentURL, CrawlStatus.CONNECTERROR);
|
||||||
downloadFile = null;
|
downloadFile = null;
|
||||||
}
|
exception.printStackTrace();
|
||||||
catch (java.net.SocketException exception)
|
|
||||||
{
|
|
||||||
logger.error("ERROR: crawl failed for [{}]: {}", url.toString(), exception.getMessage());
|
|
||||||
this.journal.add(url, parentURL, CrawlStatus.CONNECTERROR);
|
|
||||||
downloadFile = null;
|
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException exception)
|
catch (FileNotFoundException exception)
|
||||||
{
|
{
|
||||||
logger.error("ERROR: crawl failed for [{}]: {}", url.toString(), exception.getMessage());
|
logger.error("ERROR: crawl failed for [{}]: {}", url.toString(), exception.getMessage());
|
||||||
this.journal.add(url, parentURL, CrawlStatus.URLNOTFOUND);
|
this.journal.add(url, parentURL, CrawlStatus.URLNOTFOUND);
|
||||||
downloadFile = null;
|
downloadFile = null;
|
||||||
|
exception.printStackTrace();
|
||||||
}
|
}
|
||||||
catch (IOException exception)
|
catch (IOException exception)
|
||||||
{
|
{
|
||||||
logger.error("ERROR: crawl failed for [{}]: {}", url.toString(), exception.getMessage());
|
logger.error("ERROR: crawl failed for [{}]: {}", url.toString(), exception.getMessage());
|
||||||
this.journal.add(url, parentURL, CrawlStatus.DOWNLOADERROR);
|
this.journal.add(url, parentURL, CrawlStatus.DOWNLOADERROR);
|
||||||
downloadFile = null;
|
downloadFile = null;
|
||||||
|
exception.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadFile != null)
|
if (downloadFile != null)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 2020 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.
|
||||||
*
|
*
|
||||||
|
@ -60,7 +60,7 @@ public class CategoryPage
|
||||||
logger.info("Htmlize category pages.");
|
logger.info("Htmlize category pages.");
|
||||||
for (Category category : categories)
|
for (Category category : categories)
|
||||||
{
|
{
|
||||||
Services services = federation.getServices().getBy(category);
|
Services services = federation.getServicesAll().getBy(category);
|
||||||
String page = CategoryPage.htmlize(category, services);
|
String page = CategoryPage.htmlize(category, services);
|
||||||
FileUtils.write(new File(htmlizeDirectory, "category-" + category.getTechnicalName() + ".xhtml"), page, StandardCharsets.UTF_8);
|
FileUtils.write(new File(htmlizeDirectory, "category-" + category.getTechnicalName() + ".xhtml"), page, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 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.
|
||||||
*
|
*
|
||||||
|
@ -528,7 +528,7 @@ public class ChartHtmlizer
|
||||||
{
|
{
|
||||||
for (YearWeek timestamp = startTarget; !timestamp.isAfter(endTarget); timestamp = timestamp.plusWeeks(1))
|
for (YearWeek timestamp = startTarget; !timestamp.isAfter(endTarget); timestamp = timestamp.plusWeeks(1))
|
||||||
{
|
{
|
||||||
LocalDate date = timestamp.atDay(DayOfWeek.MONDAY).plusDays(6);
|
LocalDate date = timestamp.atDay(DayOfWeek.MONDAY).plusWeeks(1);
|
||||||
String timestampLabel = date.format(DateTimeFormatter.ofPattern("yyyy-MMM-dd", Locale.FRANCE));
|
String timestampLabel = date.format(DateTimeFormatter.ofPattern("yyyy-MMM-dd", Locale.FRANCE));
|
||||||
chart.getLabels().add(timestampLabel);
|
chart.getLabels().add(timestampLabel);
|
||||||
|
|
||||||
|
@ -1271,7 +1271,8 @@ public class ChartHtmlizer
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
|
|
||||||
result = htmlizeServiceCountYearChart(federation.getServices(), StatoolInfosUtils.parseDate(federation.getStartDate()).getYear());
|
result = htmlizeServiceCountYearChart(federation.getServicesAll(),
|
||||||
|
StatoolInfosUtils.parseDate(federation.getStartDate()).getYear());
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -69,8 +69,8 @@ public class FederationMetricSummaryPage
|
||||||
data.setContent("metricMenuView", FederationMetricMenuView.htmlize(federation, TypeMenu.SUMMARY, view, period));
|
data.setContent("metricMenuView", FederationMetricMenuView.htmlize(federation, TypeMenu.SUMMARY, view, period));
|
||||||
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.hits.humans", federation, view, period, "metrics.http.hits.humans", ChartColor.GREEN);
|
FederationMetricHtmlizer.htmlize(data, "http.hits.humans", federation, view, period, "metrics.http.hits.humans", ChartColor.GREEN);
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visitors", federation, view, period, "metrics.http.visitors", ChartColor.GREEN);
|
FederationMetricHtmlizer.htmlize(data, "http.visitors.humans", federation, view, period, "metrics.http.visitors.humans", ChartColor.GREEN);
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visits", federation, view, period, "metrics.http.visits", ChartColor.GREEN);
|
FederationMetricHtmlizer.htmlize(data, "http.visits.humans", federation, view, period, "metrics.http.visits.humans", ChartColor.GREEN);
|
||||||
|
|
||||||
//
|
//
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricSummaryView.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricSummaryView.xhtml", data).toString();
|
||||||
|
|
|
@ -98,29 +98,24 @@ public class FederationMetricWebPage
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.ip.ipv4", federation, view, period, "metrics.http.ip.ipv4", ChartColor.YELLOW);
|
FederationMetricHtmlizer.htmlize(data, "http.ip.ipv4", federation, view, period, "metrics.http.ip.ipv4", ChartColor.YELLOW);
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.ip.ipv6", federation, view, period, "metrics.http.ip.ipv6", ChartColor.GREEN);
|
FederationMetricHtmlizer.htmlize(data, "http.ip.ipv6", federation, view, period, "metrics.http.ip.ipv6", ChartColor.GREEN);
|
||||||
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.requesters", federation, view, period, "metrics.http.requesters", ChartColor.BLUE);
|
|
||||||
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.requesters-humansbots", federation, view, period, "http.requesters (humans + bots)", "metrics.http.requesters.humans", ChartColor.GREEN,
|
|
||||||
"metrics.http.requesters.bots", ChartColor.YELLOW);
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.requesters.humans", federation, view, period, "metrics.http.requesters.humans", ChartColor.GREEN);
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.requesters.bots", federation, view, period, "metrics.http.requesters.bots", ChartColor.YELLOW);
|
|
||||||
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.requesters-ipv4ipv6", federation, view, period, "http.requesters (ipv4 + ipv6)", "metrics.http.requesters.ipv4", ChartColor.YELLOW,
|
|
||||||
"metrics.http.requesters.ipv6", ChartColor.GREEN);
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.requesters.ipv4", federation, view, period, "metrics.http.requesters.ipv4", ChartColor.YELLOW);
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.requesters.ipv6", federation, view, period, "metrics.http.requesters.ipv6", ChartColor.GREEN);
|
|
||||||
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visitors", federation, view, period, "metrics.http.visitors", ChartColor.BLUE);
|
FederationMetricHtmlizer.htmlize(data, "http.visitors", federation, view, period, "metrics.http.visitors", ChartColor.BLUE);
|
||||||
|
|
||||||
|
FederationMetricHtmlizer.htmlize(data, "http.visitors-humansbots", federation, view, period, "http.visitors (humans + bots)", "metrics.http.visitors.humans", ChartColor.GREEN,
|
||||||
|
"metrics.http.visitors.bots", ChartColor.YELLOW);
|
||||||
|
FederationMetricHtmlizer.htmlize(data, "http.visitors.humans", federation, view, period, "metrics.http.visitors.humans", ChartColor.GREEN);
|
||||||
|
FederationMetricHtmlizer.htmlize(data, "http.visitors.bots", federation, view, period, "metrics.http.visitors.bots", ChartColor.YELLOW);
|
||||||
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visitors-ipv4ipv6", federation, view, period, "http.visitors (ipv4 + ipv6)", "metrics.http.visitors.ipv4", ChartColor.YELLOW,
|
FederationMetricHtmlizer.htmlize(data, "http.visitors-ipv4ipv6", federation, view, period, "http.visitors (ipv4 + ipv6)", "metrics.http.visitors.ipv4", ChartColor.YELLOW,
|
||||||
"metrics.http.visitors.ipv6", ChartColor.GREEN);
|
"metrics.http.visitors.ipv6", ChartColor.GREEN);
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visitors.ipv4", federation, view, period, "metrics.http.visitors.ipv4", ChartColor.YELLOW);
|
FederationMetricHtmlizer.htmlize(data, "http.visitors.ipv4", federation, view, period, "metrics.http.visitors.ipv4", ChartColor.YELLOW);
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visitors.ipv6", federation, view, period, "metrics.http.visitors.ipv6", ChartColor.GREEN);
|
FederationMetricHtmlizer.htmlize(data, "http.visitors.ipv6", federation, view, period, "metrics.http.visitors.ipv6", ChartColor.GREEN);
|
||||||
|
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visits", federation, view, period, "metrics.http.visits", ChartColor.BLUE);
|
FederationMetricHtmlizer.htmlize(data, "http.visits", federation, view, period, "metrics.http.visits", ChartColor.BLUE);
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visits-ipv4ipv6", federation, view, period, "http.visits (ipv4 + ipv6)", "metrics.http.visits.ipv4", ChartColor.YELLOW,
|
|
||||||
"metrics.http.visits.ipv6", ChartColor.GREEN);
|
FederationMetricHtmlizer.htmlize(data, "http.visits-humansbots", federation, view, period, "http.visits (humans + bots)", "metrics.http.visits.humans", ChartColor.GREEN,
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visits.ipv4", federation, view, period, "metrics.http.visits.ipv4", ChartColor.YELLOW);
|
"metrics.http.visits.bots", ChartColor.YELLOW);
|
||||||
FederationMetricHtmlizer.htmlize(data, "http.visits.ipv6", federation, view, period, "metrics.http.visits.ipv6", ChartColor.GREEN);
|
FederationMetricHtmlizer.htmlize(data, "http.visits.bots", federation, view, period, "metrics.http.visits.bots", ChartColor.YELLOW);
|
||||||
|
FederationMetricHtmlizer.htmlize(data, "http.visits.humans", federation, view, period, "metrics.http.visits.humans", ChartColor.GREEN);
|
||||||
|
|
||||||
//
|
//
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricWebView.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricWebView.xhtml", data).toString();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 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.
|
||||||
*
|
*
|
||||||
|
@ -78,7 +78,7 @@ public class FederationOrganizationsPage
|
||||||
TagDataManager data = new TagDataManager();
|
TagDataManager data = new TagDataManager();
|
||||||
|
|
||||||
data.setContent("federationHeaderView", FederationHeaderView.htmlize(federation));
|
data.setContent("federationHeaderView", FederationHeaderView.htmlize(federation));
|
||||||
data.setContent("organizationListView", OrganizationListView.htmlize(federation.getActiveOrganizations()));
|
data.setContent("organizationListView", OrganizationListView.htmlize(federation.getOrganizations()));
|
||||||
|
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/federationOrganizations.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/federationOrganizations.xhtml", data).toString();
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ public class FederationServicesPage
|
||||||
TagDataManager data = new TagDataManager();
|
TagDataManager data = new TagDataManager();
|
||||||
|
|
||||||
data.setContent("federationHeaderView", FederationHeaderView.htmlize(federation));
|
data.setContent("federationHeaderView", FederationHeaderView.htmlize(federation));
|
||||||
data.setContent("serviceListView", ServiceListView.htmlize(federation.getServices()));
|
data.setContent("serviceListView", ServiceListView.htmlize(federation.getServicesAll()));
|
||||||
|
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/federationServices.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/federationServices.xhtml", data).toString();
|
||||||
|
|
||||||
|
|
|
@ -64,19 +64,19 @@ public class FederationStatsPage
|
||||||
|
|
||||||
data.setContent("federationHeaderView", FederationHeaderView.htmlize(federation));
|
data.setContent("federationHeaderView", FederationHeaderView.htmlize(federation));
|
||||||
|
|
||||||
data.setContent("turnoutChart", ChartHtmlizer.htmlizeOrganizationTurnoutChart(federation.getActiveOrganizations()));
|
data.setContent("turnoutChart", ChartHtmlizer.htmlizeOrganizationTurnoutChart(federation.getOrganizations()));
|
||||||
data.setContent("organizationCountryChart", ChartHtmlizer.htmlizeOrganizationCountryChart(federation.getActiveOrganizations()));
|
data.setContent("organizationCountryChart", ChartHtmlizer.htmlizeOrganizationCountryChart(federation.getOrganizations()));
|
||||||
data.setContent("organizationCountChart", ChartHtmlizer.htmlizeOrganizationCountChart(federation));
|
data.setContent("organizationCountChart", ChartHtmlizer.htmlizeOrganizationCountChart(federation));
|
||||||
data.setContent("organizationInOutChart", ChartHtmlizer.htmlizeOrganizationInOutChart(federation));
|
data.setContent("organizationInOutChart", ChartHtmlizer.htmlizeOrganizationInOutChart(federation));
|
||||||
|
|
||||||
data.setContent("hostServerTypeChart", ChartHtmlizer.htmlizeHostServerTypeChart(federation.getServices()));
|
data.setContent("hostServerTypeChart", ChartHtmlizer.htmlizeHostServerTypeChart(federation.getServicesAll()));
|
||||||
data.setContent("hostProviderTypeChart", ChartHtmlizer.htmlizeHostProviderTypeChart(federation.getServices()));
|
data.setContent("hostProviderTypeChart", ChartHtmlizer.htmlizeHostProviderTypeChart(federation.getServicesAll()));
|
||||||
data.setContent("serviceInstallTypeChart", ChartHtmlizer.htmlizeServiceInstallTypeChart(federation.getServices()));
|
data.setContent("serviceInstallTypeChart", ChartHtmlizer.htmlizeServiceInstallTypeChart(federation.getServicesAll()));
|
||||||
data.setContent("serviceCountryChart", ChartHtmlizer.htmlizeServiceCountryChart(federation.getServices()));
|
data.setContent("serviceCountryChart", ChartHtmlizer.htmlizeServiceCountryChart(federation.getServicesAll()));
|
||||||
|
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
RegistrationStats stats = StatAgent.statRegistrationTypes(federation.getServices());
|
RegistrationStats stats = StatAgent.statRegistrationTypes(federation.getServicesAll());
|
||||||
|
|
||||||
data.setContent("registrationTypeChart", ChartHtmlizer.htmlizeRegistrationBarChart(stats));
|
data.setContent("registrationTypeChart", ChartHtmlizer.htmlizeRegistrationBarChart(stats));
|
||||||
data.setContent("registrationNoneTypeChart", ChartHtmlizer.htmlizeRegistrationNonePieChart(stats));
|
data.setContent("registrationNoneTypeChart", ChartHtmlizer.htmlizeRegistrationNonePieChart(stats));
|
||||||
|
@ -86,14 +86,14 @@ public class FederationStatsPage
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setContent("serviceCountYearChart", ChartHtmlizer.htmlizeServiceCountYearChart(federation));
|
data.setContent("serviceCountYearChart", ChartHtmlizer.htmlizeServiceCountYearChart(federation));
|
||||||
data.setContent("serviceDateStatusChart", ChartHtmlizer.htmlizeServiceDateStatusChart(federation.getServices()));
|
data.setContent("serviceDateStatusChart", ChartHtmlizer.htmlizeServiceDateStatusChart(federation.getServicesAll()));
|
||||||
|
|
||||||
data.setContent("softwareDistributionChart", ChartHtmlizer.htmlizeSoftwareDistributionChart());
|
data.setContent("softwareDistributionChart", ChartHtmlizer.htmlizeSoftwareDistributionChart());
|
||||||
data.setContent("softwareDistributionPieChart", ChartHtmlizer.htmlizeSoftwareDistributionPieChart(federation.getServicesAll()));
|
data.setContent("softwareDistributionPieChart", ChartHtmlizer.htmlizeSoftwareDistributionPieChart(federation.getServicesAll()));
|
||||||
data.setContent("categoryDistributionChart", ChartHtmlizer.htmlizeCategoryDistributionChart());
|
data.setContent("categoryDistributionChart", ChartHtmlizer.htmlizeCategoryDistributionChart());
|
||||||
data.setContent("categoryDistributionPieChart", ChartHtmlizer.htmlizeCatergoryDistributionPieChart(federation.getServicesAll()));
|
data.setContent("categoryDistributionPieChart", ChartHtmlizer.htmlizeCatergoryDistributionPieChart(federation.getServicesAll()));
|
||||||
|
|
||||||
data.setContent("hostNameChart", ChartHtmlizer.htmlizeHostNamePieChart(federation.getServices()));
|
data.setContent("hostNameChart", ChartHtmlizer.htmlizeHostNamePieChart(federation.getServicesAll()));
|
||||||
|
|
||||||
//
|
//
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/federationStats.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/federationStats.xhtml", data).toString();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021-2022 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 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.
|
||||||
*
|
*
|
||||||
|
@ -81,7 +81,7 @@ public class FederationUptimePage
|
||||||
TagDataManager data = new TagDataManager();
|
TagDataManager data = new TagDataManager();
|
||||||
|
|
||||||
data.setContent("headerView", FederationHeaderView.htmlize(federation));
|
data.setContent("headerView", FederationHeaderView.htmlize(federation));
|
||||||
data.setContent("uptimeView", UptimeView.htmlize(federation.getActiveServices(), journal));
|
data.setContent("uptimeView", UptimeView.htmlize(federation.getServicesAll(), journal));
|
||||||
|
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/uptimePage.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/uptimePage.xhtml", data).toString();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 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.
|
||||||
*
|
*
|
||||||
|
@ -19,7 +19,6 @@
|
||||||
package fr.devinsy.statoolinfos.htmlize;
|
package fr.devinsy.statoolinfos.htmlize;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -28,7 +27,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import fr.devinsy.statoolinfos.core.Organization;
|
import fr.devinsy.statoolinfos.core.Organization;
|
||||||
import fr.devinsy.statoolinfos.core.Organizations;
|
import fr.devinsy.statoolinfos.core.Organizations;
|
||||||
import fr.devinsy.statoolinfos.core.StatoolInfosException;
|
import fr.devinsy.statoolinfos.core.StatoolInfosException;
|
||||||
import fr.devinsy.statoolinfos.core.StatoolInfosUtils;
|
|
||||||
import fr.devinsy.xidyn.XidynException;
|
import fr.devinsy.xidyn.XidynException;
|
||||||
import fr.devinsy.xidyn.data.TagDataManager;
|
import fr.devinsy.xidyn.data.TagDataManager;
|
||||||
import fr.devinsy.xidyn.presenters.PresenterUtils;
|
import fr.devinsy.xidyn.presenters.PresenterUtils;
|
||||||
|
@ -61,12 +59,7 @@ public class OrganizationListView
|
||||||
TagDataManager data = new TagDataManager();
|
TagDataManager data = new TagDataManager();
|
||||||
|
|
||||||
data.setContent("organizationCount", organizations.size());
|
data.setContent("organizationCount", organizations.size());
|
||||||
data.setContent("serviceCount", organizations.getActiveServiceCount());
|
data.setContent("serviceCount", organizations.getServiceCount());
|
||||||
|
|
||||||
String monthLabel = LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("MMMM yyyy")).replace(" ", " ");
|
|
||||||
data.setContent("monthLabel", monthLabel);
|
|
||||||
data.setAttribute("userCountHeaderColumn", "title", monthLabel);
|
|
||||||
data.setAttribute("visitCountHeaderColumn", "title", monthLabel);
|
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (Organization organization : organizations.sortByReverseServiceCount())
|
for (Organization organization : organizations.sortByReverseServiceCount())
|
||||||
|
@ -81,9 +74,9 @@ public class OrganizationListView
|
||||||
data.setEscapedContent("organizationListLine", index, "organizationListLineUrlLink", organization.getWebsiteURL().toString());
|
data.setEscapedContent("organizationListLine", index, "organizationListLineUrlLink", organization.getWebsiteURL().toString());
|
||||||
data.setEscapedAttribute("organizationListLine", index, "organizationListLineUrlLink", "href", organization.getWebsiteURL().toString());
|
data.setEscapedAttribute("organizationListLine", index, "organizationListLineUrlLink", "href", organization.getWebsiteURL().toString());
|
||||||
}
|
}
|
||||||
data.setContent("organizationListLine", index, "organizationListLineServiceCount", StatoolInfosUtils.defaultIfZero(organization.getActiveServiceCount(), "😿"));
|
data.setContent("organizationListLine", index, "organizationListLineServiceCount", organization.getServiceActiveCount());
|
||||||
data.setContent("organizationListLine", index, "organizationListLineUserCount", StatoolInfosUtils.defaultIfZero(organization.getPreviousMonthUserCount(), "😢"));
|
data.setContent("organizationListLine", index, "organizationListLineUserCount", organization.getPreviousMonthUserCount());
|
||||||
data.setContent("organizationListLine", index, "organizationListLineVisitCount", StatoolInfosUtils.defaultIfZero(organization.getPreviousMonthVisitCount(), "😞"));
|
data.setContent("organizationListLine", index, "organizationListLineVisitCount", organization.getPreviousMonthVisitCount());
|
||||||
|
|
||||||
data.setContent("organizationListLine", index, "organizationListLineDate", organization.getCrawledDate().format(DateTimeFormatter.ofPattern("dd/MM/YYYY")));
|
data.setContent("organizationListLine", index, "organizationListLineDate", organization.getCrawledDate().format(DateTimeFormatter.ofPattern("dd/MM/YYYY")));
|
||||||
data.setAttribute("organizationListLine", index, "organizationListLineDate", "title", organization.getCrawledDate().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
data.setAttribute("organizationListLine", index, "organizationListLineDate", "title", organization.getCrawledDate().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||||
|
|
|
@ -70,8 +70,8 @@ public class OrganizationMetricSummaryPage
|
||||||
data.setContent("metricMenuView", OrganizationMetricMenuView.htmlize(organization, TypeMenu.SUMMARY, view, period));
|
data.setContent("metricMenuView", OrganizationMetricMenuView.htmlize(organization, TypeMenu.SUMMARY, view, period));
|
||||||
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.hits.humans", organization, view, period, "metrics.http.hits.humans", ChartColor.GREEN);
|
OrganizationMetricHtmlizer.htmlize(data, "http.hits.humans", organization, view, period, "metrics.http.hits.humans", ChartColor.GREEN);
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visitors", organization, view, period, "metrics.http.visitors", ChartColor.GREEN);
|
OrganizationMetricHtmlizer.htmlize(data, "http.visitors.humans", organization, view, period, "metrics.http.visitors.humans", ChartColor.GREEN);
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visits", organization, view, period, "metrics.http.visits", ChartColor.GREEN);
|
OrganizationMetricHtmlizer.htmlize(data, "http.visits.humans", organization, view, period, "metrics.http.visits.humans", ChartColor.GREEN);
|
||||||
|
|
||||||
//
|
//
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricSummaryView.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricSummaryView.xhtml", data).toString();
|
||||||
|
|
|
@ -107,29 +107,24 @@ public class OrganizationMetricWebPage
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.ip.ipv4", organization, view, period, "metrics.http.ip.ipv4", ChartColor.YELLOW);
|
OrganizationMetricHtmlizer.htmlize(data, "http.ip.ipv4", organization, view, period, "metrics.http.ip.ipv4", ChartColor.YELLOW);
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.ip.ipv6", organization, view, period, "metrics.http.ip.ipv6", ChartColor.GREEN);
|
OrganizationMetricHtmlizer.htmlize(data, "http.ip.ipv6", organization, view, period, "metrics.http.ip.ipv6", ChartColor.GREEN);
|
||||||
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.requesters", organization, view, period, "metrics.http.requesters", ChartColor.BLUE);
|
|
||||||
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.requesters-humansbots", organization, view, period, "http.requesters (humans + bots)", "metrics.http.requesters.humans", ChartColor.GREEN,
|
|
||||||
"metrics.http.requesters.bots", ChartColor.YELLOW);
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.requesters.humans", organization, view, period, "metrics.http.requesters.humans", ChartColor.GREEN);
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.requesters.bots", organization, view, period, "metrics.http.requesters.bots", ChartColor.YELLOW);
|
|
||||||
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.requesters-ipv4ipv6", organization, view, period, "http.requesters(ipv4 + ipv6)", "metrics.http.requesters.ipv4", ChartColor.YELLOW,
|
|
||||||
"metrics.http.requesters.ipv6", ChartColor.GREEN);
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.requesters.ipv4", organization, view, period, "metrics.http.requesters.ipv4", ChartColor.YELLOW);
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.requesters.ipv6", organization, view, period, "metrics.http.requesters.ipv6", ChartColor.GREEN);
|
|
||||||
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visitors", organization, view, period, "metrics.http.visitors", ChartColor.BLUE);
|
OrganizationMetricHtmlizer.htmlize(data, "http.visitors", organization, view, period, "metrics.http.visitors", ChartColor.BLUE);
|
||||||
|
|
||||||
|
OrganizationMetricHtmlizer.htmlize(data, "http.visitors-humansbots", organization, view, period, "http.visitors (humans + bots)", "metrics.http.visitors.humans", ChartColor.GREEN,
|
||||||
|
"metrics.http.visitors.bots", ChartColor.YELLOW);
|
||||||
|
OrganizationMetricHtmlizer.htmlize(data, "http.visitors.humans", organization, view, period, "metrics.http.visitors.humans", ChartColor.GREEN);
|
||||||
|
OrganizationMetricHtmlizer.htmlize(data, "http.visitors.bots", organization, view, period, "metrics.http.visitors.bots", ChartColor.YELLOW);
|
||||||
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visitors-ipv4ipv6", organization, view, period, "http.visitors (ipv4 + ipv6)", "metrics.http.visitors.ipv4", ChartColor.YELLOW,
|
OrganizationMetricHtmlizer.htmlize(data, "http.visitors-ipv4ipv6", organization, view, period, "http.visitors (ipv4 + ipv6)", "metrics.http.visitors.ipv4", ChartColor.YELLOW,
|
||||||
"metrics.http.visitors.ipv6", ChartColor.GREEN);
|
"metrics.http.visitors.ipv6", ChartColor.GREEN);
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visitors.ipv4", organization, view, period, "metrics.http.visitors.ipv4", ChartColor.YELLOW);
|
OrganizationMetricHtmlizer.htmlize(data, "http.visitors.ipv4", organization, view, period, "metrics.http.visitors.ipv4", ChartColor.YELLOW);
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visitors.ipv6", organization, view, period, "metrics.http.visitors.ipv6", ChartColor.GREEN);
|
OrganizationMetricHtmlizer.htmlize(data, "http.visitors.ipv6", organization, view, period, "metrics.http.visitors.ipv6", ChartColor.GREEN);
|
||||||
|
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visits", organization, view, period, "metrics.http.visits", ChartColor.BLUE);
|
OrganizationMetricHtmlizer.htmlize(data, "http.visits", organization, view, period, "metrics.http.visits", ChartColor.BLUE);
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visits-ipv4ipv6", organization, view, period, "http.visits (ipv4 + ipv6)", "metrics.http.visits.ipv4", ChartColor.YELLOW,
|
|
||||||
"metrics.http.visits.ipv6", ChartColor.GREEN);
|
OrganizationMetricHtmlizer.htmlize(data, "http.visits-humansbots", organization, view, period, "http.visits (humans + bots)", "metrics.http.visits.humans", ChartColor.GREEN,
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visits.ipv4", organization, view, period, "metrics.http.visits.ipv4", ChartColor.YELLOW);
|
"metrics.http.visits.bots", ChartColor.YELLOW);
|
||||||
OrganizationMetricHtmlizer.htmlize(data, "http.visits.ipv6", organization, view, period, "metrics.http.visits.ipv6", ChartColor.GREEN);
|
OrganizationMetricHtmlizer.htmlize(data, "http.visits.bots", organization, view, period, "metrics.http.visits.bots", ChartColor.YELLOW);
|
||||||
|
OrganizationMetricHtmlizer.htmlize(data, "http.visits.humans", organization, view, period, "metrics.http.visits.humans", ChartColor.GREEN);
|
||||||
|
|
||||||
//
|
//
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricWebView.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricWebView.xhtml", data).toString();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 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,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package fr.devinsy.statoolinfos.htmlize;
|
package fr.devinsy.statoolinfos.htmlize;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -28,7 +27,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import fr.devinsy.statoolinfos.core.Service;
|
import fr.devinsy.statoolinfos.core.Service;
|
||||||
import fr.devinsy.statoolinfos.core.Services;
|
import fr.devinsy.statoolinfos.core.Services;
|
||||||
import fr.devinsy.statoolinfos.core.StatoolInfosException;
|
import fr.devinsy.statoolinfos.core.StatoolInfosException;
|
||||||
import fr.devinsy.statoolinfos.core.StatoolInfosUtils;
|
|
||||||
import fr.devinsy.xidyn.XidynException;
|
import fr.devinsy.xidyn.XidynException;
|
||||||
import fr.devinsy.xidyn.data.DisplayMode;
|
import fr.devinsy.xidyn.data.DisplayMode;
|
||||||
import fr.devinsy.xidyn.data.TagDataManager;
|
import fr.devinsy.xidyn.data.TagDataManager;
|
||||||
|
@ -69,11 +67,6 @@ public class ServiceListView
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String monthLabel = LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("MMMM yyyy")).replace(" ", " ");
|
|
||||||
data.setContent("monthLabel", monthLabel);
|
|
||||||
data.setAttribute("userCountHeaderColumn", "title", monthLabel);
|
|
||||||
data.setAttribute("visitCountHeaderColumn", "title", monthLabel);
|
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (Service service : services.sortByName())
|
for (Service service : services.sortByName())
|
||||||
{
|
{
|
||||||
|
@ -95,8 +88,9 @@ public class ServiceListView
|
||||||
data.setEscapedContent("serviceListLine", index, "serviceListLineSoftwareLink", service.getSoftwareName());
|
data.setEscapedContent("serviceListLine", index, "serviceListLineSoftwareLink", service.getSoftwareName());
|
||||||
data.setAttribute("serviceListLine", index, "serviceListLineSoftwareLink", "href", "software-" + service.getSoftwareTechnicalName() + ".xhtml");
|
data.setAttribute("serviceListLine", index, "serviceListLineSoftwareLink", "href", "software-" + service.getSoftwareTechnicalName() + ".xhtml");
|
||||||
|
|
||||||
data.setContent("serviceListLine", index, "serviceListLineUserCount", StatoolInfosUtils.defaultIfZero(service.getPreviousMonthUserCount(), "😢"));
|
data.setContent("serviceListLine", index, "serviceListLineUserCount", service.getPreviousMonthUserCount());
|
||||||
data.setContent("serviceListLine", index, "serviceListLineVisitCount", StatoolInfosUtils.defaultIfZero(service.getPreviousMonthVisitCount(), "😞"));
|
|
||||||
|
data.setContent("serviceListLine", index, "serviceListLineVisitCount", service.getPreviousMonthVisitCount());
|
||||||
|
|
||||||
data.setEscapedContent("serviceListLine", index, "serviceListLineDate", service.getCrawledDate().format(DateTimeFormatter.ofPattern("dd/MM/YYYY")));
|
data.setEscapedContent("serviceListLine", index, "serviceListLineDate", service.getCrawledDate().format(DateTimeFormatter.ofPattern("dd/MM/YYYY")));
|
||||||
data.setEscapedAttribute("serviceListLine", index, "serviceListLineDate", "title", service.getCrawledDate().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
data.setEscapedAttribute("serviceListLine", index, "serviceListLineDate", "title", service.getCrawledDate().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||||
|
|
|
@ -70,8 +70,8 @@ public class ServiceMetricSummaryPage
|
||||||
data.setContent("metricMenuView", ServiceMetricMenuView.htmlize(service, TypeMenu.SUMMARY, view, period));
|
data.setContent("metricMenuView", ServiceMetricMenuView.htmlize(service, TypeMenu.SUMMARY, view, period));
|
||||||
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.hits.humans", service, view, period, "metrics.http.hits.humans", ChartColor.GREEN);
|
ServiceMetricHtmlizer.htmlize(data, "http.hits.humans", service, view, period, "metrics.http.hits.humans", ChartColor.GREEN);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visitors", service, view, period, "metrics.http.visitors", ChartColor.GREEN);
|
ServiceMetricHtmlizer.htmlize(data, "http.visitors.humans", service, view, period, "metrics.http.visitors.humans", ChartColor.GREEN);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visits", service, view, period, "metrics.http.visits", ChartColor.GREEN);
|
ServiceMetricHtmlizer.htmlize(data, "http.visits.humans", service, view, period, "metrics.http.visits.humans", ChartColor.GREEN);
|
||||||
|
|
||||||
//
|
//
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricSummaryView.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricSummaryView.xhtml", data).toString();
|
||||||
|
|
|
@ -106,29 +106,24 @@ public class ServiceMetricWebPage
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.ip.ipv4", service, view, period, "metrics.http.ip.ipv4", ChartColor.YELLOW);
|
ServiceMetricHtmlizer.htmlize(data, "http.ip.ipv4", service, view, period, "metrics.http.ip.ipv4", ChartColor.YELLOW);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.ip.ipv6", service, view, period, "metrics.http.ip.ipv6", ChartColor.GREEN);
|
ServiceMetricHtmlizer.htmlize(data, "http.ip.ipv6", service, view, period, "metrics.http.ip.ipv6", ChartColor.GREEN);
|
||||||
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.requesters", service, view, period, "metrics.http.requesters", ChartColor.BLUE);
|
ServiceMetricHtmlizer.htmlize(data, "http.visitors", service, view, period, "metrics.http.ip", ChartColor.BLUE);
|
||||||
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.requesters-humansbots", service, view, period, "http.requesters (humans + bots)", "metrics.http.requesters.humans", ChartColor.GREEN,
|
ServiceMetricHtmlizer.htmlize(data, "http.visitors-humansbots", service, view, period, "http.visitors (humans + bots)", "metrics.http.visitors.humans", ChartColor.GREEN,
|
||||||
"metrics.http.requesters.bots", ChartColor.YELLOW);
|
"metrics.http.visitors.bots", ChartColor.YELLOW);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.requesters.humans", service, view, period, "metrics.http.requesters.humans", ChartColor.GREEN);
|
ServiceMetricHtmlizer.htmlize(data, "http.visitors.humans", service, view, period, "metrics.http.visitors.humans", ChartColor.GREEN);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.requesters.bots", service, view, period, "metrics.http.requesters.bots", ChartColor.YELLOW);
|
ServiceMetricHtmlizer.htmlize(data, "http.visitors.bots", service, view, period, "metrics.http.visitors.bots", ChartColor.YELLOW);
|
||||||
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.requesters-ipv4ipv6", service, view, period, "http.requesters (ipv4 + ipv6)", "metrics.http.requesters.ipv4", ChartColor.YELLOW,
|
|
||||||
"metrics.http.requesters.ipv6", ChartColor.GREEN);
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.requesters.ipv4", service, view, period, "metrics.http.requesters.ipv4", ChartColor.YELLOW);
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.requesters.ipv6", service, view, period, "metrics.http.requesters.ipv6", ChartColor.GREEN);
|
|
||||||
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visitors", service, view, period, "metrics.http.visitors", ChartColor.BLUE);
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visitors-ipv4ipv6", service, view, period, "http.visitors (ipv4 + ipv6)", "metrics.http.visitors.ipv4", ChartColor.YELLOW,
|
ServiceMetricHtmlizer.htmlize(data, "http.visitors-ipv4ipv6", service, view, period, "http.visitors (ipv4 + ipv6)", "metrics.http.visitors.ipv4", ChartColor.YELLOW,
|
||||||
"metrics.http.visitors.ipv6", ChartColor.GREEN);
|
"metrics.http.visitors.ipv6", ChartColor.GREEN);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visitors.ipv4", service, view, period, "metrics.http.visitors.ipv4", ChartColor.YELLOW);
|
ServiceMetricHtmlizer.htmlize(data, "http.visitors.ipv4", service, view, period, "metrics.http.visitors.ipv4", ChartColor.YELLOW);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visitors.ipv6", service, view, period, "metrics.http.visitors.ipv6", ChartColor.GREEN);
|
ServiceMetricHtmlizer.htmlize(data, "http.visitors.ipv6", service, view, period, "metrics.http.visitors.ipv6", ChartColor.GREEN);
|
||||||
|
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visits", service, view, period, "metrics.http.visits", ChartColor.BLUE);
|
ServiceMetricHtmlizer.htmlize(data, "http.visits", service, view, period, "metrics.http.visits", ChartColor.BLUE);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visits-ipv4ipv6", service, view, period, "http.visits (ipv4 + ipv6)", "metrics.http.visits.ipv4", ChartColor.YELLOW,
|
|
||||||
"metrics.http.visits.ipv6", ChartColor.GREEN);
|
ServiceMetricHtmlizer.htmlize(data, "http.visits-humansbots", service, view, period, "http.visits (humans + bots)", "metrics.http.visits.humans", ChartColor.GREEN,
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visits.ipv4", service, view, period, "metrics.http.visits.ipv4", ChartColor.YELLOW);
|
"metrics.http.visits.bots", ChartColor.YELLOW);
|
||||||
ServiceMetricHtmlizer.htmlize(data, "http.visits.ipv6", service, view, period, "metrics.http.visits.ipv6", ChartColor.GREEN);
|
ServiceMetricHtmlizer.htmlize(data, "http.visits.bots", service, view, period, "metrics.http.visits.bots", ChartColor.YELLOW);
|
||||||
|
ServiceMetricHtmlizer.htmlize(data, "http.visits.humans", service, view, period, "metrics.http.visits.humans", ChartColor.GREEN);
|
||||||
|
|
||||||
//
|
//
|
||||||
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricWebView.xhtml", data).toString();
|
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/serviceMetricWebView.xhtml", data).toString();
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class ServicesPage
|
||||||
File htmlizeDirectory = HtmlizerContext.instance().getHtmlizeDirectory();
|
File htmlizeDirectory = HtmlizerContext.instance().getHtmlizeDirectory();
|
||||||
|
|
||||||
logger.info("Htmlize services page.");
|
logger.info("Htmlize services page.");
|
||||||
String page = ServicesPage.htmlize(federation.getServices());
|
String page = ServicesPage.htmlize(federation.getServicesAll());
|
||||||
FileUtils.write(new File(htmlizeDirectory, "services.xhtml"), page, StandardCharsets.UTF_8);
|
FileUtils.write(new File(htmlizeDirectory, "services.xhtml"), page, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class SoftwarePage
|
||||||
Softwares catalog = federation.getSoftwares();
|
Softwares catalog = federation.getSoftwares();
|
||||||
for (Software software : catalog.values())
|
for (Software software : catalog.values())
|
||||||
{
|
{
|
||||||
Services services = federation.getServices().getBy(software);
|
Services services = federation.getServicesAll().getBy(software);
|
||||||
String page = SoftwarePage.htmlize(software, services);
|
String page = SoftwarePage.htmlize(software, services);
|
||||||
FileUtils.write(new File(htmlizeDirectory, "software-" + software.getTechnicalName() + ".xhtml"), page, StandardCharsets.UTF_8);
|
FileUtils.write(new File(htmlizeDirectory, "software-" + software.getTechnicalName() + ".xhtml"), page, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021-2022 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 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.
|
||||||
*
|
*
|
||||||
|
@ -156,7 +156,7 @@ public class UptimeView
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (Service service : services.sortByName())
|
for (Service service : services.getBy(Service.Status.OK).sortByName())
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
data.setAttribute("line", index, "lineLogo", "src", service.getLogoFileName());
|
data.setAttribute("line", index, "lineLogo", "src", service.getLogoFileName());
|
||||||
|
|
|
@ -21,7 +21,19 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://forge.devinsy.fr/devinsy/statoolinfos">https://forge.devinsy.fr/devinsy/statoolinfos</a></li>
|
<li><a href="https://forge.devinsy.fr/devinsy/statoolinfos">https://forge.devinsy.fr/devinsy/statoolinfos</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Contributors: Angie, MrFlos, Quentin Duchemin, Fabrice61, Thomas @TConstans, @labecasse, Antoine Jaba, @setop, Jérémy Collot,
|
<p>Contributors:</p>
|
||||||
Pilou, Kepon, Laurent Sleto…</p>
|
<ul>
|
||||||
|
<li>Angie</li>
|
||||||
|
<li>MrFlos</li>
|
||||||
|
<li>Quentin Duchemin</li>
|
||||||
|
<li>Fabrice61</li>
|
||||||
|
<li>Thomas @TConstans</li>
|
||||||
|
<li>@labecasse</li>
|
||||||
|
<li>Antoine Jaba</li>
|
||||||
|
<li>@setop</li>
|
||||||
|
<li>Jérémy Collot</li>
|
||||||
|
<li>Pilou</li>
|
||||||
|
<li>Kepon</li>
|
||||||
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
<th style="width: 200px;">Membre</th>
|
<th style="width: 200px;">Membre</th>
|
||||||
<th style="width: 250px;">URL</th>
|
<th style="width: 250px;">URL</th>
|
||||||
<th style="width: 10px;">Services</th>
|
<th style="width: 10px;">Services</th>
|
||||||
<th id="userCountHeaderColumn" style="width: 10px;">Utilisateurs mensuels<sup>*</sup></th>
|
<th style="width: 10px;">Utilisateurs mensuels</th>
|
||||||
<th id="visitCountHeaderColumn" style="width: 10px;">Visites mensuelles<sup>*</sup></th>
|
<th style="width: 10px;">Visites mensuelles</th>
|
||||||
<th style="width: 10px;">Date</th>
|
<th style="width: 10px;">Date</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -42,53 +42,19 @@
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div id="month_asterisk">(*) chiffres de <span id="monthLabel">n/a</span></div>
|
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function()
|
$(document).ready(function()
|
||||||
{
|
{
|
||||||
$.fn.dataTable.moment('DD/MM/YYYY');
|
$.fn.dataTable.moment( 'DD/MM/YYYY' );
|
||||||
|
|
||||||
$.extend($.fn.dataTable.ext.type.order,
|
|
||||||
{
|
|
||||||
"custom-sort-asc": function(x, y)
|
|
||||||
{
|
|
||||||
if (!(!isNaN(x) || !isNaN(y)))
|
|
||||||
return 0;
|
|
||||||
else if (isNaN(x))
|
|
||||||
return -1;
|
|
||||||
else if (isNaN(y))
|
|
||||||
return +1;
|
|
||||||
else
|
|
||||||
return x-y;
|
|
||||||
},
|
|
||||||
"custom-sort-desc": function(x, y)
|
|
||||||
{
|
|
||||||
if (!(!isNaN(x) || !isNaN(y)))
|
|
||||||
return 0;
|
|
||||||
else if (isNaN(x))
|
|
||||||
return +1;
|
|
||||||
else if (isNaN(y))
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return y-x;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
|
|
||||||
$('#organizations').DataTable(
|
$('#organizations').DataTable(
|
||||||
{
|
{
|
||||||
paging: false,
|
paging: false,
|
||||||
ordering: true,
|
ordering: true,
|
||||||
"order": [[ 2, "desc" ]],
|
"order": [[ 2, "desc" ]],
|
||||||
language: dataTableFrench,
|
language: dataTableFrench
|
||||||
"columnDefs":
|
});
|
||||||
[
|
|
||||||
{ targets: 2, "type": 'custom-sort' },
|
|
||||||
{ targets: 3, "type": 'custom-sort' },
|
|
||||||
{ targets: 4, "type": 'custom-sort' }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
} );
|
} );
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
<th class="" style="width: 225px;">Organisation</th>
|
<th class="" style="width: 225px;">Organisation</th>
|
||||||
<th class="">URL</th>
|
<th class="">URL</th>
|
||||||
<th class="">Logiciel</th>
|
<th class="">Logiciel</th>
|
||||||
<th id="userCountHeaderColumn" class="" style="width: 100px;">Utilisateurs mensuels<sup>*</sup></th>
|
<th class="" style="width: 100px;">Utilisateurs mensuels</th>
|
||||||
<th id="visitCountHeaderColumn" class="" style="width: 10px;">Visites mensuelles<sup>*</sup></th>
|
<th class="" style="width: 10px;">Visites mensuelles</th>
|
||||||
<th class="" style="width: 25px;">Statut</th>
|
<th class="" style="width: 25px;">Statut</th>
|
||||||
<th class="" style="width: 25px;" colspan="5">Inscription</th>
|
<th class="" style="width: 25px;" colspan="5">Inscription</th>
|
||||||
<th class="" style="width: 25px;" colspan="5">Liens</th>
|
<th class="" style="width: 25px;" colspan="5">Liens</th>
|
||||||
|
@ -131,51 +131,19 @@
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div id="month_asterisk">(*) chiffres de <span id="monthLabel">n/a</span></div>
|
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function()
|
$(document).ready(function()
|
||||||
{
|
{
|
||||||
$.fn.dataTable.moment('DD/MM/YYYY');
|
$.fn.dataTable.moment( 'DD/MM/YYYY' );
|
||||||
|
|
||||||
$.extend($.fn.dataTable.ext.type.order,
|
|
||||||
{
|
|
||||||
"custom-sort-asc": function(x, y)
|
|
||||||
{
|
|
||||||
if (!(!isNaN(x) || !isNaN(y)))
|
|
||||||
return 0;
|
|
||||||
else if (isNaN(x))
|
|
||||||
return -1;
|
|
||||||
else if (isNaN(y))
|
|
||||||
return +1;
|
|
||||||
else
|
|
||||||
return x-y;
|
|
||||||
},
|
|
||||||
"custom-sort-desc": function(x, y)
|
|
||||||
{
|
|
||||||
if (!(!isNaN(x) || !isNaN(y)))
|
|
||||||
return 0;
|
|
||||||
else if (isNaN(x))
|
|
||||||
return +1;
|
|
||||||
else if (isNaN(y))
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return y-x;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
$('#serviceListTable').DataTable(
|
$('#serviceListTable').DataTable(
|
||||||
{
|
{
|
||||||
paging: false,
|
paging: false,
|
||||||
ordering: true,
|
ordering: true,
|
||||||
"order": [[ 2, "desc" ]],
|
"order": [[ 2, "desc" ]],
|
||||||
language: dataTableFrench,
|
language: dataTableFrench
|
||||||
"columnDefs":
|
});
|
||||||
[
|
|
||||||
{ targets: 4, "type": 'custom-sort' },
|
|
||||||
{ targets: 5, "type": 'custom-sort' }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
<div id="metricMenuView" />
|
<div id="metricMenuView" />
|
||||||
<div id="charts" style="display: block;">
|
<div id="charts" style="display: block;">
|
||||||
<div id="http.hits.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.hits.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
<div id="http.visitors" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.visitors.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
<div id="http.visits" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.visits.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -50,31 +50,23 @@
|
||||||
<div id="http.ip.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.ip.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
<div id="http.ip.bots" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.ip.bots" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
|
|
||||||
<h2>http.requesters</h2>
|
<h2>http.visitors</h2>
|
||||||
<div id="http.requesters" style="width: 450px; height: 300px; border: 1px solid #e7e7e7;"/>
|
|
||||||
|
|
||||||
<div id="http.requesters-ipv4ipv6" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
|
||||||
<div id="http.requesters.ipv4" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
|
||||||
<div id="http.requesters.ipv6" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
|
||||||
<br/>
|
|
||||||
<div id="http.requesters-humansbots" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
|
||||||
<div id="http.requesters.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
|
||||||
<div id="http.requesters.bots" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
|
||||||
|
|
||||||
<h2>Visiteurs</h2>
|
|
||||||
<div id="http.visitors" style="width: 450px; height: 300px; border: 1px solid #e7e7e7;"/>
|
<div id="http.visitors" style="width: 450px; height: 300px; border: 1px solid #e7e7e7;"/>
|
||||||
|
|
||||||
<div id="http.visitors-ipv4ipv6" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.visitors-ipv4ipv6" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
<div id="http.visitors.ipv4" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.visitors.ipv4" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
<div id="http.visitors.ipv6" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.visitors.ipv6" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
|
<br/>
|
||||||
|
<div id="http.visitors-humansbots" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
|
<div id="http.visitors.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
|
<div id="http.visitors.bots" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
|
|
||||||
<h2>Visites</h2>
|
<h2>http.visits</h2>
|
||||||
<div id="http.visits" style="width: 450px; height: 300px; border: 1px solid #e7e7e7;"/>
|
<div id="http.visits" style="width: 450px; height: 300px; border: 1px solid #e7e7e7;"/>
|
||||||
|
|
||||||
<div id="http.visits-ipv4ipv6" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.visits-humansbots" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
<div id="http.visits.ipv4" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.visits.humans" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
<div id="http.visits.ipv6" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
<div id="http.visits.bots" style="width: 450px; height: 300px; display: inline-block; border: 1px solid #e7e7e7;"/>
|
||||||
<br/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 160 B |
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 158 B After Width: | Height: | Size: 158 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
|
@ -21,7 +21,6 @@ package fr.devinsy.statoolinfos.metrics.http;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -36,8 +35,6 @@ public class HttpAccessLog
|
||||||
{
|
{
|
||||||
private static Logger logger = LoggerFactory.getLogger(HttpAccessLog.class);
|
private static Logger logger = LoggerFactory.getLogger(HttpAccessLog.class);
|
||||||
|
|
||||||
public static final Pattern ASSET_PATTERN = Pattern.compile("^.*\\.(avi|css|gif|ico|jpeg|jpg|js|mp3|mp4|ogg|png|svg|wav) HTTP.*$");
|
|
||||||
|
|
||||||
private String ip;
|
private String ip;
|
||||||
private String remoteUser;
|
private String remoteUser;
|
||||||
private LocalDateTime time;
|
private LocalDateTime time;
|
||||||
|
@ -82,36 +79,6 @@ public class HttpAccessLog
|
||||||
return this.ip;
|
return this.ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the method.
|
|
||||||
*
|
|
||||||
* @return the method
|
|
||||||
*/
|
|
||||||
public HttpMethod getMethod()
|
|
||||||
{
|
|
||||||
HttpMethod result;
|
|
||||||
|
|
||||||
if (this.request == null)
|
|
||||||
{
|
|
||||||
result = HttpMethod.UNKNOWN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int space = this.request.indexOf(' ');
|
|
||||||
if (space == -1)
|
|
||||||
{
|
|
||||||
result = HttpMethod.UNKNOWN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = HttpMethod.of(this.request.substring(0, space));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getReferer()
|
public String getReferer()
|
||||||
{
|
{
|
||||||
return this.referer;
|
return this.referer;
|
||||||
|
@ -264,29 +231,6 @@ public class HttpAccessLog
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if is visit.
|
|
||||||
*
|
|
||||||
* @return true, if is visit
|
|
||||||
*/
|
|
||||||
public boolean isVisit()
|
|
||||||
{
|
|
||||||
boolean result;
|
|
||||||
|
|
||||||
if ((this.status.getCategory() == HttpStatusCategory.SUCCESS) && (!isBot()) && (this.request.startsWith("GET ")) &&
|
|
||||||
(!ASSET_PATTERN.matcher(this.request).matches()))
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBodyBytesSent(final long bodyBytesSent)
|
public void setBodyBytesSent(final long bodyBytesSent)
|
||||||
{
|
{
|
||||||
this.bodyBytesSent = bodyBytesSent;
|
this.bodyBytesSent = bodyBytesSent;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 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.
|
||||||
*
|
*
|
||||||
|
@ -47,26 +47,23 @@ public class HttpAccessLogAnalyzer
|
||||||
// '"$request" $status $body_bytes_sent '
|
// '"$request" $status $body_bytes_sent '
|
||||||
// '"$http_referer" "$http_user_agent"';
|
// '"$http_referer" "$http_user_agent"';
|
||||||
public static final Pattern COMBINED_PATTERN = Pattern.compile(
|
public static final Pattern COMBINED_PATTERN = Pattern.compile(
|
||||||
"^(?<remoteAddress>[a-zA-F0-9\\\\:\\\\.]+) - (?<remoteUser>[^\\[]+) \\[(?<time>[^\\]]+)\\] \"(?<request>.*)\" (?<status>\\d+) (?<bodyBytesSent>\\d+) \"(?<referer>.*)\" \"(?<userAgent>[^\"]*)\".*$");
|
"^(?<remoteAddress>[a-zA-F0-9\\\\:\\\\.]+) - (?<remoteUser>[^\\[]+) \\[(?<time>[^\\]]+)\\] \"(?<request>[^\"]*)\" (?<status>\\d+) (?<bodyBytesSent>\\d+) \"(?<referer>[^\"]*)\" \"(?<userAgent>[^\"]*)\".*$");
|
||||||
|
|
||||||
private int errorCount;
|
private int errorCount;
|
||||||
private PathCounters counters;
|
private PathCounters counters;
|
||||||
|
private VisitCounters visits;
|
||||||
|
private VisitCounters botVisits;
|
||||||
|
private VisitCounters humanVisits;
|
||||||
private IpCounters ips;
|
private IpCounters ips;
|
||||||
private IpCounters ipv4;
|
private IpCounters ipv4;
|
||||||
private IpCounters ipv6;
|
private IpCounters ipv6;
|
||||||
private IpCounters botIps;
|
private IpCounters botIps;
|
||||||
private IpCounters humanIps;
|
private IpCounters humanIps;
|
||||||
private VisitorCounters requesters;
|
|
||||||
private VisitorCounters ipv4Requesters;
|
|
||||||
private VisitorCounters ipv6Requesters;
|
|
||||||
private VisitorCounters botRequesters;
|
|
||||||
private VisitorCounters humanRequesters;
|
|
||||||
private VisitCounters visits;
|
|
||||||
private VisitCounters ipv4Visits;
|
|
||||||
private VisitCounters ipv6Visits;
|
|
||||||
private VisitorCounters visitors;
|
private VisitorCounters visitors;
|
||||||
private VisitorCounters ipv4Visitors;
|
private VisitorCounters ipv4Visitors;
|
||||||
private VisitorCounters ipv6Visitors;
|
private VisitorCounters ipv6Visitors;
|
||||||
|
private VisitorCounters botVisitors;
|
||||||
|
private VisitorCounters humanVisitors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new http access log prober.
|
* Instantiates a new http access log prober.
|
||||||
|
@ -74,25 +71,20 @@ public class HttpAccessLogAnalyzer
|
||||||
public HttpAccessLogAnalyzer()
|
public HttpAccessLogAnalyzer()
|
||||||
{
|
{
|
||||||
this.counters = new PathCounters();
|
this.counters = new PathCounters();
|
||||||
|
this.visits = new VisitCounters();
|
||||||
|
this.botVisits = new VisitCounters();
|
||||||
|
this.humanVisits = new VisitCounters();
|
||||||
this.ips = new IpCounters();
|
this.ips = new IpCounters();
|
||||||
this.ipv4 = new IpCounters();
|
this.ipv4 = new IpCounters();
|
||||||
this.ipv6 = new IpCounters();
|
this.ipv6 = new IpCounters();
|
||||||
this.botIps = new IpCounters();
|
this.botIps = new IpCounters();
|
||||||
this.humanIps = new IpCounters();
|
this.humanIps = new IpCounters();
|
||||||
|
|
||||||
this.requesters = new VisitorCounters();
|
|
||||||
this.ipv4Requesters = new VisitorCounters();
|
|
||||||
this.ipv6Requesters = new VisitorCounters();
|
|
||||||
this.humanRequesters = new VisitorCounters();
|
|
||||||
this.botRequesters = new VisitorCounters();
|
|
||||||
|
|
||||||
this.visits = new VisitCounters();
|
|
||||||
this.ipv4Visits = new VisitCounters();
|
|
||||||
this.ipv6Visits = new VisitCounters();
|
|
||||||
|
|
||||||
this.visitors = new VisitorCounters();
|
this.visitors = new VisitorCounters();
|
||||||
this.ipv4Visitors = new VisitorCounters();
|
this.ipv4Visitors = new VisitorCounters();
|
||||||
this.ipv6Visitors = new VisitorCounters();
|
this.ipv6Visitors = new VisitorCounters();
|
||||||
|
this.botVisitors = new VisitorCounters();
|
||||||
|
this.humanVisitors = new VisitorCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,19 +105,15 @@ public class HttpAccessLogAnalyzer
|
||||||
result.putAll(this.botIps.getCounters("metrics.http.ip.bots"));
|
result.putAll(this.botIps.getCounters("metrics.http.ip.bots"));
|
||||||
result.putAll(this.humanIps.getCounters("metrics.http.ip.humans"));
|
result.putAll(this.humanIps.getCounters("metrics.http.ip.humans"));
|
||||||
|
|
||||||
result.putAll(this.requesters.getCounters("metrics.http.requesters"));
|
|
||||||
result.putAll(this.ipv4Requesters.getCounters("metrics.http.requesters.ipv4"));
|
|
||||||
result.putAll(this.ipv6Requesters.getCounters("metrics.http.requesters.ipv6"));
|
|
||||||
result.putAll(this.botRequesters.getCounters("metrics.http.requesters.bots"));
|
|
||||||
result.putAll(this.humanRequesters.getCounters("metrics.http.requesters.humans"));
|
|
||||||
|
|
||||||
result.putAll(this.visits.getCounters("metrics.http.visits"));
|
result.putAll(this.visits.getCounters("metrics.http.visits"));
|
||||||
result.putAll(this.ipv4Visits.getCounters("metrics.http.visits.ipv4"));
|
result.putAll(this.botVisits.getCounters("metrics.http.visits.bots"));
|
||||||
result.putAll(this.ipv6Visits.getCounters("metrics.http.visits.ipv6"));
|
result.putAll(this.humanVisits.getCounters("metrics.http.visits.humans"));
|
||||||
|
|
||||||
result.putAll(this.visitors.getCounters("metrics.http.visitors"));
|
result.putAll(this.visitors.getCounters("metrics.http.visitors"));
|
||||||
result.putAll(this.ipv4Visitors.getCounters("metrics.http.visitors.ipv4"));
|
result.putAll(this.ipv4Visitors.getCounters("metrics.http.visitors.ipv4"));
|
||||||
result.putAll(this.ipv6Visitors.getCounters("metrics.http.visitors.ipv6"));
|
result.putAll(this.ipv6Visitors.getCounters("metrics.http.visitors.ipv6"));
|
||||||
|
result.putAll(this.botVisitors.getCounters("metrics.http.visitors.bots"));
|
||||||
|
result.putAll(this.humanVisitors.getCounters("metrics.http.visitors.humans"));
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
@ -249,7 +237,7 @@ public class HttpAccessLogAnalyzer
|
||||||
}
|
}
|
||||||
|
|
||||||
// metrics.http.pages.* =
|
// metrics.http.pages.* =
|
||||||
if ((log.getStatus().getCategory() == HttpStatusCategory.SUCCESS) && (isPage(log.getRequest())))
|
if ((isPage(log.getRequest())) && (log.getStatus().getCategory() == HttpStatusCategory.SUCCESS))
|
||||||
{
|
{
|
||||||
this.counters.inc("metrics.http.pages", year, yearMonth, yearWeek, date);
|
this.counters.inc("metrics.http.pages", year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
|
@ -279,74 +267,47 @@ public class HttpAccessLogAnalyzer
|
||||||
this.humanIps.put(log.getIp(), year, yearMonth, yearWeek, date);
|
this.humanIps.put(log.getIp(), year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
// metrics.http.requesters.* =
|
// metrics.http.visits.* =
|
||||||
this.requesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
this.visits.putVisit(log);
|
||||||
|
this.visits.storeTimeMarks(year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
// metrics.http.requesters.ipv4.* =
|
|
||||||
// metrics.http.requesters.ipv6.* =
|
|
||||||
if (log.isIPv4())
|
|
||||||
{
|
|
||||||
this.ipv4Requesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.ipv6Requesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
|
||||||
}
|
|
||||||
|
|
||||||
// metrics.http.requesters.bots.*
|
|
||||||
// metrics.http.requesters.humans.*
|
|
||||||
if (log.isBot())
|
if (log.isBot())
|
||||||
{
|
{
|
||||||
this.botRequesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
this.botVisits.putVisit(log);
|
||||||
|
this.botVisits.storeTimeMarks(year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.humanRequesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
this.humanVisits.putVisit(log);
|
||||||
|
this.humanVisits.storeTimeMarks(year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
// metrics.http.visits.* =
|
//
|
||||||
// metrics.http.visits.ipv4.* =
|
|
||||||
// metrics.http.visits.ipv6.* =
|
|
||||||
// metrics.http.visitors.* =
|
// metrics.http.visitors.* =
|
||||||
|
this.visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
// metrics.http.visitors.ipv4.* =
|
// metrics.http.visitors.ipv4.* =
|
||||||
// metrics.http.visitors.ipv6.* =
|
// metrics.http.visitors.ipv6.* =
|
||||||
if (log.isVisit())
|
if (log.isIPv4())
|
||||||
{
|
{
|
||||||
// metrics.http.visits.* =
|
this.ipv4Visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
||||||
// metrics.http.visits.ipv4.* =
|
}
|
||||||
// metrics.http.visits.ipv6.* =
|
else
|
||||||
this.visits.putVisit(log);
|
{
|
||||||
this.visits.storeTimeMarks(year, yearMonth, yearWeek, date);
|
this.ipv6Visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
if (log.isIPv4())
|
|
||||||
{
|
|
||||||
this.ipv4Visits.putVisit(log);
|
|
||||||
this.ipv4Visits.storeTimeMarks(year, yearMonth, yearWeek, date);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.ipv6Visits.putVisit(log);
|
|
||||||
this.ipv6Visits.storeTimeMarks(year, yearMonth, yearWeek, date);
|
|
||||||
}
|
|
||||||
|
|
||||||
// metrics.http.visitors.* =
|
|
||||||
// metrics.http.visitors.ipv4.* =
|
|
||||||
// metrics.http.visitors.ipv6.* =
|
|
||||||
this.visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
|
||||||
|
|
||||||
if (log.isIPv4())
|
|
||||||
{
|
|
||||||
this.ipv4Visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.ipv6Visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// metrics.http.methods.XXXX
|
// metrics.http.visitors.bots.*
|
||||||
String method = log.getMethod().toString();
|
// metrics.http.visitors.humans.*
|
||||||
this.counters.inc("metrics.http.methods." + method, year, yearMonth, yearWeek, date);
|
if (log.isBot())
|
||||||
|
{
|
||||||
|
this.botVisitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.humanVisitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
|
||||||
|
}
|
||||||
|
|
||||||
// metrics.http.status.XXXX
|
// metrics.http.status.XXXX
|
||||||
String status = String.valueOf(log.getStatus().getCode());
|
String status = String.valueOf(log.getStatus().getCode());
|
||||||
|
|
|
@ -84,8 +84,6 @@ public class HttpErrorLogAnalyzer
|
||||||
{
|
{
|
||||||
if ((file != null) && (!file.isFile()) || (file.exists()))
|
if ((file != null) && (!file.isFile()) || (file.exists()))
|
||||||
{
|
{
|
||||||
System.out.println("Probing file [" + file.getAbsolutePath() + "]");
|
|
||||||
|
|
||||||
//
|
//
|
||||||
Pattern pattern;
|
Pattern pattern;
|
||||||
if (LineIterator.readFirstLine(file).startsWith("["))
|
if (LineIterator.readFirstLine(file).startsWith("["))
|
||||||
|
@ -169,14 +167,7 @@ public class HttpErrorLogAnalyzer
|
||||||
if (matcher.matches())
|
if (matcher.matches())
|
||||||
{
|
{
|
||||||
result = new HttpErrorLog();
|
result = new HttpErrorLog();
|
||||||
if (pattern == APACHE_ERROR_PATTERN)
|
result.setTime(LocalDateTime.parse(matcher.group("time"), DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss.SSSSSS yyyy").withLocale(Locale.ENGLISH)));
|
||||||
{
|
|
||||||
result.setTime(LocalDateTime.parse(matcher.group("time"), DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss.SSSSSS yyyy").withLocale(Locale.ENGLISH)));
|
|
||||||
}
|
|
||||||
else if (pattern == NGINX_ERROR_PATTERN)
|
|
||||||
{
|
|
||||||
result.setTime(LocalDateTime.parse(matcher.group("time"), DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withLocale(Locale.ENGLISH)));
|
|
||||||
}
|
|
||||||
result.setLevel(matcher.group("level"));
|
result.setLevel(matcher.group("level"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2022 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.metrics.http;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Class HttpMethod.
|
|
||||||
*/
|
|
||||||
public enum HttpMethod
|
|
||||||
{
|
|
||||||
GET,
|
|
||||||
HEAD,
|
|
||||||
POST,
|
|
||||||
OPTIONS,
|
|
||||||
CONNECT,
|
|
||||||
TRACE,
|
|
||||||
PUT,
|
|
||||||
PATCH,
|
|
||||||
DELETE,
|
|
||||||
UNKNOWN;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the.
|
|
||||||
*
|
|
||||||
* @param value
|
|
||||||
* the value
|
|
||||||
* @return the http method
|
|
||||||
*/
|
|
||||||
public static HttpMethod of(final String value)
|
|
||||||
{
|
|
||||||
HttpMethod result;
|
|
||||||
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = valueOf(value);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException exception)
|
|
||||||
{
|
|
||||||
result = UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -47,8 +47,6 @@ public class UserAgent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the browser.
|
* Gets the browser.
|
||||||
*
|
|
||||||
* WARNING: MUST BE GREATLY IMPROVED
|
|
||||||
*
|
*
|
||||||
* @return the browser
|
* @return the browser
|
||||||
*/
|
*/
|
||||||
|
@ -56,34 +54,18 @@ public class UserAgent
|
||||||
{
|
{
|
||||||
UserAgentBrowser result;
|
UserAgentBrowser result;
|
||||||
|
|
||||||
if (StringUtils.containsIgnoreCase(this.source, "Chrome/"))
|
if (StringUtils.containsIgnoreCase(this.source, "Firefox"))
|
||||||
{
|
|
||||||
result = UserAgentBrowser.CHROME;
|
|
||||||
}
|
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "Chromium/"))
|
|
||||||
{
|
|
||||||
result = UserAgentBrowser.CHROMIUM;
|
|
||||||
}
|
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "Firefox/"))
|
|
||||||
{
|
{
|
||||||
result = UserAgentBrowser.FIREFOX;
|
result = UserAgentBrowser.FIREFOX;
|
||||||
}
|
}
|
||||||
|
else if (StringUtils.containsIgnoreCase(this.source, "Chrome"))
|
||||||
|
{
|
||||||
|
result = UserAgentBrowser.CHROME;
|
||||||
|
}
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "Lynx"))
|
else if (StringUtils.containsIgnoreCase(this.source, "Lynx"))
|
||||||
{
|
{
|
||||||
result = UserAgentBrowser.LYNX;
|
result = UserAgentBrowser.LYNX;
|
||||||
}
|
}
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "MSIE "))
|
|
||||||
{
|
|
||||||
result = UserAgentBrowser.MSIE;
|
|
||||||
}
|
|
||||||
else if (StringsUtils.containsAnyIgnoreCase(this.source, "Opera", "OPR/"))
|
|
||||||
{
|
|
||||||
result = UserAgentBrowser.OPERA;
|
|
||||||
}
|
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "Safari/"))
|
|
||||||
{
|
|
||||||
result = UserAgentBrowser.SAFARI;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = UserAgentBrowser.OTHER;
|
result = UserAgentBrowser.OTHER;
|
||||||
|
@ -95,8 +77,6 @@ public class UserAgent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the device.
|
* Gets the device.
|
||||||
*
|
|
||||||
* WARNING: MUST BE GREATLY IMPROVED
|
|
||||||
*
|
*
|
||||||
* @return the device
|
* @return the device
|
||||||
*/
|
*/
|
||||||
|
@ -104,21 +84,13 @@ public class UserAgent
|
||||||
{
|
{
|
||||||
UserAgentDevice result;
|
UserAgentDevice result;
|
||||||
|
|
||||||
if (StringsUtils.containsAnyIgnoreCase(this.source, "Playstation"))
|
if (StringsUtils.containsAnyIgnoreCase(this.source, "iOS", "Android"))
|
||||||
{
|
|
||||||
result = UserAgentDevice.CONSOLE;
|
|
||||||
}
|
|
||||||
else if (StringsUtils.containsAnyIgnoreCase(this.source, "Desktop"))
|
|
||||||
{
|
|
||||||
result = UserAgentDevice.PC;
|
|
||||||
}
|
|
||||||
else if (StringsUtils.containsAnyIgnoreCase(this.source, "Android", "iPhone"))
|
|
||||||
{
|
{
|
||||||
result = UserAgentDevice.PHONE;
|
result = UserAgentDevice.PHONE;
|
||||||
}
|
}
|
||||||
else if (StringsUtils.containsAnyIgnoreCase(this.source, "iPad"))
|
else if (StringsUtils.containsAnyIgnoreCase(this.source, "Playstation"))
|
||||||
{
|
{
|
||||||
result = UserAgentDevice.TABLET;
|
result = UserAgentDevice.CONSOLE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -138,42 +110,18 @@ public class UserAgent
|
||||||
{
|
{
|
||||||
UserAgentOS result;
|
UserAgentOS result;
|
||||||
|
|
||||||
if (StringUtils.containsIgnoreCase(this.source, "Android"))
|
if (StringUtils.containsIgnoreCase(this.source, "Firefox"))
|
||||||
{
|
{
|
||||||
result = UserAgentOS.ANDROID;
|
result = UserAgentOS.ANDROID;
|
||||||
}
|
}
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "FreeBSD"))
|
else if (StringUtils.containsIgnoreCase(this.source, "Chrome"))
|
||||||
{
|
{
|
||||||
result = UserAgentOS.FREEBSD;
|
result = UserAgentOS.FREEBSD;
|
||||||
}
|
}
|
||||||
else if (StringsUtils.containsAnyIgnoreCase(this.source, "Debian", "Gentoo", "Linux aarch", "Linux arm", "Linux i586", "Linux i686", "Linux x64", "Linux x86_64"))
|
else if (StringUtils.containsIgnoreCase(this.source, "Lynx"))
|
||||||
{
|
{
|
||||||
result = UserAgentOS.GNULINUX;
|
result = UserAgentOS.GNULINUX;
|
||||||
}
|
}
|
||||||
else if (StringsUtils.containsAnyIgnoreCase(this.source, "Debian", "Gentoo", "Linux aarch", "Linux arm", "Linux i586", "Linux i686", "Linux x64", "Linux x86_64"))
|
|
||||||
{
|
|
||||||
result = UserAgentOS.GNULINUX;
|
|
||||||
}
|
|
||||||
else if (StringsUtils.containsAnyIgnoreCase(this.source, "iPhone"))
|
|
||||||
{
|
|
||||||
result = UserAgentOS.IOS;
|
|
||||||
}
|
|
||||||
else if (StringsUtils.containsAnyIgnoreCase(this.source, "Macintosh", "Mac OS X", "Mac OS Desktop"))
|
|
||||||
{
|
|
||||||
result = UserAgentOS.MACOS;
|
|
||||||
}
|
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "windows"))
|
|
||||||
{
|
|
||||||
result = UserAgentOS.MSWINDOWS;
|
|
||||||
}
|
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "NetBSD"))
|
|
||||||
{
|
|
||||||
result = UserAgentOS.NETBSD;
|
|
||||||
}
|
|
||||||
else if (StringUtils.containsIgnoreCase(this.source, "OpenBSD"))
|
|
||||||
{
|
|
||||||
result = UserAgentOS.OPENBSD;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = UserAgentOS.OTHER;
|
result = UserAgentOS.OTHER;
|
||||||
|
@ -186,8 +134,6 @@ public class UserAgent
|
||||||
/**
|
/**
|
||||||
* Gets the type.
|
* Gets the type.
|
||||||
*
|
*
|
||||||
* WARNING: MUST BE GREATLY IMPROVED
|
|
||||||
*
|
|
||||||
* @return the type
|
* @return the type
|
||||||
*/
|
*/
|
||||||
public UserAgentType getType()
|
public UserAgentType getType()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021-2022 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 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,9 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package fr.devinsy.statoolinfos.metrics.http;
|
package fr.devinsy.statoolinfos.metrics.http;
|
||||||
|
|
||||||
/**
|
|
||||||
* The Enum UserAgentOS.
|
|
||||||
*/
|
|
||||||
public enum UserAgentOS
|
public enum UserAgentOS
|
||||||
{
|
{
|
||||||
ANDROID,
|
ANDROID,
|
||||||
|
@ -31,5 +28,5 @@ public enum UserAgentOS
|
||||||
MACOS,
|
MACOS,
|
||||||
NETBSD,
|
NETBSD,
|
||||||
OPENBSD,
|
OPENBSD,
|
||||||
OTHER,
|
OTHER
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ public class VisitCounters extends HashMap<String, Visits>
|
||||||
*/
|
*/
|
||||||
public void putVisit(final HttpAccessLog log)
|
public void putVisit(final HttpAccessLog log)
|
||||||
{
|
{
|
||||||
if (log != null)
|
if ((log != null) && (log.getStatus().getCategory() == HttpStatusCategory.SUCCESS))
|
||||||
{
|
{
|
||||||
String key = computeKey(log);
|
String key = computeKey(log);
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,8 @@ HeadlessChrome/
|
||||||
^Go-http-client
|
^Go-http-client
|
||||||
^GoModuleMirror/
|
^GoModuleMirror/
|
||||||
^HotJava/
|
^HotJava/
|
||||||
internal dummy connection
|
|
||||||
^Java/
|
^Java/
|
||||||
^JGit/
|
^JGit/
|
||||||
Let's Encrypt validation server;
|
|
||||||
^MastoPeek
|
^MastoPeek
|
||||||
^mattermost-
|
^mattermost-
|
||||||
^Misskey/
|
^Misskey/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021-2022 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 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.
|
||||||
*
|
*
|
||||||
|
@ -83,7 +83,6 @@ public class MinetestLogAnalyzer
|
||||||
result.putAll(this.counters);
|
result.putAll(this.counters);
|
||||||
|
|
||||||
result.putAll(this.activePlayers.getCounters("metrics.service.users"));
|
result.putAll(this.activePlayers.getCounters("metrics.service.users"));
|
||||||
result.putAll(this.activePlayers.getCounters("metrics.service.accounts.active"));
|
|
||||||
result.putAll(this.ips.getCounters("metrics.service.ip"));
|
result.putAll(this.ips.getCounters("metrics.service.ip"));
|
||||||
result.putAll(this.ipv4.getCounters("metrics.service.ip.ipv4"));
|
result.putAll(this.ipv4.getCounters("metrics.service.ip.ipv4"));
|
||||||
result.putAll(this.ipv6.getCounters("metrics.service.ip.ipv6"));
|
result.putAll(this.ipv6.getCounters("metrics.service.ip.ipv6"));
|
||||||
|
@ -162,7 +161,6 @@ public class MinetestLogAnalyzer
|
||||||
// metrics.metaverse.logs.warning
|
// metrics.metaverse.logs.warning
|
||||||
// metrics.metaverse.logs.error
|
// metrics.metaverse.logs.error
|
||||||
// metrics.metaverse.logs.none
|
// metrics.metaverse.logs.none
|
||||||
// metrics.metaverse.logs.unknown
|
|
||||||
if (log.getLevel() == MinetestLogLevel.ACTION)
|
if (log.getLevel() == MinetestLogLevel.ACTION)
|
||||||
{
|
{
|
||||||
this.counters.inc("metrics.metaverse.logs.action", year, yearMonth, yearWeek, date);
|
this.counters.inc("metrics.metaverse.logs.action", year, yearMonth, yearWeek, date);
|
||||||
|
@ -184,13 +182,14 @@ public class MinetestLogAnalyzer
|
||||||
this.counters.inc("metrics.metaverse.logs.unknown", year, yearMonth, yearWeek, date);
|
this.counters.inc("metrics.metaverse.logs.unknown", year, yearMonth, yearWeek, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
// metrics.service.users (= metrics.metaverse.players.active)
|
// metrics.metaverse.players.active
|
||||||
|
// metrics.service.users
|
||||||
this.activePlayers.put(log.getNickname(), year, yearMonth, yearWeek, date);
|
this.activePlayers.put(log.getNickname(), year, yearMonth, yearWeek, date);
|
||||||
|
|
||||||
// metrics.metaverse.players.max
|
// metrics.metaverse.players.max
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// metrics.metaverse.joiners
|
// metrics.metaverse.joiners --
|
||||||
if (log.getMessage().contains(" joins game."))
|
if (log.getMessage().contains(" joins game."))
|
||||||
{
|
{
|
||||||
this.counters.inc("metrics.metaverse.joiners", year, yearMonth, yearWeek, date);
|
this.counters.inc("metrics.metaverse.joiners", year, yearMonth, yearWeek, date);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021-2022 Christian Pierre MOMON <christian@momon.org>
|
* Copyright (C) 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.
|
||||||
*
|
*
|
||||||
|
@ -55,24 +55,12 @@ public class MinetestProber
|
||||||
{
|
{
|
||||||
PathCounters result;
|
PathCounters result;
|
||||||
|
|
||||||
// metrics.service.users, metrics.service.accounts.active
|
|
||||||
// metrics.metaverse.joiners
|
|
||||||
// metrics.service.ip
|
|
||||||
// metrics.service.ip.ipv4
|
|
||||||
// metrics.service.ip.ipv6
|
|
||||||
// metrics.metaverse.logs
|
|
||||||
// metrics.metaverse.logs.action
|
|
||||||
// metrics.metaverse.logs.warning
|
|
||||||
// metrics.metaverse.logs.error
|
|
||||||
// metrics.metaverse.logs.none
|
|
||||||
// metrics.metaverse.logs.unknown
|
|
||||||
result = MinetestLogAnalyzer.probe(logs);
|
result = MinetestLogAnalyzer.probe(logs);
|
||||||
|
|
||||||
// result.putAll(MumbleDatabaseAnalyzer.probe());
|
// metrics.metaverse.players
|
||||||
// metrics.service.accounts
|
// accounts
|
||||||
// metrics.service.database.bytes
|
// database size
|
||||||
|
// file size
|
||||||
// metrics.service.files.bytes
|
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 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.
|
||||||
*
|
*
|
||||||
|
@ -21,11 +21,8 @@ package fr.devinsy.statoolinfos.properties;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.Year;
|
import java.time.Year;
|
||||||
import java.time.YearMonth;
|
import java.time.YearMonth;
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.time.format.DateTimeParseException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
@ -258,13 +255,22 @@ public class PathPropertyList extends ArrayList<PathProperty> implements PathPro
|
||||||
pattern = prefix + ".";
|
pattern = prefix + ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PathProperty current : this)
|
boolean ended = false;
|
||||||
|
Iterator<PathProperty> iterator = iterator();
|
||||||
|
while (!ended)
|
||||||
{
|
{
|
||||||
if (StringUtils.startsWith(current.getPath(), pattern))
|
if (iterator.hasNext())
|
||||||
{
|
{
|
||||||
result.add(current);
|
PathProperty current = iterator.next();
|
||||||
|
if (StringUtils.startsWith(current.getPath(), pattern))
|
||||||
|
{
|
||||||
|
result.add(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,69 +310,6 @@ public class PathPropertyList extends ArrayList<PathProperty> implements PathPro
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the date.
|
|
||||||
*
|
|
||||||
* @param path
|
|
||||||
* the path
|
|
||||||
* @return the date
|
|
||||||
*/
|
|
||||||
public LocalDate getDate(final String path)
|
|
||||||
{
|
|
||||||
LocalDate result;
|
|
||||||
|
|
||||||
String value = get(path);
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String pattern;
|
|
||||||
if (value.matches("\\d{1,2}/\\d{1,2}/\\d{4}"))
|
|
||||||
{
|
|
||||||
pattern = "dd/MM/yyyy";
|
|
||||||
}
|
|
||||||
else if (value.matches("\\d{4}-\\d{2}-\\d{2}"))
|
|
||||||
{
|
|
||||||
pattern = "yyyy-MM-dd";
|
|
||||||
}
|
|
||||||
else if (value.matches("\\d{1,2}/\\d{4}"))
|
|
||||||
{
|
|
||||||
value = "01/" + value;
|
|
||||||
pattern = "dd/MM/yyyy";
|
|
||||||
}
|
|
||||||
else if (value.matches("\\d{4}-\\d{2}"))
|
|
||||||
{
|
|
||||||
value = value + "-01";
|
|
||||||
pattern = "yyyy-MM-dd";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pattern = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pattern == null)
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = LocalDate.parse(value, DateTimeFormatter.ofPattern(pattern));
|
|
||||||
}
|
|
||||||
catch (DateTimeParseException exception)
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the index property.
|
* Gets the index property.
|
||||||
*
|
*
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class StatAgent
|
||||||
CategoryStat stat = new CategoryStat(category);
|
CategoryStat stat = new CategoryStat(category);
|
||||||
StringSet organizations = new StringSet();
|
StringSet organizations = new StringSet();
|
||||||
|
|
||||||
for (Service service : federation.getServices())
|
for (Service service : federation.getServicesAll())
|
||||||
{
|
{
|
||||||
String softwareName = service.getSoftwareName();
|
String softwareName = service.getSoftwareName();
|
||||||
if (category.getSoftwares().containsIgnoreCase(softwareName))
|
if (category.getSoftwares().containsIgnoreCase(softwareName))
|
||||||
|
@ -195,7 +195,7 @@ public class StatAgent
|
||||||
SoftwareStat stat = new SoftwareStat(software.getName());
|
SoftwareStat stat = new SoftwareStat(software.getName());
|
||||||
stat.getCategories().addAll(categories.findBySoftware(software.getName()));
|
stat.getCategories().addAll(categories.findBySoftware(software.getName()));
|
||||||
StringSet organizations = new StringSet();
|
StringSet organizations = new StringSet();
|
||||||
for (Service service : federation.getServices())
|
for (Service service : federation.getServicesAll())
|
||||||
{
|
{
|
||||||
Software current = catalog.get(service.getSoftwareName());
|
Software current = catalog.get(service.getSoftwareName());
|
||||||
if (current == software)
|
if (current == software)
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class LineIterator
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = "";
|
result = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|