aboutsummaryrefslogtreecommitdiff
path: root/spark-common/src/main/java/me/lucko/spark
diff options
context:
space:
mode:
authorAndrew Steinborn <andrew@steinborn.me>2020-05-26 05:49:58 -0400
committerGitHub <noreply@github.com>2020-05-26 10:49:58 +0100
commitd993703e9b52651d456e7eceb691f90228b2cd5e (patch)
tree3f3c3450cb69818c1ea7edec552e92a44884a4b3 /spark-common/src/main/java/me/lucko/spark
parent0f207b3c44c701d42ac1bb828f5c967e2de73568 (diff)
downloadspark-d993703e9b52651d456e7eceb691f90228b2cd5e.tar.gz
spark-d993703e9b52651d456e7eceb691f90228b2cd5e.tar.bz2
spark-d993703e9b52651d456e7eceb691f90228b2cd5e.zip
Add 95th percentile MSPT and replace average MSPT with median MSPT (#55)
Diffstat (limited to 'spark-common/src/main/java/me/lucko/spark')
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java18
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickStatistics.java10
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java24
3 files changed, 35 insertions, 17 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java b/spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java
index 08233db..64c2fba 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java
@@ -48,6 +48,8 @@ import java.util.function.Consumer;
public class HealthModule implements CommandModule {
+ private static final int MSPT_95_PERCENTILE = 95;
+
@Override
public void registerCommands(Consumer<Command> consumer) {
consumer.accept(Command.builder()
@@ -67,10 +69,9 @@ public class HealthModule implements CommandModule {
resp.replyPrefixed(TextComponent.empty());
if (tickStatistics.isDurationSupported()) {
- resp.replyPrefixed(TextComponent.of("Tick durations (avg/min/max ms) from last 5s, 10s, 1m:"));
+ resp.replyPrefixed(TextComponent.of("Tick durations (min/med/95%ile/max ms) from last 10s, 1m:"));
resp.replyPrefixed(TextComponent.builder(" ")
- .append(formatTickDurations(tickStatistics.duration5Sec())).append(TextComponent.of(", "))
- .append(formatTickDurations(tickStatistics.duration10Sec())).append(TextComponent.of(", "))
+ .append(formatTickDurations(tickStatistics.duration10Sec())).append(TextComponent.of("; "))
.append(formatTickDurations(tickStatistics.duration1Min()))
.build()
);
@@ -129,12 +130,11 @@ public class HealthModule implements CommandModule {
report.add(TextComponent.builder("")
.append(TextComponent.builder(">").color(TextColor.DARK_GRAY).decoration(TextDecoration.BOLD, true).build())
.append(TextComponent.space())
- .append(TextComponent.of("Tick durations (avg/min/max ms) from last 5s, 10s, 1m:", TextColor.GOLD))
+ .append(TextComponent.of("Tick durations (min/med/95%ile/max ms) from last 10s, 1m:", TextColor.GOLD))
.build()
);
report.add(TextComponent.builder(" ")
- .append(formatTickDurations(tickStatistics.duration5Sec())).append(TextComponent.of(", "))
- .append(formatTickDurations(tickStatistics.duration10Sec())).append(TextComponent.of(", "))
+ .append(formatTickDurations(tickStatistics.duration10Sec())).append(TextComponent.of("; "))
.append(formatTickDurations(tickStatistics.duration1Min()))
.build()
);
@@ -299,10 +299,12 @@ public class HealthModule implements CommandModule {
public static TextComponent formatTickDurations(RollingAverage average){
return TextComponent.builder("")
- .append(formatTickDuration(average.getAverage()))
- .append(TextComponent.of('/', TextColor.GRAY))
.append(formatTickDuration(average.getMin()))
.append(TextComponent.of('/', TextColor.GRAY))
+ .append(formatTickDuration(average.getMedian()))
+ .append(TextComponent.of('/', TextColor.GRAY))
+ .append(formatTickDuration(average.getPercentile(MSPT_95_PERCENTILE)))
+ .append(TextComponent.of('/', TextColor.GRAY))
.append(formatTickDuration(average.getMax()))
.build();
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickStatistics.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickStatistics.java
index 1ab0ea2..9e6f7c5 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickStatistics.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickStatistics.java
@@ -54,10 +54,9 @@ public class TickStatistics implements TickHook.Callback, TickReporter.Callback
private final TpsRollingAverage[] tpsAverages = {this.tps5Sec, this.tps10Sec, this.tps1Min, this.tps5Min, this.tps15Min};
private boolean durationSupported = false;
- private final RollingAverage tickDuration5Sec = new RollingAverage(TPS * 5);
private final RollingAverage tickDuration10Sec = new RollingAverage(TPS * 10);
private final RollingAverage tickDuration1Min = new RollingAverage(TPS * 60);
- private final RollingAverage[] tickDurationAverages = {this.tickDuration5Sec, this.tickDuration10Sec, this.tickDuration1Min};
+ private final RollingAverage[] tickDurationAverages = {this.tickDuration10Sec, this.tickDuration1Min};
private long last = 0;
@@ -118,13 +117,6 @@ public class TickStatistics implements TickHook.Callback, TickReporter.Callback
return this.tps15Min.getAverage();
}
- public RollingAverage duration5Sec() {
- if (!this.durationSupported) {
- return null;
- }
- return this.tickDuration5Sec;
- }
-
public RollingAverage duration10Sec() {
if (!this.durationSupported) {
return null;
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java b/spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java
index 5cf5bb5..1e5e8b2 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java
@@ -23,6 +23,8 @@ package me.lucko.spark.common.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Queue;
public class RollingAverage {
@@ -79,4 +81,26 @@ public class RollingAverage {
}
}
+ public double getMedian() {
+ return getPercentile(50);
+ }
+
+ public double getPercentile(int percentile) {
+ if (percentile < 0 || percentile > 100) {
+ throw new IllegalArgumentException("Invalid percentage " + percentile);
+ }
+
+ List<BigDecimal> sortedSamples;
+ synchronized (this) {
+ if (this.samples.isEmpty()) {
+ return 0;
+ }
+ sortedSamples = new ArrayList<>(this.samples);
+ }
+ sortedSamples.sort(null);
+
+ int rank = (int) Math.ceil((percentile / 100d) * sortedSamples.size());
+ return sortedSamples.get(rank).doubleValue();
+ }
+
}