Added sql database probing. Gitea + Minetest.

This commit is contained in:
Christian P. MOMON 2022-03-07 19:40:30 +01:00
parent b1e841c787
commit 87a6a15f10
15 changed files with 881 additions and 110 deletions

View file

@ -10,7 +10,6 @@
</classpathentry>
<classpathentry kind="lib" path="lib/commons-codec-1.8.jar" sourcepath="lib/commons-codec-1.8-sources.jar"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="lib" path="lib/mysql-jdbc-5.0.8.jar"/>
<classpathentry kind="lib" path="lib/UnitTesting/hamcrest-core-1.3.jar" sourcepath="lib/UnitTesting/hamcrest-core-1.3-sources.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"/>
@ -29,5 +28,9 @@
<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="lib" path="lib/json-simple-1.1.1.jar" sourcepath="lib/json-simple-1.1.1-sources.jar"/>
<classpathentry kind="lib" path="lib/mariadb-java-client-3.0.3.jar"/>
<classpathentry kind="lib" path="lib/postgresql-42.3.3.jar"/>
<classpathentry kind="lib" path="lib/sqlite-jdbc-3.36.0.3.jar"/>
<classpathentry kind="lib" path="lib/mysql-jdbc-5.0.8.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

116
README.md
View file

@ -127,55 +127,6 @@ 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.
### 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.httpaccesslog.pattern=
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)
@ -197,6 +148,13 @@ conf.probe.httpaccesslog.pattern=
conf.probe.gitea.data=/opt/gitea/data
conf.probe.gitea.api.url=https://forge.libre-service.eu/
conf.probe.gitea.token=b6598c616b1cd350b834258205da4e5e8b951005
# jdbc:mariadb://localhost:1234/databasename
# jdbc:mysql://localhost:1234/databasename
# jdbc:postgresql://localhost:1234/databasename
# jdbc:sqlite:/foo/bar/databasename.sqlite
conf.probe.gitea.database.url=
conf.probe.gitea.database.user=
conf.probe.gitea.database.password=
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
```
@ -208,7 +166,37 @@ Configuration template:
conf.probe.types=LibreQR
conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
conf.probe.httpaccesslog.pattern=
conf.probe.libreqr.data=/var/www/qrcode.libre-service.eu/data/
conf.probe.libreqr.datafiles=/var/www/foo.bar.org/temp/
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
```
### Minetest metrics
Configuration template:
```
conf.probe.types=Minetest
conf.probe.minetest.logs=/home/cpm/Projets/StatoolInfos/EnvTest/minetest/minetest.log*
conf.probe.minetest.players.database.url=jdbc:postgresql://localhost:5432/minetestdb
conf.probe.minetest.players.database.user=minetestdba
conf.probe.minetest.players.database.password=XXXXXXXXXXX
conf.probe.minetest.worlds.database.url=jdbc:postgresql://localhost:5432/minetestdb
conf.probe.minetest.worlds.database.user=minetestdba
conf.probe.minetest.worlds.database.password=XXXXXXXXXXX
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
```
@ -223,3 +211,31 @@ conf.probe.httpaccesslog.pattern=
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.httpaccesslog.pattern=
conf.probe.privatebin.data=/var/www/paste.libre-service.eu/data/
conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
```
### 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=
```

Binary file not shown.

BIN
lib/postgresql-42.3.3.jar Normal file

Binary file not shown.

