diff --git a/agent/pom.xml b/agent/pom.xml
new file mode 100644
index 0000000..f5b0d24
--- /dev/null
+++ b/agent/pom.xml
@@ -0,0 +1,191 @@
+
+
+ 4.0.0
+
+ io.github.dpsoft
+ ap-agent
+ 0.1.2-SNAPSHOT
+ jar
+
+
+ 2.9-4
+ 0.10.3
+ 1.4.2
+ 2.5.0
+ 0.0.2-SNAPSHOT
+ 11
+ 11
+ 11
+
+
+
+
+ oss-snapshots
+ Oss Snapshots
+ https://s01.oss.sonatype.org/content/repositories/snapshots/
+
+
+ maven-central
+ Maven central
+ https://repo.maven.apache.org/maven2/
+
+
+ local
+ Maven local
+ file:////home/diego/.m2/repository
+
+
+
+
+
+ me.bechberger
+ ap-loader-all
+ ${me.bechberger.ap-loader.version}
+
+
+ io.vavr
+ vavr
+ ${io.vavr.version}
+
+
+ com.typesafe
+ config
+ ${com.typesafe.config.version}
+
+
+ org.tinylog
+ tinylog-api
+ ${org.tinylog.version}
+
+
+ org.tinylog
+ tinylog-impl
+ ${org.tinylog.version}
+
+
+ me.bechberger
+ jfrtofp
+ ${me.bechberger.version}
+
+
+ io.github.dpsoft
+ context-api
+ 0.1.2-SNAPSHOT
+ provided
+
+
+
+
+
+ src/main/resources
+ true
+
+ **/build-info.properties
+
+
+
+ src/main/resources
+ false
+
+ **/build-info.properties
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.4.1
+
+
+ package
+
+ shade
+
+
+ true
+ ${project.build.directory}/dependency-reduced-pom.xml
+ true
+
+
+ org.codehaus.mojo
+
+
+
+
+
+ io.github.dpsoft.ap.Agent
+
+
+
+
+
+
+ *:*
+
+ META-INF/maven/**
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+ META-INF/*.md
+ META-INF/LICENSE
+
+
+
+
+
+ com.typesafe.config
+ io.github.dpsoft.ap.libs.com.typesafe.config
+
+
+ io.vavr
+ io.github.dpsoft.ap.libs.io.vavr
+
+
+ org.tinylog
+ io.github.dpsoft.ap.libs.org.tinylog
+
+
+ one
+ io.github.dpsoft.ap.libs.one
+
+
+ dev.dirs
+ io.github.dpsoft.ap.libs.dev.dirs
+
+
+ me.bechberger
+ io.github.dpsoft.ap.libs.me.bechberger
+
+
+ kotlin
+ io.github.dpsoft.ap.libs.kotlin
+
+
+ kotlinx
+ io.github.dpsoft.ap.libs.kotlinx
+
+
+ org.jetbrains
+ io.github.dpsoft.ap.libs.org.jetbrains
+
+
+ org.jline
+ io.github.dpsoft.ap.libs.org.jline
+
+
+ org.objectweb
+ io.github.dpsoft.ap.libs.org.objectweb
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/io/github/dpsoft/ap/Agent.java b/agent/src/main/java/io/github/dpsoft/ap/Agent.java
similarity index 97%
rename from src/main/java/io/github/dpsoft/ap/Agent.java
rename to agent/src/main/java/io/github/dpsoft/ap/Agent.java
index 442241f..179bb63 100644
--- a/src/main/java/io/github/dpsoft/ap/Agent.java
+++ b/agent/src/main/java/io/github/dpsoft/ap/Agent.java
@@ -1,14 +1,14 @@
package io.github.dpsoft.ap;
-import io.github.dpsoft.ap.handler.AsyncProfilerHandler;
import io.github.dpsoft.ap.util.Banner;
import io.github.dpsoft.ap.util.Runner;
import io.github.dpsoft.ap.util.Server;
+import io.github.dpsoft.ap.handler.AsyncProfilerHandler;
import java.lang.instrument.Instrumentation;
public final class Agent {
- public static void premain(String args, Instrumentation inst) {
+ public static void premain(String args, Instrumentation instrumentation) {
Runner.runWith((profiler, configuration) -> {
Banner.show(configuration);
diff --git a/src/main/java/io/github/dpsoft/ap/command/Command.java b/agent/src/main/java/io/github/dpsoft/ap/command/Command.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/command/Command.java
rename to agent/src/main/java/io/github/dpsoft/ap/command/Command.java
diff --git a/src/main/java/io/github/dpsoft/ap/config/AgentConfiguration.java b/agent/src/main/java/io/github/dpsoft/ap/config/AgentConfiguration.java
similarity index 99%
rename from src/main/java/io/github/dpsoft/ap/config/AgentConfiguration.java
rename to agent/src/main/java/io/github/dpsoft/ap/config/AgentConfiguration.java
index 050f09f..2a19f2f 100644
--- a/src/main/java/io/github/dpsoft/ap/config/AgentConfiguration.java
+++ b/agent/src/main/java/io/github/dpsoft/ap/config/AgentConfiguration.java
@@ -14,6 +14,7 @@ public final class AgentConfiguration {
public final Handler handler;
public final boolean showBanner;
+
private AgentConfiguration(Config config) {
this.server = new Server(config);
this.handler = new Handler(config);
diff --git a/agent/src/main/java/io/github/dpsoft/ap/context/APContextListener.java b/agent/src/main/java/io/github/dpsoft/ap/context/APContextListener.java
new file mode 100644
index 0000000..1369390
--- /dev/null
+++ b/agent/src/main/java/io/github/dpsoft/ap/context/APContextListener.java
@@ -0,0 +1,18 @@
+package io.github.dpsoft.ap.context;
+
+import io.github.dpsoft.ap.context.api.context.Context;
+import io.github.dpsoft.ap.context.api.storage.ContextStorageListener;
+
+/**
+ * This listener is used to store the current context id in AsyncProfiler and restore it when the context is restored.
+ */
+public final class APContextListener implements ContextStorageListener {
+ @Override
+ public void onContextStored(Context context) {
+ System.out.println("stored::AsyncProfiler.setContextId(" + context.get(Context.ContextID) + ")");
+ }
+ @Override
+ public void onContextRestored(Context context) {
+ System.out.println("restored::AsyncProfiler.setContextId(" + context.get(Context.ContextID) + ")");
+ }
+}
diff --git a/src/main/java/io/github/dpsoft/ap/converters/experimental/hotcold/HotColdFlameGraph.java b/agent/src/main/java/io/github/dpsoft/ap/converters/experimental/hotcold/HotColdFlameGraph.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/converters/experimental/hotcold/HotColdFlameGraph.java
rename to agent/src/main/java/io/github/dpsoft/ap/converters/experimental/hotcold/HotColdFlameGraph.java
diff --git a/src/main/java/io/github/dpsoft/ap/converters/experimental/hotcold/jfr2hotcoldflame.java b/agent/src/main/java/io/github/dpsoft/ap/converters/experimental/hotcold/jfr2hotcoldflame.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/converters/experimental/hotcold/jfr2hotcoldflame.java
rename to agent/src/main/java/io/github/dpsoft/ap/converters/experimental/hotcold/jfr2hotcoldflame.java
diff --git a/src/main/java/io/github/dpsoft/ap/converters/experimental/package-info.java b/agent/src/main/java/io/github/dpsoft/ap/converters/experimental/package-info.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/converters/experimental/package-info.java
rename to agent/src/main/java/io/github/dpsoft/ap/converters/experimental/package-info.java
diff --git a/src/main/java/io/github/dpsoft/ap/functions/Functions.java b/agent/src/main/java/io/github/dpsoft/ap/functions/Functions.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/functions/Functions.java
rename to agent/src/main/java/io/github/dpsoft/ap/functions/Functions.java
diff --git a/src/main/java/io/github/dpsoft/ap/handler/AsyncProfilerHandler.java b/agent/src/main/java/io/github/dpsoft/ap/handler/AsyncProfilerHandler.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/handler/AsyncProfilerHandler.java
rename to agent/src/main/java/io/github/dpsoft/ap/handler/AsyncProfilerHandler.java
diff --git a/src/main/java/io/github/dpsoft/ap/util/Banner.java b/agent/src/main/java/io/github/dpsoft/ap/util/Banner.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/util/Banner.java
rename to agent/src/main/java/io/github/dpsoft/ap/util/Banner.java
diff --git a/src/main/java/io/github/dpsoft/ap/util/BuildInfo.java b/agent/src/main/java/io/github/dpsoft/ap/util/BuildInfo.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/util/BuildInfo.java
rename to agent/src/main/java/io/github/dpsoft/ap/util/BuildInfo.java
diff --git a/src/main/java/io/github/dpsoft/ap/util/ProfilerExecutor.java b/agent/src/main/java/io/github/dpsoft/ap/util/ProfilerExecutor.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/util/ProfilerExecutor.java
rename to agent/src/main/java/io/github/dpsoft/ap/util/ProfilerExecutor.java
diff --git a/src/main/java/io/github/dpsoft/ap/util/Runner.java b/agent/src/main/java/io/github/dpsoft/ap/util/Runner.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/util/Runner.java
rename to agent/src/main/java/io/github/dpsoft/ap/util/Runner.java
diff --git a/src/main/java/io/github/dpsoft/ap/util/Server.java b/agent/src/main/java/io/github/dpsoft/ap/util/Server.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/util/Server.java
rename to agent/src/main/java/io/github/dpsoft/ap/util/Server.java
diff --git a/src/main/java/io/github/dpsoft/ap/util/StrSubstitutor.java b/agent/src/main/java/io/github/dpsoft/ap/util/StrSubstitutor.java
similarity index 100%
rename from src/main/java/io/github/dpsoft/ap/util/StrSubstitutor.java
rename to agent/src/main/java/io/github/dpsoft/ap/util/StrSubstitutor.java
diff --git a/src/main/java/one/converter/Arguments.java b/agent/src/main/java/one/converter/Arguments.java
similarity index 100%
rename from src/main/java/one/converter/Arguments.java
rename to agent/src/main/java/one/converter/Arguments.java
diff --git a/src/main/java/one/converter/CollapsedStacks.java b/agent/src/main/java/one/converter/CollapsedStacks.java
similarity index 100%
rename from src/main/java/one/converter/CollapsedStacks.java
rename to agent/src/main/java/one/converter/CollapsedStacks.java
diff --git a/agent/src/main/resources/META-INF/services/io.github.dpsoft.ap.context.api.storage.ContextStorageListener b/agent/src/main/resources/META-INF/services/io.github.dpsoft.ap.context.api.storage.ContextStorageListener
new file mode 100644
index 0000000..dc2b79c
--- /dev/null
+++ b/agent/src/main/resources/META-INF/services/io.github.dpsoft.ap.context.api.storage.ContextStorageListener
@@ -0,0 +1 @@
+io.github.dpsoft.ap.context.APContextListener
\ No newline at end of file
diff --git a/src/main/resources/banner.txt b/agent/src/main/resources/banner.txt
similarity index 100%
rename from src/main/resources/banner.txt
rename to agent/src/main/resources/banner.txt
diff --git a/src/main/resources/build-info.properties b/agent/src/main/resources/build-info.properties
similarity index 100%
rename from src/main/resources/build-info.properties
rename to agent/src/main/resources/build-info.properties
diff --git a/src/main/resources/reference.conf b/agent/src/main/resources/reference.conf
similarity index 85%
rename from src/main/resources/reference.conf
rename to agent/src/main/resources/reference.conf
index a573ad5..0c315ca 100644
--- a/src/main/resources/reference.conf
+++ b/agent/src/main/resources/reference.conf
@@ -9,6 +9,7 @@ ap-agent {
port: 8080
}
+ # The agent will recive requests on this path
handler {
go-mode: false
go-context: "/debug/pprof/profile"
diff --git a/src/main/resources/tinylog.properties b/agent/src/main/resources/tinylog.properties
similarity index 100%
rename from src/main/resources/tinylog.properties
rename to agent/src/main/resources/tinylog.properties
diff --git a/agent/src/test/resources/application.conf b/agent/src/test/resources/application.conf
new file mode 100644
index 0000000..1030035
--- /dev/null
+++ b/agent/src/test/resources/application.conf
@@ -0,0 +1,10 @@
+ap-agent {
+
+ #The agent banner will be shown on the console
+ show-banner = false
+
+ # Bytecode instrumentation is disabled by default
+ context-instrumenter {
+ enabled = true
+ }
+}
\ No newline at end of file
diff --git a/context-api/pom.xml b/context-api/pom.xml
new file mode 100644
index 0000000..9b1f36d
--- /dev/null
+++ b/context-api/pom.xml
@@ -0,0 +1,23 @@
+
+ 4.0.0
+
+ io.github.dpsoft
+ context-api
+ 0.1.2-SNAPSHOT
+ jar
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.9.2
+ test
+
+
+
+
+ 11
+ 11
+ 11
+
+
\ No newline at end of file
diff --git a/context-api/src/main/java/io/github/dpsoft/ap/context/api/ContextHandler.java b/context-api/src/main/java/io/github/dpsoft/ap/context/api/ContextHandler.java
new file mode 100644
index 0000000..0f53108
--- /dev/null
+++ b/context-api/src/main/java/io/github/dpsoft/ap/context/api/ContextHandler.java
@@ -0,0 +1,42 @@
+package io.github.dpsoft.ap.context.api;
+
+
+import io.github.dpsoft.ap.context.api.context.Context;
+import io.github.dpsoft.ap.context.api.storage.ContextStorage;
+import io.github.dpsoft.ap.context.api.storage.Storage;
+
+import java.util.function.Supplier;
+
+/**
+ * This class is used to store and retrieve the current context.
+ * Its implementation is Noop by default, but it can be replaced by an agent in runtime.
+ */
+public class ContextHandler {
+ /**
+ * Returns the current context.
+ */
+ public static Context currentContext() { return ContextStorage.INSTANCE.currentContext();}
+ /**
+ * Stores the current context and returns a scope that can be used to restore it.
+ */
+ public static Storage.Scope storeContext(Context context) { return ContextStorage.INSTANCE.storeContext(context);}
+
+ /**
+ * Runs the given supplier with the given context.
+ * The context is restored after the supplier returns.
+ */
+ public static T runWithContext(Context context, Supplier supplier) {
+ try (var ignored = storeContext(context)) {
+ return supplier.get();
+ }
+ }
+ /**
+ * Runs the given runnable with the given context.
+ * The context is restored after the runnable returns.
+ */
+ public static void runWitContext(Context context, Runnable runnable) {
+ try (var ignored = storeContext(context)) {
+ runnable.run();
+ }
+ }
+}
diff --git a/context-api/src/main/java/io/github/dpsoft/ap/context/api/context/Context.java b/context-api/src/main/java/io/github/dpsoft/ap/context/api/context/Context.java
new file mode 100644
index 0000000..7e929b1
--- /dev/null
+++ b/context-api/src/main/java/io/github/dpsoft/ap/context/api/context/Context.java
@@ -0,0 +1,66 @@
+package io.github.dpsoft.ap.context.api.context;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public final class Context {
+ public static final Context EMPTY = new Context(Map.of(), Labels.EMPTY);
+
+ public static final Context.Key ContextID = new Context.Key<>("contextId", 0L);
+
+ private final Map underlying;
+
+ private final Labels labels;
+
+ public static Context of(Labels labels) {
+ return new Context(Map.of(), labels);
+ }
+
+ public static Context of(Context.Key key, T value) {
+ return new Context(Map.of(key.name, value), Labels.EMPTY);
+ }
+
+ public static Context of(Context.Key key, T value, Labels labels) {
+ return new Context(Map.of(key.name, value), labels);
+ }
+
+ private Context(Map underling, Labels labels) {
+ this.labels = labels;
+ this.underlying = underling;
+ }
+
+ public Context withEntry(Context.Key key, T value) {
+ var x = new HashMap(underlying.size() + 1);
+ x.putAll(underlying);
+ x.put(key.name, value);
+
+ return new Context(x, labels);
+ }
+
+ public Context withTag(String key, String value) {
+ return new Context(underlying, labels.withLabel(key, value));
+ }
+
+ public Labels labels() {
+ return labels;
+ }
+
+
+ public T get(Context.Key key) {
+ return (T) underlying.getOrDefault(key.name, key.emptyValue);
+ }
+
+ public static Context.Key key(String name, T emptyValue) {
+ return new Context.Key<>(name, emptyValue);
+ }
+
+ public static class Key {
+ public final String name;
+ public final T emptyValue;
+
+ public Key(String name, T emptyValue) {
+ this.name = name;
+ this.emptyValue = emptyValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/context-api/src/main/java/io/github/dpsoft/ap/context/api/context/Labels.java b/context-api/src/main/java/io/github/dpsoft/ap/context/api/context/Labels.java
new file mode 100644
index 0000000..ff945e1
--- /dev/null
+++ b/context-api/src/main/java/io/github/dpsoft/ap/context/api/context/Labels.java
@@ -0,0 +1,62 @@
+package io.github.dpsoft.ap.context.api.context;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public final class Labels {
+ public final static Labels EMPTY = new Labels(Map.of());
+ private final Map underlying;
+
+ private Labels(Map underlying) {
+ this.underlying = underlying;
+ }
+
+ public static Labels from(Map underlying) {
+ return new Labels(underlying);
+ }
+
+ public static Labels of(String key, String value) {
+ return new Labels(Map.of(key, value));
+ }
+
+ public Labels withLabel(String key, String value) {
+ var mergedMap = new HashMap(underlying.size() + 1);
+ mergedMap.putAll(underlying);
+ mergedMap.put(key, value);
+
+ return new Labels(mergedMap);
+ }
+
+ public Set