mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-11-20 09:35:47 +01:00
Implemented performance tab endpoint
This commit is contained in:
parent
2d5890ff69
commit
da04c431b6
@ -61,6 +61,10 @@ public class TPSMutator {
|
||||
return filterBy(tps -> tps.getDate() >= after && tps.getDate() <= before);
|
||||
}
|
||||
|
||||
public TPSMutator filterTPSBetween(int above, int below) {
|
||||
return filterBy(tps -> tps.getTicksPerSecond() > above && tps.getTicksPerSecond() < below);
|
||||
}
|
||||
|
||||
public List<TPS> all() {
|
||||
return tpsData;
|
||||
}
|
||||
@ -241,4 +245,10 @@ public class TPSMutator {
|
||||
.filter(num -> num >= 0)
|
||||
.min().orElse(-1);
|
||||
}
|
||||
|
||||
public double averagePlayersOnline() {
|
||||
return tpsData.stream()
|
||||
.mapToDouble(TPS::getPlayers)
|
||||
.average().orElse(-1);
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.system.json;
|
||||
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.store.mutators.TPSMutator;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.queries.objects.TPSQueries;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.DisplaySettings;
|
||||
import com.djrapitops.plan.utilities.formatting.Formatter;
|
||||
import com.djrapitops.plan.utilities.formatting.Formatters;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Parses JSON payload for /server-page Performance tab.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@Singleton
|
||||
public class PerformanceJSONParser implements TabJSONParser<Map<String, Object>> {
|
||||
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
|
||||
private final Formatter<Double> decimalFormatter;
|
||||
private final Formatter<Long> timeAmountFormatter;
|
||||
private final Formatter<Double> percentageFormatter;
|
||||
|
||||
@Inject
|
||||
public PerformanceJSONParser(
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
Formatters formatters
|
||||
) {
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
|
||||
decimalFormatter = formatters.decimals();
|
||||
percentageFormatter = formatters.percentage();
|
||||
timeAmountFormatter = formatters.timeAmount();
|
||||
}
|
||||
|
||||
public Map<String, Object> createJSONAsMap(UUID serverUUID) {
|
||||
Map<String, Object> serverOverview = new HashMap<>();
|
||||
Database db = dbSystem.getDatabase();
|
||||
long now = System.currentTimeMillis();
|
||||
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
|
||||
List<TPS> tpsData = db.query(TPSQueries.fetchTPSDataOfServer(monthAgo, now, serverUUID));
|
||||
|
||||
serverOverview.put("numbers", createNumbersMap(tpsData));
|
||||
serverOverview.put("insights", createInsightsMap(tpsData, serverUUID));
|
||||
return serverOverview;
|
||||
}
|
||||
|
||||
private Map<String, Object> createNumbersMap(List<TPS> tpsData) {
|
||||
long now = System.currentTimeMillis();
|
||||
long dayAgo = now - TimeUnit.DAYS.toMillis(1L);
|
||||
long weekAgo = now - TimeUnit.DAYS.toMillis(7L);
|
||||
|
||||
Map<String, Object> numbers = new HashMap<>();
|
||||
|
||||
TPSMutator tpsDataMonth = new TPSMutator(tpsData);
|
||||
TPSMutator tpsDataWeek = tpsDataMonth.filterDataBetween(weekAgo, now);
|
||||
TPSMutator tpsDataDay = tpsDataWeek.filterDataBetween(dayAgo, now);
|
||||
|
||||
Integer tpsThreshold = config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED);
|
||||
numbers.put("low_tps_spikes_30d", tpsDataMonth.lowTpsSpikeCount(tpsThreshold));
|
||||
numbers.put("low_tps_spikes_7d", tpsDataWeek.lowTpsSpikeCount(tpsThreshold));
|
||||
numbers.put("low_tps_spikes_24h", tpsDataDay.lowTpsSpikeCount(tpsThreshold));
|
||||
|
||||
numbers.put("server_downtime_30d", timeAmountFormatter.apply(tpsDataMonth.serverDownTime()));
|
||||
numbers.put("server_downtime_7d", timeAmountFormatter.apply(tpsDataWeek.serverDownTime()));
|
||||
numbers.put("server_downtime_24h", timeAmountFormatter.apply(tpsDataDay.serverDownTime()));
|
||||
|
||||
numbers.put("tps_30d", format(tpsDataMonth.averageTPS()));
|
||||
numbers.put("tps_7d", format(tpsDataWeek.averageTPS()));
|
||||
numbers.put("tps_24h", format(tpsDataDay.averageTPS()));
|
||||
numbers.put("cpu_30d", percentageFormatter.apply(tpsDataMonth.averageCPU() / 100.0));
|
||||
numbers.put("cpu_7d", percentageFormatter.apply(tpsDataWeek.averageCPU() / 100.0));
|
||||
numbers.put("cpu_24h", percentageFormatter.apply(tpsDataDay.averageCPU() / 100.0));
|
||||
numbers.put("ram_30d", format(tpsDataMonth.averageRAM()) + " MB");
|
||||
numbers.put("ram_7d", format(tpsDataWeek.averageRAM()) + " MB");
|
||||
numbers.put("ram_24h", format(tpsDataDay.averageRAM()) + " MB");
|
||||
numbers.put("entities_30d", (int) tpsDataMonth.averageEntities());
|
||||
numbers.put("entities_7d", (int) tpsDataWeek.averageEntities());
|
||||
numbers.put("entities_24h", (int) tpsDataDay.averageEntities());
|
||||
numbers.put("chunks_30d", (int) tpsDataMonth.averageChunks());
|
||||
numbers.put("chunks_7d", (int) tpsDataWeek.averageChunks());
|
||||
numbers.put("chunks_24h", (int) tpsDataDay.averageChunks());
|
||||
|
||||
numbers.put("max_disk_30d", tpsDataMonth.maxFreeDisk() + " Mb");
|
||||
numbers.put("max_disk_7d", tpsDataWeek.maxFreeDisk() + " Mb");
|
||||
numbers.put("max_disk_24h", tpsDataDay.maxFreeDisk() + " Mb");
|
||||
numbers.put("min_disk_30d", tpsDataMonth.minFreeDisk() + " Mb");
|
||||
numbers.put("min_disk_7d", tpsDataWeek.minFreeDisk() + " Mb");
|
||||
numbers.put("min_disk_24h", tpsDataDay.minFreeDisk() + " Mb");
|
||||
|
||||
return numbers;
|
||||
}
|
||||
|
||||
private String format(double value) {
|
||||
return decimalFormatter.apply(value);
|
||||
}
|
||||
|
||||
private Map<String, Object> createInsightsMap(List<TPS> tpsData, UUID serverUUID) {
|
||||
Database db = dbSystem.getDatabase();
|
||||
long now = System.currentTimeMillis();
|
||||
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
|
||||
|
||||
TPSMutator tpsMutator = new TPSMutator(tpsData);
|
||||
Integer tpsThreshold = config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED);
|
||||
TPSMutator lowTPS = tpsMutator.filterTPSBetween(-1, tpsThreshold);
|
||||
|
||||
Map<String, Object> insights = new HashMap<>();
|
||||
|
||||
insights.put("low_tps_players", decimalFormatter.apply(lowTPS.averagePlayersOnline()));
|
||||
insights.put("low_tps_cpu", decimalFormatter.apply(lowTPS.averageCPU()));
|
||||
insights.put("low_tps_entities", decimalFormatter.apply(lowTPS.averageEntities()));
|
||||
insights.put("low_tps_chunks", decimalFormatter.apply(lowTPS.averageChunks()));
|
||||
|
||||
insights.put("low_tps_disconnects", "Not implemented");
|
||||
insights.put("low_disk_space_dates", Collections.emptyList());
|
||||
|
||||
return insights;
|
||||
}
|
||||
}
|
@ -50,7 +50,8 @@ public class RootJSONHandler extends TreePageHandler {
|
||||
SessionsOverviewJSONParser sessionsOverviewJSONParser,
|
||||
PlayerKillsJSONHandler playerKillsJSONHandler,
|
||||
PvPPvEJSONParser pvPPvEJSONParser,
|
||||
PlayerBaseOverviewJSONParser playerBaseOverviewJSONParser
|
||||
PlayerBaseOverviewJSONParser playerBaseOverviewJSONParser,
|
||||
PerformanceJSONParser performanceJSONParser
|
||||
) {
|
||||
super(responseFactory);
|
||||
|
||||
@ -66,6 +67,7 @@ public class RootJSONHandler extends TreePageHandler {
|
||||
registerPage("sessionsOverview", sessionsOverviewJSONParser);
|
||||
registerPage("playerVersus", pvPPvEJSONParser);
|
||||
registerPage("playerbaseOverview", playerBaseOverviewJSONParser);
|
||||
registerPage("performanceOverview", performanceJSONParser);
|
||||
}
|
||||
|
||||
private <T> void registerPage(String identifier, TabJSONParser<T> tabJSONParser) {
|
||||
|
@ -45,7 +45,7 @@ public class TimeAmountFormatter implements Formatter<Long> {
|
||||
|
||||
@Override
|
||||
public String apply(Long ms) {
|
||||
if (ms <= 0) {
|
||||
if (ms < 0) {
|
||||
return "-";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
@ -107,20 +107,18 @@ public class TimeAmountFormatter implements Formatter<Long> {
|
||||
}
|
||||
|
||||
private void appendSeconds(StringBuilder builder, long seconds, long minutes, long hours, String fHours, String fMinutes, String fSeconds) {
|
||||
if (seconds != 0 || fSeconds.contains(ZERO_PH)) {
|
||||
String s = fSeconds.replace(SECONDS_PH, String.valueOf(seconds));
|
||||
if (minutes == 0 && s.contains(MINUTES_PH)) {
|
||||
if (hours == 0 && fMinutes.contains(HOURS_PH)) {
|
||||
builder.append(fHours.replace(ZERO_PH, "0").replace(HOURS_PH, "0"));
|
||||
}
|
||||
builder.append(fMinutes.replace(HOURS_PH, "").replace(ZERO_PH, "0").replace(MINUTES_PH, "0"));
|
||||
String s = fSeconds.replace(SECONDS_PH, String.valueOf(seconds));
|
||||
if (minutes == 0 && s.contains(MINUTES_PH)) {
|
||||
if (hours == 0 && fMinutes.contains(HOURS_PH)) {
|
||||
builder.append(fHours.replace(ZERO_PH, "0").replace(HOURS_PH, "0"));
|
||||
}
|
||||
s = s.replace(MINUTES_PH, "");
|
||||
if (s.contains(ZERO_PH) && String.valueOf(seconds).length() == 1) {
|
||||
builder.append('0');
|
||||
}
|
||||
builder.append(s);
|
||||
builder.append(fMinutes.replace(HOURS_PH, "").replace(ZERO_PH, "0").replace(MINUTES_PH, "0"));
|
||||
}
|
||||
s = s.replace(MINUTES_PH, "");
|
||||
if (s.contains(ZERO_PH) && String.valueOf(seconds).length() == 1) {
|
||||
builder.append('0');
|
||||
}
|
||||
builder.append(s);
|
||||
}
|
||||
|
||||
private void appendDays(StringBuilder builder, long days) {
|
||||
|
@ -1421,48 +1421,7 @@
|
||||
jsonRequest("../v1/sessionsOverview?serverName=${serverName}", loadSessionValues);
|
||||
jsonRequest("../v1/playerVersus?serverName=${serverName}", loadPvPPvEValues);
|
||||
jsonRequest("../v1/playerbaseOverview?serverName=${serverName}", loadPlayerbaseOverviewValues);
|
||||
loadPerformanceValues(
|
||||
{
|
||||
numbers: {
|
||||
low_tps_spikes_30d: 4532,
|
||||
low_tps_spikes_7d: 1235,
|
||||
low_tps_spikes_24h: 411,
|
||||
server_downtime_30d: '5d 1h 43m',
|
||||
server_downtime_7d: '3d 1h 43m',
|
||||
server_downtime_24h: '1h 43m',
|
||||
tps_30d: '19.91',
|
||||
tps_7d: '19.94',
|
||||
tps_24h: '19.94',
|
||||
cpu_30d: '16.91%',
|
||||
cpu_7d: '14.4%',
|
||||
cpu_24h: '16.01%',
|
||||
ram_30d: '320 MB',
|
||||
ram_7d: '432 MB',
|
||||
ram_24h: '432 MB',
|
||||
entities_30d: 43,
|
||||
entities_7d: 26,
|
||||
entities_24h: 75,
|
||||
chunks_30d: 246,
|
||||
chunks_7d: 256,
|
||||
chunks_24h: 256,
|
||||
max_disk_30d: '135113 Mb',
|
||||
max_disk_7d: '134795 Mb',
|
||||
max_disk_24h: '126425 Mb',
|
||||
min_disk_30d: '79872 Mb',
|
||||
min_disk_7d: '126419 Mb',
|
||||
min_disk_24h: '126419 Mb'
|
||||
},
|
||||
insights: {
|
||||
low_tps_players: '32.54',
|
||||
low_tps_entities: '432.54',
|
||||
low_tps_disconnects: '6.43',
|
||||
low_disk_space_dates: [
|
||||
'7 February 2019 12:34',
|
||||
'8 February 2019 1:43'
|
||||
]
|
||||
}
|
||||
}, null
|
||||
);
|
||||
jsonRequest("../v1/performanceOverview?serverName=${serverName}", loadPerformanceValues);
|
||||
setLoadingText('Rendering graphs..');
|
||||
|
||||
// TODO remove
|
||||
|
@ -38,6 +38,8 @@ Parameter|Expected value|Description
|
||||
|
||||
### `GET /v1/players`
|
||||
|
||||
### `GET /v1/performanceOverview`
|
||||
|
||||
Obtain data for `/server` player list.
|
||||
|
||||
Required parameters: `serverName` or `serverUUID`
|
||||
|
Loading…
Reference in New Issue
Block a user