aboutsummaryrefslogtreecommitdiff
path: root/spark-common/src
diff options
context:
space:
mode:
authorembeddedt <42941056+embeddedt@users.noreply.github.com>2022-06-09 16:34:22 -0400
committerembeddedt <42941056+embeddedt@users.noreply.github.com>2022-06-09 16:34:22 -0400
commitb3cb433ae9992962344f8aaa12024a5c3481590f (patch)
tree9a30a5cf2d915cd31f9e44d5f2153651aaa92d86 /spark-common/src
parent0d7f5bb4ec86f39579373eac863b425043590cd1 (diff)
parent0ac8713eaaefe7336db2e0369bbe547dc6c0da7d (diff)
downloadspark-b3cb433ae9992962344f8aaa12024a5c3481590f.tar.gz
spark-b3cb433ae9992962344f8aaa12024a5c3481590f.tar.bz2
spark-b3cb433ae9992962344f8aaa12024a5c3481590f.zip
Merge remote-tracking branch 'lucko/master' into forge-1.7.10
Diffstat (limited to 'spark-common/src')
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java87
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java22
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/api/GarbageCollectorInfo.java6
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/CommandResponseHandler.java14
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java322
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/HeapAnalysisModule.java87
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/SamplerModule.java6
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/CompletionSupplier.java27
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/TabCompleter.java27
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/heapdump/HeapDumpSummary.java31
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java36
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuInfo.java51
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuMonitor.java12
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/disk/DiskUsage.java71
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/memory/GarbageCollectorStatistics.java10
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/memory/MemoryInfo.java153
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/net/Direction.java37
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/net/NetworkInterfaceAverages.java88
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/net/NetworkInterfaceInfo.java274
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/net/NetworkMonitor.java141
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingStatistics.java149
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingSummary.java81
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PlayerPingProvider.java40
-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/platform/AbstractPlatformInfo.java17
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/PlatformInfo.java38
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/PlatformStatisticsProvider.java188
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java136
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/PropertiesFileReader.java64
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/ServerConfigProvider.java59
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java77
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java7
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadDumper.java3
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadGrouper.java53
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadNodeOrder.java11
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/AbstractDataAggregator.java10
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/DataAggregator.java6
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncDataAggregator.java2
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncProfilerAccess.java80
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncSampler.java53
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/jfr/JfrReader.java18
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaDataAggregator.java6
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java41
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/SimpleDataAggregator.java2
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/TickedDataAggregator.java7
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/node/AbstractNode.java1
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/node/StackTraceNode.java7
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/node/ThreadNode.java33
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/tick/AbstractTickHook.java4
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/tick/AbstractTickReporter.java4
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java27
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/ClassSourceLookup.java25
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/Compression.java100
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/FormatUtil.java29
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/LinuxProc.java84
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java17
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/SparkThreadFactory.java49
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/StatisticFormatter.java189
-rw-r--r--spark-common/src/main/proto/spark/spark.proto192
-rw-r--r--spark-common/src/main/proto/spark/spark_heap.proto27
-rw-r--r--spark-common/src/main/proto/spark/spark_sampler.proto73
-rwxr-xr-xspark-common/src/main/resources/linux/libasyncProfiler.sobin398099 -> 0 bytes
-rwxr-xr-xspark-common/src/main/resources/macosx/libasyncProfiler.sobin599568 -> 0 bytes
-rwxr-xr-xspark-common/src/main/resources/spark/linux/aarch64/libasyncProfiler.sobin0 -> 328432 bytes
-rwxr-xr-xspark-common/src/main/resources/spark/linux/amd64/libasyncProfiler.sobin0 -> 342239 bytes
-rwxr-xr-xspark-common/src/main/resources/spark/macos/libasyncProfiler.sobin0 -> 688400 bytes
66 files changed, 2911 insertions, 610 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java b/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java
index 57f8732..0ef4556 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java
@@ -40,7 +40,11 @@ import me.lucko.spark.common.command.tabcomplete.CompletionSupplier;
import me.lucko.spark.common.command.tabcomplete.TabCompleter;
import me.lucko.spark.common.monitor.cpu.CpuMonitor;
import me.lucko.spark.common.monitor.memory.GarbageCollectorStatistics;
+import me.lucko.spark.common.monitor.net.NetworkMonitor;
+import me.lucko.spark.common.monitor.ping.PingStatistics;
+import me.lucko.spark.common.monitor.ping.PlayerPingProvider;
import me.lucko.spark.common.monitor.tick.TickStatistics;
+import me.lucko.spark.common.platform.PlatformStatisticsProvider;
import me.lucko.spark.common.tick.TickHook;
import me.lucko.spark.common.tick.TickReporter;
import me.lucko.spark.common.util.BytebinClient;
@@ -63,7 +67,9 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Level;
import java.util.stream.Collectors;
import static net.kyori.adventure.text.Component.space;
@@ -89,6 +95,7 @@ public class SparkPlatform {
private final String viewerUrl;
private final OkHttpClient httpClient;
private final BytebinClient bytebinClient;
+ private final boolean disableResponseBroadcast;
private final List<CommandModule> commandModules;
private final List<Command> commands;
private final ReentrantLock commandExecuteLock = new ReentrantLock(true);
@@ -96,6 +103,8 @@ public class SparkPlatform {
private final TickHook tickHook;
private final TickReporter tickReporter;
private final TickStatistics tickStatistics;
+ private final PingStatistics pingStatistics;
+ private final PlatformStatisticsProvider statisticsProvider;
private Map<String, GarbageCollectorStatistics> startupGcStatistics = ImmutableMap.of();
private long serverNormalOperationStartTime;
private final AtomicBoolean enabled = new AtomicBoolean(false);
@@ -111,6 +120,8 @@ public class SparkPlatform {
this.httpClient = new OkHttpClient();
this.bytebinClient = new BytebinClient(this.httpClient, bytebinUrl, "spark-plugin");
+ this.disableResponseBroadcast = this.configuration.getBoolean("disableResponseBroadcast", false);
+
this.commandModules = ImmutableList.of(
new SamplerModule(),
new HealthModule(),
@@ -131,7 +142,12 @@ public class SparkPlatform {
this.tickHook = plugin.createTickHook();
this.tickReporter = plugin.createTickReporter();
- this.tickStatistics = this.tickHook != null ? new TickStatistics() : null;
+ this.tickStatistics = this.tickHook != null || this.tickReporter != null ? new TickStatistics() : null;
+
+ PlayerPingProvider pingProvider = plugin.createPlayerPingProvider();
+ this.pingStatistics = pingProvider != null ? new PingStatistics(pingProvider) : null;
+
+ this.statisticsProvider = new PlatformStatisticsProvider(this);
}
public void enable() {
@@ -147,7 +163,11 @@ public class SparkPlatform {
this.tickReporter.addCallback(this.tickStatistics);
this.tickReporter.start();
}
+ if (this.pingStatistics != null) {
+ this.pingStatistics.start();
+ }
CpuMonitor.ensureMonitoring();
+ NetworkMonitor.ensureMonitoring();
// poll startup GC statistics after plugins & the world have loaded
this.plugin.executeAsync(() -> {
@@ -167,6 +187,9 @@ public class SparkPlatform {
if (this.tickReporter != null) {
this.tickReporter.close();
}
+ if (this.pingStatistics != null) {
+ this.pingStatistics.close();
+ }
for (CommandModule module : this.commandModules) {
module.close();
@@ -198,6 +221,10 @@ public class SparkPlatform {
return this.bytebinClient;
}
+ public boolean shouldBroadcastResponse() {
+ return !this.disableResponseBroadcast;
+ }
+
public List<Command> getCommands() {
return this.commands;
}
@@ -214,6 +241,10 @@ public class SparkPlatform {
return this.tickReporter;
}
+ public PlatformStatisticsProvider getStatisticsProvider() {
+ return this.statisticsProvider;
+ }
+
public ClassSourceLookup createClassSourceLookup() {
return this.plugin.createClassSourceLookup();
}
@@ -222,6 +253,10 @@ public class SparkPlatform {
return this.tickStatistics;
}
+ public PingStatistics getPingStatistics() {
+ return this.pingStatistics;
+ }
+
public Map<String, GarbageCollectorStatistics> getStartupGcStatistics() {
return this.startupGcStatistics;
}
@@ -255,12 +290,62 @@ public class SparkPlatform {
}
public void executeCommand(CommandSender sender, String[] args) {
+ AtomicReference<Thread> executorThread = new AtomicReference<>();
+ AtomicReference<Thread> timeoutThread = new AtomicReference<>();
+ AtomicBoolean completed = new AtomicBoolean(false);
+
+ // execute the command
this.plugin.executeAsync(() -> {
+ executorThread.set(Thread.currentThread());
this.commandExecuteLock.lock();
try {
executeCommand0(sender, args);
+ } catch (Exception e) {
+ this.plugin.log(Level.SEVERE, "Exception occurred whilst executing a spark command");
+ e.printStackTrace();
} finally {
this.commandExecuteLock.unlock();
+ executorThread.set(null);
+ completed.set(true);
+
+ Thread timeout = timeoutThread.get();
+ if (timeout != null) {
+ timeout.interrupt();
+ }
+ }
+ });
+
+ // schedule a task to detect timeouts
+ this.plugin.executeAsync(() -> {
+ timeoutThread.set(Thread.currentThread());
+ try {
+ for (int i = 1; i <= 3; i++) {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+
+ if (completed.get()) {
+ return;
+ }
+
+ Thread executor = executorThread.get();
+ if (executor == null) {
+ getPlugin().log(Level.WARNING, "A command execution has not completed after " +
+ (i * 5) + " seconds but there is no executor present. Perhaps the executor shutdown?");
+
+ } else {
+ String stackTrace = Arrays.stream(executor.getStackTrace())
+ .map(el -> " " + el.toString())
+ .collect(Collectors.joining("\n"));
+
+ getPlugin().log(Level.WARNING, "A command execution has not completed after " +
+ (i * 5) + " seconds, it might be stuck. Trace: \n" + stackTrace);
+ }
+ }
+ } finally {
+ timeoutThread.set(null);
}
});
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java b/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java
index f312916..b817df1 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java
@@ -22,7 +22,9 @@ package me.lucko.spark.common;
import me.lucko.spark.api.Spark;
import me.lucko.spark.common.command.sender.CommandSender;
+import me.lucko.spark.common.monitor.ping.PlayerPingProvider;
import me.lucko.spark.common.platform.PlatformInfo;
+import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider;
import me.lucko.spark.common.sampler.ThreadDumper;
import me.lucko.spark.common.tick.TickHook;
import me.lucko.spark.common.tick.TickReporter;
@@ -121,6 +123,26 @@ public interface SparkPlugin {
}
/**
+ * Creates a player ping provider function.
+ *
+ * <p>Returns {@code null} if the platform does not support querying player pings</p>
+ *
+ * @return the player ping provider function
+ */
+ default PlayerPingProvider createPlayerPingProvider() {
+ return null;
+ }
+
+ /**
+ * Creates a server config provider.
+ *
+ * @return the server config provider function
+ */
+ default ServerConfigProvider createServerConfigProvider() {
+ return ServerConfigProvider.NO_OP;
+ }
+
+ /**
* Gets information for the platform.
*
* @return information about the platform
diff --git a/spark-common/src/main/java/me/lucko/spark/common/api/GarbageCollectorInfo.java b/spark-common/src/main/java/me/lucko/spark/common/api/GarbageCollectorInfo.java
index 8d289aa..fc14c67 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/api/GarbageCollectorInfo.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/api/GarbageCollectorInfo.java
@@ -36,10 +36,8 @@ public class GarbageCollectorInfo implements GarbageCollector {
this.name = name;
this.totalCollections = stats.getCollectionCount();
this.totalTime = stats.getCollectionTime();
-
- double totalTimeDouble = this.totalTime;
- this.averageTime = this.totalCollections == 0 ? 0 : totalTimeDouble / this.totalCollections;
- this.averageFrequency = this.totalCollections == 0 ? 0 : (long) ((serverUptime - totalTimeDouble) / this.totalCollections);
+ this.averageTime = stats.getAverageCollectionTime();
+ this.averageFrequency = stats.getAverageCollectionFrequency(serverUptime);
}
@Override
diff --git a/spark-common/src/main/java/me/lucko/spark/common/command/CommandResponseHandler.java b/spark-common/src/main/java/me/lucko/spark/common/command/CommandResponseHandler.java
index a9e2229..d1481bd 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/command/CommandResponseHandler.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/command/CommandResponseHandler.java
@@ -88,12 +88,20 @@ public class CommandResponseHandler {
}
public void broadcast(Component message) {
- allSenders(sender -> sender.sendMessage(message));
+ if (this.platform.shouldBroadcastResponse()) {
+ allSenders(sender -> sender.sendMessage(message));
+ } else {
+ reply(message);
+ }
}
public void broadcast(Iterable<Component> message) {
- Component joinedMsg = Component.join(JoinConfiguration.separator(Component.newline()), message);
- allSenders(sender -> sender.sendMessage(joinedMsg));
+ if (this.platform.shouldBroadcastResponse()) {
+ Component joinedMsg = Component.join(JoinConfiguration.separator(Component.newline()), message);
+ allSenders(sender -> sender.sendMessage(joinedMsg));
+ } else {
+ reply(message);
+ }
}
public void replyPrefixed(Component message) {
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 51fa905..16eadc8 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
@@ -20,8 +20,6 @@
package me.lucko.spark.common.command.modules;
-import com.google.common.base.Strings;
-
import me.lucko.spark.common.SparkPlatform;
import me.lucko.spark.common.command.Arguments;
import me.lucko.spark.common.command.Command;
@@ -30,25 +28,29 @@ import me.lucko.spark.common.command.CommandResponseHandler;
import me.lucko.spark.common.command.sender.CommandSender;
import me.lucko.spark.common.command.tabcomplete.TabCompleter;
import me.lucko.spark.common.monitor.cpu.CpuMonitor;
+import me.lucko.spark.common.monitor.disk.DiskUsage;
+import me.lucko.spark.common.monitor.net.Direction;
+import me.lucko.spark.common.monitor.net.NetworkInterfaceAverages;
+import me.lucko.spark.common.monitor.net.NetworkMonitor;
+import me.lucko.spark.common.monitor.ping.PingStatistics;
+import me.lucko.spark.common.monitor.ping.PingSummary;
import me.lucko.spark.common.monitor.tick.TickStatistics;
import me.lucko.spark.common.util.FormatUtil;
import me.lucko.spark.common.util.RollingAverage;
+import me.lucko.spark.common.util.StatisticFormatter;
import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.TextComponent;
-import net.kyori.adventure.text.format.TextColor;
-import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
import java.lang.management.MemoryUsage;
-import java.nio.file.FileStore;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
import java.util.function.Consumer;
import static net.kyori.adventure.text.Component.empty;
@@ -60,13 +62,10 @@ import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
import static net.kyori.adventure.text.format.NamedTextColor.RED;
import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
-import static net.kyori.adventure.text.format.NamedTextColor.YELLOW;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class HealthModule implements CommandModule {
- private static final double MSPT_95_PERCENTILE = 0.95d;
-
@Override
public void registerCommands(Consumer<Command> consumer) {
consumer.accept(Command.builder()
@@ -77,10 +76,19 @@ public class HealthModule implements CommandModule {
);
consumer.accept(Command.builder()
+ .aliases("ping")
+ .argumentUsage("player", "username")
+ .executor(HealthModule::ping)
+ .tabCompleter((platform, sender, arguments) -> TabCompleter.completeForOpts(arguments, "--player"))
+ .build()
+ );
+
+ consumer.accept(Command.builder()
.aliases("healthreport", "health", "ht")
.argumentUsage("memory", null)
+ .argumentUsage("network", null)
.executor(HealthModule::healthReport)
- .tabCompleter((platform, sender, arguments) -> TabCompleter.completeForOpts(arguments, "--memory"))
+ .tabCompleter((platform, sender, arguments) -> TabCompleter.completeForOpts(arguments, "--memory", "--network"))
.build()
);
}
@@ -91,11 +99,11 @@ public class HealthModule implements CommandModule {
resp.replyPre