aboutsummaryrefslogtreecommitdiff
path: root/spark-common
diff options
context:
space:
mode:
Diffstat (limited to 'spark-common')
-rw-r--r--spark-common/build.gradle39
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java118
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java45
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/Arguments.java11
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/Command.java58
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/ActivityLogModule.java1
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/GcMonitoringModule.java22
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/HeapAnalysisModule.java4
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/SamplerModule.java241
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/LinuxProc.java (renamed from spark-common/src/main/java/me/lucko/spark/common/util/LinuxProc.java)9
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/WindowsWmic.java74
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuInfo.java13
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/memory/MemoryInfo.java2
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/net/NetworkInterfaceInfo.java2
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/os/OperatingSystemInfo.java86
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/MetadataProvider.java (renamed from spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadNodeOrder.java)35
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/PlatformStatisticsProvider.java24
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/ConfigParser.java48
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/ExcludedConfigFilter.java (renamed from spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java)57
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/PropertiesConfigParser.java (renamed from spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/PropertiesFileReader.java)29
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/ServerConfigProvider.java69
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/AbstractChunkInfo.java55
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/AsyncWorldInfoProvider.java90
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/ChunkInfo.java44
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/CountMap.java110
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldInfoProvider.java104
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldStatisticsProvider.java189
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java99
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/BackgroundSamplerManager.java115
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java17
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java29
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerContainer.java76
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerSettings.java61
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadDumper.java24
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/AbstractDataAggregator.java6
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/DataAggregator.java8
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncDataAggregator.java4
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncProfilerAccess.java58
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncProfilerJob.java276
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncSampler.java273
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/JfrParsingException.java27
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/ProfileSegment.java50
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/jfr/Dictionary.java4
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/jfr/JfrReader.java4
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaDataAggregator.java7
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java85
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/SimpleDataAggregator.java4
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/TickedDataAggregator.java36
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/node/AbstractNode.java75
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/node/StackTraceNode.java79
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/node/ThreadNode.java166
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/source/ClassSourceLookup.java462
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/source/SourceMetadata.java81
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProfilingWindowUtils.java70
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProtoTimeEncoder.java93
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/window/WindowStatisticsCollector.java287
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java75
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/ClassSourceLookup.java241
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/Compression.java60
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/Configuration.java70
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/FormatUtil.java20
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/IndexedListBuilder.java (renamed from spark-common/src/main/java/me/lucko/spark/common/util/AbstractHttpClient.java)33
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/SparkPlaceholder.java191
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/TemporaryFiles.java81
-rw-r--r--spark-common/src/main/proto/spark/spark.proto42
-rw-r--r--spark-common/src/main/proto/spark/spark_sampler.proto29
-rwxr-xr-xspark-common/src/main/resources/spark/linux/aarch64/libasyncProfiler.sobin328432 -> 343408 bytes
-rwxr-xr-xspark-common/src/main/resources/spark/linux/amd64-musl/libasyncProfiler.sobin0 -> 317560 bytes
-rwxr-xr-xspark-common/src/main/resources/spark/linux/amd64/libasyncProfiler.sobin342239 -> 361312 bytes
-rwxr-xr-xspark-common/src/main/resources/spark/macos/libasyncProfiler.sobin688400 -> 724576 bytes
70 files changed, 3975 insertions, 1022 deletions
diff --git a/spark-common/build.gradle b/spark-common/build.gradle
index 554eec2..c3d960d 100644
--- a/spark-common/build.gradle
+++ b/spark-common/build.gradle
@@ -1,29 +1,37 @@
+import org.cadixdev.gradle.licenser.LicenseExtension
+
plugins {
- id 'com.google.protobuf' version '0.8.16'
+ id 'com.google.protobuf' version '0.9.1'
}
license {
exclude '**/sampler/async/jfr/**'
}
+extensions.configure(LicenseExtension.class) {
+ it.exclude {
+ it.file.toString().startsWith(buildDir.toString())
+ }
+}
+
dependencies {
api project(':spark-api')
- implementation 'com.github.jvm-profiling-tools:async-profiler:v2.7'
+ implementation 'com.github.jvm-profiling-tools:async-profiler:v2.8.3'
implementation 'org.ow2.asm:asm:9.1'
- implementation 'com.google.protobuf:protobuf-javalite:3.15.6'
- implementation 'com.squareup.okhttp3:okhttp:3.14.1'
- implementation 'com.squareup.okio:okio:1.17.3'
+ implementation 'com.google.protobuf:protobuf-javalite:3.21.11'
implementation 'net.bytebuddy:byte-buddy-agent:1.11.0'
- implementation 'org.tukaani:xz:1.8'
- api('net.kyori:adventure-api:4.9.3') {
+ api('net.kyori:adventure-api:4.12.0') {
+ exclude(module: 'adventure-bom')
exclude(module: 'checker-qual')
exclude(module: 'annotations')
}
- api('net.kyori:adventure-text-serializer-gson:4.9.3') {
+ api('net.kyori:adventure-text-serializer-gson:4.12.0') {
+ exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
exclude(module: 'gson')
}
- api('net.kyori:adventure-text-serializer-legacy:4.9.3') {
+ api('net.kyori:adventure-text-serializer-legacy:4.12.0') {
+ exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
}
implementation('net.kyori:adventure-text-feature-pagination:4.0.0-SNAPSHOT') {
@@ -34,20 +42,9 @@ dependencies {
compileOnly 'org.checkerframework:checker-qual:3.8.0'
}
-processResources {
- from(sourceSets.main.resources.srcDirs) {
- include 'spark/linux/libasyncProfiler.so'
- include 'spark/macosx/libasyncProfiler.so'
- }
-}
-
protobuf {
protoc {
- if (System.getProperty("os.name") == "Mac OS X" && System.getProperty("os.arch") == "aarch64") {
- path = '/opt/homebrew/bin/protoc'
- } else {
- artifact = 'com.google.protobuf:protoc:3.15.6'
- }
+ artifact = 'com.google.protobuf:protoc:3.21.11'
}
generateProtoTasks {
all().each { task ->
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 0ef4556..dae04ff 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
@@ -45,17 +45,18 @@ 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.sampler.BackgroundSamplerManager;
+import me.lucko.spark.common.sampler.SamplerContainer;
+import me.lucko.spark.common.sampler.source.ClassSourceLookup;
import me.lucko.spark.common.tick.TickHook;
import me.lucko.spark.common.tick.TickReporter;
import me.lucko.spark.common.util.BytebinClient;
-import me.lucko.spark.common.util.ClassSourceLookup;
import me.lucko.spark.common.util.Configuration;
import me.lucko.spark.common.util.TemporaryFiles;
+import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
-import okhttp3.OkHttpClient;
-
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -64,6 +65,7 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -74,13 +76,11 @@ import java.util.stream.Collectors;
import static net.kyori.adventure.text.Component.space;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
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.TextDecoration.BOLD;
-import static net.kyori.adventure.text.format.TextDecoration.UNDERLINED;
/**
* Abstract spark implementation used by all platforms.
@@ -91,15 +91,17 @@ public class SparkPlatform {
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
private final SparkPlugin plugin;
+ private final TemporaryFiles temporaryFiles;
private final Configuration configuration;
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);
private final ActivityLog activityLog;
+ private final SamplerContainer samplerContainer;
+ private final BackgroundSamplerManager backgroundSamplerManager;
private final TickHook tickHook;
private final TickReporter tickReporter;
private final TickStatistics tickStatistics;
@@ -112,13 +114,12 @@ public class SparkPlatform {
public SparkPlatform(SparkPlugin plugin) {
this.plugin = plugin;
+ this.temporaryFiles = new TemporaryFiles(this.plugin.getPluginDirectory().resolve("tmp"));
this.configuration = new Configuration(this.plugin.getPluginDirectory().resolve("config.json"));
this.viewerUrl = this.configuration.getString("viewerUrl", "https://spark.lucko.me/");
String bytebinUrl = this.configuration.getString("bytebinUrl", "https://bytebin.lucko.me/");
-
- this.httpClient = new OkHttpClient();
- this.bytebinClient = new BytebinClient(this.httpClient, bytebinUrl, "spark-plugin");
+ this.bytebinClient = new BytebinClient(bytebinUrl, "spark-plugin");
this.disableResponseBroadcast = this.configuration.getBoolean("disableResponseBroadcast", false);
@@ -140,6 +141,9 @@ public class SparkPlatform {
this.activityLog = new ActivityLog(plugin.getPluginDirectory().resolve("activity.json"));
this.activityLog.load();
+ this.samplerContainer = new SamplerContainer();
+ this.backgroundSamplerManager = new BackgroundSamplerManager(this, this.configuration);
+
this.tickHook = plugin.createTickHook();
this.tickReporter = plugin.createTickReporter();
this.tickStatistics = this.tickHook != null || this.tickReporter != null ? new TickStatistics() : null;
@@ -178,6 +182,8 @@ public class SparkPlatform {
SparkApi api = new SparkApi(this);
this.plugin.registerApi(api);
SparkApi.register(api);
+
+ this.backgroundSamplerManager.initialise();
}
public void disable() {
@@ -195,20 +201,21 @@ public class SparkPlatform {
module.close();
}
- SparkApi.unregister();
+ this.samplerContainer.close();
- TemporaryFiles.deleteTemporaryFiles();
+ SparkApi.unregister();
- // shutdown okhttp
- // see: https://github.com/square/okhttp/issues/4029
- this.httpClient.dispatcher().executorService().shutdown();
- this.httpClient.connectionPool().evictAll();
+ this.temporaryFiles.deleteTemporaryFiles();
}
public SparkPlugin getPlugin() {
return this.plugin;
}
+ public TemporaryFiles getTemporaryFiles() {
+ return this.temporaryFiles;
+ }
+
public Configuration getConfiguration() {
return this.configuration;
}
@@ -233,6 +240,14 @@ public class SparkPlatform {
return this.activityLog;
}
+ public SamplerContainer getSamplerContainer() {
+ return this.samplerContainer;
+ }
+
+ public BackgroundSamplerManager getBackgroundSamplerManager() {
+ return this.backgroundSamplerManager;
+ }
+
public TickHook getTickHook() {
return this.tickHook;
}
@@ -366,14 +381,15 @@ public class SparkPlatform {
.append(text("v" + getPlugin().getVersion(), GRAY))
.build()
);
+
+ String helpCmd = "/" + getPlugin().getCommandName() + " help";
resp.replyPrefixed(text()
.color(GRAY)
- .append(text("Use "))
+ .append(text("Run "))
.append(text()
- .content("/" + getPlugin().getCommandName() + " help")
+ .content(helpCmd)
.color(WHITE)
- .decoration(UNDERLINED, true)
- .clickEvent(ClickEvent.runCommand("/" + getPlugin().getCommandName() + " help"))
+ .clickEvent(ClickEvent.runCommand(helpCmd))
.build()
)
.append(text(" to view usage information."))
@@ -389,7 +405,7 @@ public class SparkPlatform {
if (command.aliases().contains(alias)) {
resp.setCommandPrimaryAlias(command.primaryAlias());
try {
- command.executor().execute(this, sender, resp, new Arguments(rawArgs));
+ command.executor().execute(this, sender, resp, new Arguments(rawArgs, command.allowSubCommand()));
} catch (Arguments.ParseException e) {
resp.replyPrefixed(text(e.getMessage(), RED));
}
@@ -437,35 +453,53 @@ public class SparkPlatform {
);
for (Command command : commands) {
String usage = "/" + getPlugin().getCommandName() + " " + command.primaryAlias();
- ClickEvent clickEvent = ClickEvent.suggestCommand(usage);
- sender.reply(text()
- .append(text(">", GOLD, BOLD))
- .append(space())
- .append(text().content(usage).color(GRAY).clickEvent(clickEvent).build())
- .build()
- );
- for (Command.ArgumentInfo arg : command.arguments()) {
- if (arg.requiresParameter()) {
+
+ if (command.allowSubCommand()) {
+ Map<String, List<Command.ArgumentInfo>> argumentsBySubCommand = command.arguments().stream()
+ .collect(Collectors.groupingBy(Command.ArgumentInfo::subCommandName, LinkedHashMap::new, Collectors.toList()));
+
+ argumentsBySubCommand.forEach((subCommand, arguments) -> {
+ String subCommandUsage = usage + " " + subCommand;
+
sender.reply(text()
- .content(" ")
- .append(text("[", DARK_GRAY))
- .append(text("--" + arg.argumentName(), GRAY))
+ .append(text(">", GOLD, BOLD))
.append(space())
- .append(text("<" + arg.parameterDescription() + ">", DARK_GRAY))
- .append(text("]", DARK_GRAY))
- .build()
- );
- } else {
- sender.reply(text()
- .content(" ")
- .append(text("[", DARK_GRAY))
- .append(text("--" + arg.argumentName(), GRAY))
- .append(text("]", DARK_GRAY))
+ .append(text().content(subCommandUsage).color(GRAY).clickEvent(ClickEvent.suggestCommand(subCommandUsage)).build())
.build()
);
+
+ for (Command.ArgumentInfo arg : arguments) {
+ if (arg.argumentName().isEmpty()) {
+ continue;
+ }
+ sender.reply(arg.toComponent(" "));
+ }
+ });
+ } else {
+ sender.reply(text()
+ .append(text(">", GOLD, BOLD))
+ .append(space())
+ .append(text().content(usage).color(GRAY).clickEvent(ClickEvent.suggestCommand(usage)).build())
+ .build()
+ );
+
+ for (Command.ArgumentInfo arg : command.arguments()) {
+ sender.reply(arg.toComponent(" "));
}
}
}
+
+ sender.reply(Component.empty());
+ sender.replyPrefixed(text()
+ .append(text("For full usage information, please go to: "))
+ .append(text()
+ .content("https://spark.lucko.me/docs/Command-Usage")
+ .color(WHITE)
+ .clickEvent(ClickEvent.openUrl("https://spark.lucko.me/docs/Command-Usage"))
+ .build()
+ )
+ .build()
+ );
}
}
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 b817df1..b7aef2a 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
@@ -23,14 +23,19 @@ 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.MetadataProvider;
import me.lucko.spark.common.platform.PlatformInfo;
import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider;
+import me.lucko.spark.common.platform.world.WorldInfoProvider;
import me.lucko.spark.common.sampler.ThreadDumper;
+import me.lucko.spark.common.sampler.source.ClassSourceLookup;
+import me.lucko.spark.common.sampler.source.SourceMetadata;
import me.lucko.spark.common.tick.TickHook;
import me.lucko.spark.common.tick.TickReporter;
-import me.lucko.spark.common.util.ClassSourceLookup;
import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Collections;
import java.util.logging.Level;
import java.util.stream.Stream;
@@ -75,6 +80,15 @@ public interface SparkPlugin {
void executeAsync(Runnable task);
/**
+ * Executes the given {@link Runnable} on the server/client main thread.
+ *
+ * @param task the task
+ */
+ default void executeSync(Runnable task) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Print to the plugin logger.
*
* @param level the log level
@@ -123,6 +137,15 @@ public interface SparkPlugin {
}
/**