Binary file not shown.

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2021 Christian Pierre MOMON <christian@momon.org>
* Copyright (C) 2020-2022 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
@ -266,11 +266,9 @@ public class Configuration extends PathPropertyList
result = new DatabaseConfig();
result.setHost(get(prefix + ".db.host"));
result.setPort(get(prefix + ".db.port"));
result.setName(get(prefix + ".db.name"));
result.setUser(get(prefix + ".db.user"));
result.setPassword(get(prefix + ".db.password"));
result.setUrl(get(prefix + ".database.url"));
result.setUser(get(prefix + ".database.user"));
result.setPassword(get(prefix + ".database.password"));
//
return result;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Christian Pierre MOMON <christian@momon.org>
* Copyright (C) 2021-2022 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
@ -18,14 +18,14 @@
*/
package fr.devinsy.statoolinfos.core;
import org.apache.commons.lang3.StringUtils;
/**
* The Class DatabaseConfig.
*/
public class DatabaseConfig
{
private String host;
private String port;
private String name;
private String url;
private String user;
private String password;
@ -34,31 +34,19 @@ public class DatabaseConfig
*/
public DatabaseConfig()
{
this.host = null;
this.port = null;
this.name = null;
this.url = null;
this.user = null;
this.password = null;
}
public String getHost()
{
return this.host;
}
public String getName()
{
return this.name;
}
public String getPassword()
{
return this.password;
}
public String getPort()
public String getUrl()
{
return this.port;
return this.url;
}
public String getUser()
@ -66,14 +54,26 @@ public class DatabaseConfig
return this.user;
}
public void setHost(final String host)
/**
* Checks if is sets the.
*
* @return true, if is sets the
*/
public boolean isSet()
{
this.host = host;
boolean result;
if (StringUtils.isAnyBlank(this.url, this.user))
{
result = false;
}
else
{
result = true;
}
public void setName(final String name)
{
this.name = name;
//
return result;
}
public void setPassword(final String password)
@ -81,13 +81,37 @@ public class DatabaseConfig
this.password = password;
}
public void setPort(final String port)
public void setUrl(final String url)
{
this.port = port;
this.url = url;
}
public void setUser(final String user)
{
this.user = user;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
String result;
String password;
if (StringUtils.isBlank(this.password))
{
password = "";
}
else
{
password = "**********";
}
result = String.format("[%s,%s,%s]", this.url, this.user, password);
//
return result;
}
}

View file

@ -159,8 +159,10 @@ public class Prober
logger.info("apiURL=[{}]", apiURL);
String apiToken = configuration.get("conf.probe.gitea.api.token");
logger.info("apiToken=[{}]", apiToken == null ? "null" : "************************");
DatabaseConfig database = configuration.getDatabaseConfig("conf.probe.gitea");
logger.info("database={}", database.toString());
PathCounters metrics = GiteaProber.probe(FilesUtils.searchByWildcard(httpLogs), httpAccessLogRegex, apiURL, apiToken, dataDirectory);
PathCounters metrics = GiteaProber.probe(FilesUtils.searchByWildcard(httpLogs), httpAccessLogRegex, apiURL, apiToken, dataDirectory, database);
counters.putAll(metrics);
}
@ -187,9 +189,13 @@ public class Prober
{
logger.info("== Probing Minetest.");
String source = configuration.get("conf.probe.minetest.logs");
DatabaseConfig database = configuration.getDatabaseConfig("conf.probe.minetest.players");
logger.info("source=[{}]", source);
DatabaseConfig playerDatabase = configuration.getDatabaseConfig("conf.probe.minetest.players");
logger.info("players database={}", playerDatabase.toString());
DatabaseConfig worldDatabase = configuration.getDatabaseConfig("conf.probe.minetest.worlds");
logger.info("wordls database={}", worldDatabase.toString());
PathCounters data = MinetestProber.probe(source, database);
PathCounters data = MinetestProber.probe(source, playerDatabase, worldDatabase);
counters.putAll(data);
}

View file

