Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attach the Agent to a running process #13

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,31 @@ methodWithArgs
TraceAgent (trace_retval): `public int net.test.TestClass2nd.methodWithArgs(java.lang.String,int) returns with 12
```

## Attaching Agent to running java process (hotswap)

The agent can be attached to already running java process.

To start trace on a running process one can use:

```
$ java -cp <JAVA HOME>/lib/tools.jar:target/trace-agent-1.0-SNAPSHOT.jar net.test.AgentLoader target/trace-agent-1.0-SNAPSHOT.jar <PID of process>

The above command attaches to the running java process and installs the actions. The instrumentaion messages will start showing in the processes logs/stdout as per the configuration.

For example when attaching to a Spark executor using its pid:
...
21/03/17 13:30:52 INFO yarn.Client: Application report for application_1614936955492_0466 (state: ACCEPTED)
TraceAgent is initializing
TraceAgent tries to install actions: [{actionId='trace_args', classMatcher='REGEXP(org\.apache\.spark\.sql\.execution\.SparkStratgies.*)'}, ...]
TraceAgent installed actions successfully
...
21/03/17 14:18:33 INFO yarn.Client: Application report for application_1614936955492_0470 (state: RUNNING)
21/03/17 14:18:34 INFO util.Utils: Using initial executors = 0, max of spark.dynamicAllocation.initialExecutors, spark.dynamicAllocation.minExecutors and spark.executor.instances
TraceAgent (timing): `public final void org.apache.spark.SparkContext$$anonfun$23.apply(org.apache.spark.ExecutorAllocationManager)` took 22 ms
TraceAgent (timing): `public final void org.apache.spark.SparkContext$$anonfun$24.apply(org.apache.spark.ContextCleaner)` took 2 ms
....

```

## The config format

Expand Down Expand Up @@ -230,6 +255,7 @@ In this case all the rules are used from both the internal and external action f
In distributed environment when external action file is used you should take care on each node the action file is really can be accessed using the path.
Otherwise the error is logged but the application continues: "TraceAgent does not find the external action file: <file>".


# The counter action

This action can be used to count the number of of method calls. It has one parameter `count_frequency` which specifies after how many calls there will be a printout.
Expand Down
9 changes: 9 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<premain>net.test.TraceAgent</premain>
<java.version>1.8</java.version>
<sun.tools.version>1.8.0</sun.tools.version>
</properties>

<dependencies>
Expand All @@ -29,6 +31,13 @@
<artifactId>byte-buddy</artifactId>
<version>1.10.10</version>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${sun.tools.version}</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>

<build>
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/net/test/AgentLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net.test;

import com.sun.tools.attach.VirtualMachine;

import java.io.File;
import java.util.Optional;

/** Agent Loader to attach to a PID. */
public class AgentLoader {

public static void main(String[] args) {
File agentFile = new File(args[0]);

System.out.println(agentFile.getAbsolutePath());
try {
String pid = args[1];
System.out.println("Attaching to target JVM with PID: " + pid);
VirtualMachine jvm = VirtualMachine.attach(pid);
jvm.loadAgent(agentFile.getAbsolutePath());
jvm.detach();
System.out.println("Succefully attached to target JVM and loaded Java agent");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/net/test/TraceAgent.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ private void installActions(List<TraceAction> actions) {
final Object interceptor = action.getActionInterceptor(traceAgentArgs);
if (interceptor != null) {
new AgentBuilder.Default()
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
.type(action.getClassMatcher())
.transform(
(builder, type, classLoader, module) ->
Expand Down Expand Up @@ -117,4 +118,8 @@ public static void premain(String arguments, Instrumentation instrumentation) {
TraceAgent traceAgent = new TraceAgent(traceAgentArgs, instrumentation);
traceAgent.install();
}

public static void agentmain(String arguments, Instrumentation instrumentation) {
premain(arguments, instrumentation);
}
}