Implemented performance tab endpoint

This commit is contained in:
Rsl1122 2019-07-19 11:40:52 +03:00
parent 2d5890ff69
commit da04c431b6
6 changed files with 173 additions and 56 deletions

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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`