@ -20,6 +20,7 @@ package fr.devinsy.statoolinfos.metrics.gitea;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
@ -27,6 +28,7 @@ import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.statoolinfos.core.DatabaseConfig;
import fr.devinsy.statoolinfos.core.StatoolInfosException;
import fr.devinsy.statoolinfos.metrics.PathCounters;
import fr.devinsy.statoolinfos.metrics.UserCounters;
@ -36,6 +38,7 @@ import fr.devinsy.statoolinfos.metrics.http.HttpStatusCategory;
import fr.devinsy.statoolinfos.metrics.util.DatabaseProber;
import fr.devinsy.statoolinfos.metrics.util.DatafilesProber;
import fr.devinsy.statoolinfos.util.Files;
import fr.devinsy.statoolinfos.util.sql.SQLDatabase;
import fr.devinsy.strings.StringList;
/**
@ -67,7 +70,8 @@ public class GiteaProber
* @throws StatoolInfosException
* the statool infos exception
*/
public static PathCounters probe(final Files httpLogs, final String httpLogRegex, final String apiURL, final String apiToken, final File dataPath) throws IOException, StatoolInfosException
public static PathCounters probe(final Files httpLogs, final String httpLogRegex, final String apiURL, final String apiToken, final File dataPath, final DatabaseConfig databaseConfig)
throws IOException, StatoolInfosException
{
PathCounters result;
@ -77,7 +81,23 @@ public class GiteaProber
result = probeHttpAccessLog(httpLogs, httpLogRegex);
// metrics.service.database.bytes
result.putAll(DatabaseProber.probe(null));
try
{
if (databaseConfig.isSet())
{
SQLDatabase database = new SQLDatabase(databaseConfig.getUrl(), databaseConfig.getUser(), databaseConfig.getPassword());
database.open();
result.putAll(DatabaseProber.probe(database));
}
else
{
System.out.println("GITEA Database undefined.");
}
}
catch (SQLException exception)
{
logger.error("ERROR with database.", exception);
}
// metrics.service.files.bytes
// metrics.service.files.count

View file

@ -19,13 +19,17 @@
package fr.devinsy.statoolinfos.metrics.minetest;
import java.io.IOException;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.statoolinfos.core.DatabaseConfig;
import fr.devinsy.statoolinfos.core.StatoolInfosException;
import fr.devinsy.statoolinfos.metrics.PathCounters;
import fr.devinsy.statoolinfos.util.sql.SQLDatabase;
import fr.devinsy.strings.StringList;
/**
* The Class MinetestProber.
@ -51,7 +55,7 @@ public class MinetestProber
* @throws StatoolInfosException
* @throws IOException
*/
public static PathCounters probe(final String logs, final DatabaseConfig databaseConfig) throws IOException, StatoolInfosException
public static PathCounters probe(final String logs, final DatabaseConfig playerDatabaseConfig, final DatabaseConfig worldDatabaseConfig) throws IOException, StatoolInfosException
{
PathCounters result;
@ -68,6 +72,52 @@ public class MinetestProber
// metrics.metaverse.logs.unknown
result = MinetestLogAnalyzer.probe(logs);
// metrics.service.database.bytes
long databaseSize = 0;
try
{
System.out.println("Probing database [" + playerDatabaseConfig.getUrl() + "]");
if (playerDatabaseConfig.isSet())
{
SQLDatabase database = new SQLDatabase(playerDatabaseConfig.getUrl(), playerDatabaseConfig.getUser(), playerDatabaseConfig.getPassword());
database.open();
databaseSize += database.getDatabaseSize();
}
else
{
System.out.println("Minetest Players Database undefined.");
}
}
catch (SQLException exception)
{
logger.error("ERROR with database.", exception);
}
if (!StringUtils.equals(playerDatabaseConfig.getUrl(), worldDatabaseConfig.getUrl()))
{
try
{
System.out.println("Probing database [" + worldDatabaseConfig.getUrl() + "]");
if (worldDatabaseConfig.isSet())
{
SQLDatabase database = new SQLDatabase(worldDatabaseConfig.getUrl(), worldDatabaseConfig.getUser(), worldDatabaseConfig.getPassword());
database.open();
databaseSize += database.getDatabaseSize();
}
else
{
System.out.println("Minetest Worlds Database undefined.");
}
}
catch (SQLException exception)
{
logger.error("ERROR with database.", exception);
}
}
StringList timemarks = result.getNowTimeMarks();
result.set(databaseSize, "metrics.service.database.bytes", timemarks);
// result.putAll(MumbleDatabaseAnalyzer.probe());
// metrics.service.accounts
// metrics.service.database.bytes

View file

@ -23,8 +23,9 @@ import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.statoolinfos.core.DatabaseConfig;
import fr.devinsy.statoolinfos.metrics.PathCounters;
import fr.devinsy.statoolinfos.util.sql.SQLDatabase;
import fr.devinsy.strings.StringList;
/**
* The Class DatabaseProber.
@ -49,30 +50,21 @@ public class DatabaseProber
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public static PathCounters probe(final DatabaseConfig config) throws IOException
public static PathCounters probe(final SQLDatabase database) throws IOException
{
PathCounters result;
result = new PathCounters();
if (config != null)
if ((database != null) && (database.isOpened()))
{
System.out.println("Probing directory [" + config.getName() + "]");
}
System.out.println("Probing database [" + database.getUrl() + "]");
// if ((directory != null) && (directory.exists()) &&
// (directory.isDirectory()))
// {
// StringList timemarks = result.getNowTimeMarks();
//
// // metrics.service.database.bytes
// long size = FileUtils.sizeOfDirectory(directory);
// result.set(size, prefix + ".files.bytes", timemarks);
// }
// else
// {
// System.out.println("WARNING: datafile path not valid.");
// }
// metrics.service.database.bytes
long bytes = database.getDatabaseSize();
StringList timemarks = result.getNowTimeMarks();
result.set(bytes, "metrics.service.database.bytes", timemarks);
}
//
return result;

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2018-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.util.sql;
import java.sql.SQLException;
/**
* The Class ClosedDatabaseException.
*/
public class ClosedDatabaseException extends SQLException
{
private static final long serialVersionUID = 9220220563426218282L;
/**
* Instantiates a new closed database exception.
*/
public ClosedDatabaseException()
{
super("Invalid database status for this operation: closed.");
}
/**
* Instantiates a new closed database exception.
*
* @param message
* the message
*/
public ClosedDatabaseException(final String message)
{
super(message);
}
/**
* Instantiates a new closed database exception.
*
* @param message
* the message
* @param cause
* the cause
*/
public ClosedDatabaseException(final String message, final Throwable cause)
{
super(message, cause);
}
/**
* Instantiates a new closed database exception.
*
* @param cause
* the cause
*/
public ClosedDatabaseException(final Throwable cause)
{
super(cause);
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2018-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.util.sql;
import java.sql.SQLException;
/**
* The Class OpenedDatabaseException.
*/
public class OpenedDatabaseException extends SQLException
{
private static final long serialVersionUID = -8218498455798186368L;
/**
* Instantiates a new opened database exception.
*/
public OpenedDatabaseException()
{
super("Invalid database status for this operation: opened.");
}
/**
* Instantiates a new opened database exception.
*
* @param message
* the message
*/
public OpenedDatabaseException(final String message)
{
super(message);
}
/**
* Instantiates a new opened database exception.
*
* @param message
* the message
* @param cause
* the cause
*/
public OpenedDatabaseException(final String message, final Throwable cause)
{
super(message, cause);
}
/**
* Instantiates a new opened database exception.
*
* @param cause
* the cause
*/
public OpenedDatabaseException(final Throwable cause)
{
super(cause);
}
}

View file

@ -0,0 +1,441 @@
/*
* Copyright (C) 2013-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.util.sql;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class SQLDatabase.
*/
public class SQLDatabase
{
private static final Logger logger = LoggerFactory.getLogger(SQLDatabase.class);;
public enum Driver
{
HSQL,
MARIADB,
MYSQL,
NONE,
POSTGRES,
SQLITE
};
public enum Status
{
OPENED,
CLOSED
};
private Status status;
private Driver driver;
private String url;
private String login;
private String password;
private Connection connection;
/**
* This method opens a database session.
*
* @param driverClassName
* the driver class name
* @param url
* the url
* @param login
* the login
* @param password
* the password
*/
public SQLDatabase(final String url, final String login, final String password)
{
if (StringUtils.isBlank(url))
{
throw new IllegalArgumentException("url is null.");
}
else if (StringUtils.isBlank(login))
{
throw new IllegalArgumentException("login is null.");
}
else
{
this.status = Status.CLOSED;
this.driver = Driver.NONE;
this.url = url;
this.login = login;
this.password = password;
this.connection = null;
}
}
/**
* Close.
*/
public void close()
{
if (this.connection != null)
{
try
{
this.connection.close();
}
catch (SQLException exception)
{
logger.error("Error closing database.", exception);
}
finally
{
this.connection = null;
}
}
this.status = Status.CLOSED;
}
/**
* Gets the connection.
*
* @return the connection
* @throws SQLException
* the SQL exception
*/
public Connection getConnection() throws SQLException
{
Connection result;
if (isClosed())
{
throw new SQLException("Database not opened.");
}
else
{
if (this.connection != null)
{
result = this.connection;
}
else
{
throw new IllegalArgumentException("Connection not initialized.");
}
}
//
return result;
}
/**
* Gets the database size.
*
* @return the database size
*/
public long getDatabaseSize()
{
long result;
try
{
if (isOpened())
{
switch (this.driver)
{
case HSQL:
{
result = 0;
}
break;
case MARIADB:
case MYSQL:
{
String sql = "SELECT SUM(data_length + index_length) FROM information_schema.tables where table_schema = (select database());";
result = queryNumber(sql);
}
break;
case POSTGRES:
{
String sql = "SELECT pg_database_size(pg_database.datname) FROM pg_database WHERE pg_database.datname = (select current_catalog);";
result = queryNumber(sql);
}
break;
case SQLITE:
{
File file = new File(this.url.replace("jdbc:sqlite:", ""));
result = file.length();
}
break;
case NONE:
default:
result = 0;
}
}
else
{
result = 0;
}
}
catch (SQLException exception)
{
logger.error("ERROR querying database size.", exception);
result = 0;
}
//
return result;
}
/**
* Gets the driver.
*
* @return the driver
*/
public Driver getDriver()
{
Driver result;
result = this.driver;
//
return result;
}
/**
* Gets the login.
*
* @return the login
*/
public String getLogin()
{
String result;
result = this.login;
//
return result;
}
/**
* Gets the password.
*
* @return the password
*/
public String getPassword()
{
String result;
result = this.password;
//
return result;
}
/**
* Gets the url.
*
* @return the url
*/
public String getUrl()
{
String result;
result = this.url;
//
return result;
}
/**
* Checks if is closed.
*
* @return true, if is closed
*/
public boolean isClosed()
{
boolean result;
if (this.status == Status.CLOSED)
{
result = true;
}
else
{
result = false;
}
//
return result;
}
/**
* Checks if is opened.
*
* @return true, if is opened
*/
public boolean isOpened()
{
boolean result;
result = !isClosed();
//
return result;
}
/**
* Open.
*
* @throws SQLException
* the SQL exception
*/
public void open() throws SQLException
{
try
{
//
close();
//
if (this.url == null)
{
throw new IllegalArgumentException("Undefined source.");
}
else
{
if (this.url.startsWith("jdbc:sqlite:"))
{
this.driver = Driver.SQLITE;
Class.forName("org.sqlite.JDBC");
}
else if (this.url.startsWith("jdbc:postgresql:"))
{
Class.forName("org.postgresql.Driver");
this.driver = Driver.POSTGRES;
}
else if (this.url.startsWith("jdbc:mysql:"))
{
Class.forName("com.mysql.jdbc.Driver");
this.driver = Driver.MYSQL;
}
else if (this.url.startsWith("jdbc:mariadb:"))
{
Class.forName("org.mariadb.jdbc.Driver");
this.driver = Driver.MARIADB;
}
else
{
throw new SQLException("Unknown database type.");
}
this.connection = DriverManager.getConnection(this.url, this.login, this.password);
this.status = Status.OPENED;
logger.info("Single connection opened with [{}].", this.url);
}
}
catch (ClassNotFoundException exception)
{
throw new SQLException("ERROR with driver name.", exception);
}
}
/**
* Query number.
*
* @param sql
* the sql
* @return the long
* @throws SQLException
* the SQL exception
*/
public long queryNumber(final String sql) throws SQLException
{
long result;
if (isClosed())
{
throw new ClosedDatabaseException();
}
else
{
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try
{
connection = getConnection();
connection.setAutoCommit(true);
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
resultSet.next();
result = resultSet.getLong(1);
}
finally
{
SQLUtils.closeQuietly(statement, resultSet);
}
}
//
return result;
}
/**
* Sets the login.
*
* @param login
* the new login
*/
public void setLogin(final String login)
{
this.login = login;
}
/**
* Sets the password.
*
* @param password
* the new password
*/
public void setPassword(final String password)
{
this.password = password;
}
/**
* Sets the url.
*
* @param url
* the new url
*/
public void setUrl(final String url)
{
this.url = url;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
* Copyright (C) 2020-2022 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
@ -16,7 +16,7 @@
* 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.util;
package fr.devinsy.statoolinfos.util.sql;
import java.sql.Connection;
import java.sql.DriverManager;
@ -25,6 +25,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@ -244,6 +245,32 @@ public final class SQLUtils
return result;
}
/**
* To date time.
*
* @param source
* the source
* @return the date time
*/
public static LocalDateTime toDateTime(final java.sql.Timestamp source)
{
LocalDateTime result;
if (source == null)
{
result = null;
}
else
{
long seconds = source.getTime() / 1000;
long nanos = (source.getTime() - seconds * 1000) * 1000000;
result = LocalDateTime.ofEpochSecond(seconds, (int) nanos, ZoneOffset.UTC);
}
//
return result;
}
/**
* To date time.
*
@ -269,4 +296,54 @@ public final class SQLUtils
//
return result;
}
/**
* To timestamp.
*
* @param source
* the source
* @return the java.sql. timestamp
*/
public static java.sql.Timestamp toTimestamp(final Date source)
{
java.sql.Timestamp result;
if (source == null)
{
result = null;
}
else
{
result = new java.sql.Timestamp(source.getTime() * 1000);
}
//
return result;
}
/**
* To timestamp.
*
* @param source
* the source
* @return the java.sql. timestamp
*/
public static java.sql.Timestamp toTimestamp(final LocalDateTime source)
{
java.sql.Timestamp result;
if (source == null)
{
result = null;
}
else
{
long seconds = source.toEpochSecond(ZoneOffset.UTC);
long milliseconds = source.getNano() / 1000000;
result = new java.sql.Timestamp(seconds * 1000 + milliseconds);
}
//
return result;
}
}