mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-06 16:37:58 +01:00
Optimized /network Server information queries
This commit is contained in:
parent
539d817bf9
commit
517f479ad0
@ -24,6 +24,7 @@ import com.djrapitops.plan.utilities.html.graphs.line.Point;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
@ -252,4 +253,11 @@ public class TPSMutator {
|
||||
.mapToDouble(TPS::getPlayers)
|
||||
.average().orElse(-1);
|
||||
}
|
||||
|
||||
public Optional<TPS> getLast() {
|
||||
if (tpsData.isEmpty()) return Optional.empty();
|
||||
// else
|
||||
tpsData.sort(new TPSComparator());
|
||||
return Optional.of(tpsData.get(tpsData.size() - 1));
|
||||
}
|
||||
}
|
@ -26,9 +26,7 @@ import com.djrapitops.plan.db.sql.tables.UsersTable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
@ -100,6 +98,31 @@ public class PlayerCountQueries {
|
||||
return queryPlayerCount(sql, after, before);
|
||||
}
|
||||
|
||||
public static Query<Map<UUID, Integer>> uniquePlayerCounts(long after, long before) {
|
||||
String sql = SELECT + SessionsTable.SERVER_UUID + ",COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
|
||||
FROM + SessionsTable.TABLE_NAME +
|
||||
WHERE + SessionsTable.SESSION_END + "<=?" +
|
||||
AND + SessionsTable.SESSION_START + ">=?" +
|
||||
GROUP_BY + UserInfoTable.SERVER_UUID;
|
||||
|
||||
return new QueryStatement<Map<UUID, Integer>>(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setLong(1, before);
|
||||
statement.setLong(2, after);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Integer> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, Integer> byServer = new HashMap<>();
|
||||
while (set.next()) {
|
||||
byServer.put(UUID.fromString(set.getString(UserInfoTable.SERVER_UUID)), set.getInt("player_count"));
|
||||
}
|
||||
return byServer;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a EpochMs - Count map of unique players on a server.
|
||||
*
|
||||
@ -233,6 +256,31 @@ public class PlayerCountQueries {
|
||||
return queryPlayerCount(sql, after, before);
|
||||
}
|
||||
|
||||
public static Query<Map<UUID, Integer>> newPlayerCounts(long after, long before) {
|
||||
String sql = SELECT + UserInfoTable.SERVER_UUID + ",COUNT(1) as player_count" +
|
||||
FROM + UserInfoTable.TABLE_NAME +
|
||||
WHERE + UserInfoTable.REGISTERED + "<=?" +
|
||||
AND + UserInfoTable.REGISTERED + ">=?" +
|
||||
GROUP_BY + UserInfoTable.SERVER_UUID;
|
||||
|
||||
return new QueryStatement<Map<UUID, Integer>>(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setLong(1, before);
|
||||
statement.setLong(2, after);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Integer> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, Integer> byServer = new HashMap<>();
|
||||
while (set.next()) {
|
||||
byServer.put(UUID.fromString(set.getString(UserInfoTable.SERVER_UUID)), set.getInt("player_count"));
|
||||
}
|
||||
return byServer;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a EpochMs - Count map of new players on a server.
|
||||
*
|
||||
|
@ -63,16 +63,7 @@ public class TPSQueries {
|
||||
List<TPS> data = new ArrayList<>();
|
||||
while (set.next()) {
|
||||
|
||||
TPS tps = TPSBuilder.get()
|
||||
.date(set.getLong(DATE))
|
||||
.tps(set.getDouble(TPS))
|
||||
.playersOnline(set.getInt(PLAYERS_ONLINE))
|
||||
.usedCPU(set.getDouble(CPU_USAGE))
|
||||
.usedMemory(set.getLong(RAM_USAGE))
|
||||
.entities(set.getInt(ENTITIES))
|
||||
.chunksLoaded(set.getInt(CHUNKS))
|
||||
.freeDiskSpace(set.getLong(FREE_DISK))
|
||||
.toTPS();
|
||||
com.djrapitops.plan.data.container.TPS tps = extractTPS(set);
|
||||
|
||||
data.add(tps);
|
||||
}
|
||||
@ -81,6 +72,19 @@ public class TPSQueries {
|
||||
};
|
||||
}
|
||||
|
||||
public static TPS extractTPS(ResultSet set) throws SQLException {
|
||||
return TPSBuilder.get()
|
||||
.date(set.getLong(DATE))
|
||||
.tps(set.getDouble(TPS))
|
||||
.playersOnline(set.getInt(PLAYERS_ONLINE))
|
||||
.usedCPU(set.getDouble(CPU_USAGE))
|
||||
.usedMemory(set.getLong(RAM_USAGE))
|
||||
.entities(set.getInt(ENTITIES))
|
||||
.chunksLoaded(set.getInt(CHUNKS))
|
||||
.freeDiskSpace(set.getLong(FREE_DISK))
|
||||
.toTPS();
|
||||
}
|
||||
|
||||
public static Query<List<TPS>> fetchTPSDataOfServer(long after, long before, UUID serverUUID) {
|
||||
String sql = Select.all(TABLE_NAME)
|
||||
.where(SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID)
|
||||
@ -99,18 +103,7 @@ public class TPSQueries {
|
||||
public List<TPS> processResults(ResultSet set) throws SQLException {
|
||||
List<TPS> data = new ArrayList<>();
|
||||
while (set.next()) {
|
||||
|
||||
TPS tps = TPSBuilder.get()
|
||||
.date(set.getLong(DATE))
|
||||
.tps(set.getDouble(TPS))
|
||||
.playersOnline(set.getInt(PLAYERS_ONLINE))
|
||||
.usedCPU(set.getDouble(CPU_USAGE))
|
||||
.usedMemory(set.getLong(RAM_USAGE))
|
||||
.entities(set.getInt(ENTITIES))
|
||||
.chunksLoaded(set.getInt(CHUNKS))
|
||||
.freeDiskSpace(set.getLong(FREE_DISK))
|
||||
.toTPS();
|
||||
|
||||
TPS tps = extractTPS(set);
|
||||
data.add(tps);
|
||||
}
|
||||
return data;
|
||||
@ -146,15 +139,15 @@ public class TPSQueries {
|
||||
};
|
||||
}
|
||||
|
||||
public static Query<Map<UUID, List<DateObj<Integer>>>> fetchPlayersOnlineOfAllServersBut(long after, long before, UUID leaveOut) {
|
||||
String sql = SELECT + ServerTable.SERVER_UUID + ',' + DATE + ',' + PLAYERS_ONLINE +
|
||||
public static Query<Map<UUID, List<TPS>>> fetchTPSDataOfAllServersBut(long after, long before, UUID leaveOut) {
|
||||
String sql = SELECT + '*' +
|
||||
FROM + TABLE_NAME +
|
||||
INNER_JOIN + ServerTable.TABLE_NAME + " on " + ServerTable.TABLE_NAME + '.' + ServerTable.SERVER_ID + '=' + SERVER_ID +
|
||||
WHERE + ServerTable.SERVER_UUID + "!=?" +
|
||||
AND + ServerTable.INSTALLED + "=?" +
|
||||
AND + DATE + "<?" +
|
||||
AND + DATE + ">?";
|
||||
return new QueryStatement<Map<UUID, List<DateObj<Integer>>>>(sql, 1000) {
|
||||
return new QueryStatement<Map<UUID, List<TPS>>>(sql, 1000) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, leaveOut.toString());
|
||||
@ -164,16 +157,16 @@ public class TPSQueries {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, List<DateObj<Integer>>> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, List<DateObj<Integer>>> byServer = new HashMap<>();
|
||||
|
||||
public Map<UUID, List<TPS>> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, List<TPS>> byServer = new HashMap<>();
|
||||
while (set.next()) {
|
||||
UUID serverUUID = UUID.fromString(set.getString(ServerTable.SERVER_UUID));
|
||||
List<DateObj<Integer>> ofServer = byServer.getOrDefault(serverUUID, new ArrayList<>());
|
||||
ofServer.add(new DateObj<>(set.getLong(DATE), set.getInt(PLAYERS_ONLINE)));
|
||||
List<TPS> ofServer = byServer.getOrDefault(serverUUID, new ArrayList<>());
|
||||
|
||||
ofServer.add(extractTPS(set));
|
||||
|
||||
byServer.put(serverUUID, ofServer);
|
||||
}
|
||||
|
||||
return byServer;
|
||||
}
|
||||
};
|
||||
|
@ -155,26 +155,37 @@ public class JSONFactory {
|
||||
|
||||
public List<Map<String, Object>> serversAsJSONMaps() {
|
||||
Database db = dbSystem.getDatabase();
|
||||
Map<UUID, Server> serverInformation = db.query(ServerQueries.fetchPlanServerInformation());
|
||||
long now = System.currentTimeMillis();
|
||||
long weekAgo = now - TimeUnit.DAYS.toMillis(7L);
|
||||
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
|
||||
|
||||
Formatter<Long> year = formatters.yearLong();
|
||||
Formatter<Double> decimals = formatters.decimals();
|
||||
Formatter<Long> timeAmount = formatters.timeAmount();
|
||||
|
||||
Map<UUID, Server> serverInformation = db.query(ServerQueries.fetchPlanServerInformation());
|
||||
UUID proxyUUID = serverInformation.values().stream()
|
||||
.filter(Server::isProxy)
|
||||
.findFirst()
|
||||
.map(Server::getUuid).orElse(null);
|
||||
|
||||
Map<UUID, List<TPS>> tpsData = db.query(
|
||||
TPSQueries.fetchTPSDataOfAllServersBut(monthAgo, now, proxyUUID)
|
||||
);
|
||||
Map<UUID, Integer> totalPlayerCounts = db.query(PlayerCountQueries.newPlayerCounts(0, now));
|
||||
Map<UUID, Integer> newPlayerCounts = db.query(PlayerCountQueries.newPlayerCounts(monthAgo, now));
|
||||
Map<UUID, Integer> uniquePlayerCounts = db.query(PlayerCountQueries.uniquePlayerCounts(monthAgo, now));
|
||||
|
||||
List<Map<String, Object>> servers = new ArrayList<>();
|
||||
serverInformation.entrySet()
|
||||
.stream() // Sort alphabetically
|
||||
.sorted(Comparator.comparing(entry -> entry.getValue().getIdentifiableName().toLowerCase()))
|
||||
.filter(entry -> entry.getValue().isNotProxy())
|
||||
.forEach(entry -> {
|
||||
if (entry.getValue().isProxy()) return;
|
||||
|
||||
UUID serverUUID = entry.getKey();
|
||||
Map<String, Object> server = new HashMap<>();
|
||||
server.put("name", entry.getValue().getIdentifiableName());
|
||||
|
||||
// TODO Optimize these queries
|
||||
Optional<DateObj<Integer>> recentPeak = db.query(TPSQueries.fetchPeakPlayerCount(serverUUID, now - TimeUnit.DAYS.toMillis(2L)));
|
||||
Optional<DateObj<Integer>> allTimePeak = db.query(TPSQueries.fetchAllTimePeakPlayerCount(serverUUID));
|
||||
server.put("last_peak_date", recentPeak.map(DateObj::getDate).map(year).orElse("-"));
|
||||
@ -182,17 +193,20 @@ public class JSONFactory {
|
||||
server.put("last_peak_players", recentPeak.map(DateObj::getValue).orElse(0));
|
||||
server.put("best_peak_players", allTimePeak.map(DateObj::getValue).orElse(0));
|
||||
|
||||
TPSMutator tpsMonth = new TPSMutator(db.query(TPSQueries.fetchTPSDataOfServer(now - TimeUnit.DAYS.toMillis(30L), now, serverUUID)));
|
||||
server.put("playersOnline", tpsMonth.all().stream().map(tps -> new double[]{tps.getDate(), tps.getPlayers()}).toArray(double[][]::new));
|
||||
server.put("players", db.query(PlayerCountQueries.newPlayerCount(0, now, serverUUID)));
|
||||
server.put("new_players", db.query(PlayerCountQueries.newPlayerCount(weekAgo, now, serverUUID)));
|
||||
server.put("unique_players", db.query(PlayerCountQueries.uniquePlayerCount(weekAgo, now, serverUUID)));
|
||||
TPSMutator tpsMonth = new TPSMutator(tpsData.getOrDefault(serverUUID, Collections.emptyList()));
|
||||
server.put("playersOnline", tpsMonth.all().stream()
|
||||
.map(tps -> new double[]{tps.getDate(), tps.getPlayers()})
|
||||
.toArray(double[][]::new));
|
||||
server.put("players", totalPlayerCounts.getOrDefault(serverUUID, 0));
|
||||
server.put("new_players", newPlayerCounts.getOrDefault(serverUUID, 0));
|
||||
server.put("unique_players", uniquePlayerCounts.getOrDefault(serverUUID, 0));
|
||||
TPSMutator tpsWeek = tpsMonth.filterDataBetween(weekAgo, now);
|
||||
double averageTPS = tpsWeek.averageTPS();
|
||||
server.put("avg_tps", averageTPS != -1 ? decimals.apply(averageTPS) : "No data");
|
||||
server.put("low_tps_spikes", tpsWeek.lowTpsSpikeCount(config.getNumber(DisplaySettings.GRAPH_TPS_THRESHOLD_MED)));
|
||||
server.put("downtime", timeAmount.apply(tpsWeek.serverDownTime()));
|
||||
Optional<TPS> online = db.query(TPSQueries.fetchLatestTPSEntryForServer(serverUUID));
|
||||
|
||||
Optional<TPS> online = tpsWeek.getLast();
|
||||
server.put("online", online.isPresent() ?
|
||||
online.get().getDate() >= now - TimeUnit.MINUTES.toMillis(3L) ?
|
||||
online.get().getPlayers() : "Possibly offline"
|
||||
|
Loading…
Reference in New Issue
Block a user