Skip to content

Commit

Permalink
Merge pull request #32 from Redmart/feature/load-agent-dynamically
Browse files Browse the repository at this point in the history
Loading agent dynamically after VM has started
  • Loading branch information
ajsquared committed Jan 24, 2016
2 parents 2a350cc + 054c298 commit 378ab7a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ Every pull request will be built with [Travis CI](https://travis-ci.org/etsy/sta
- Joe Meissler [stickperson](https://github.com/stickperson)
- Ben Darfler [bdarfler](https://github.com/bdarfler)
- Ihor Bobak [ibobak](https://github.com/ibobak)
- Jeff Fenchel [jfenc91](https://github.com/jfenc91)
- Jeff Fenchel [jfenc91](https://github.com/jfenc91)
- Alejandro Rivera [AlejandroRivera](https://github.com/AlejandroRivera)
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ The profiler is enabled using the JVM's `-javaagent` argument. You are required
-javaagent:/usr/etsy/statsd-jvm-profiler/statsd-jvm-profiler.jar=server=hostname,port=num
```

The profiler can also be loaded dynamically (after the JVM has already started), but this technique requires relying on Sun's `tools.jar`, meaning it's an implementation-specific solution that might not work for all JVMs. For more information see the [Dynamic Loading section](#dynamic-loading-of-agent).

An example of setting up Cascading/Scalding jobs to use the profiler can be found in the `example` directory.

### Global Options
Expand Down Expand Up @@ -97,6 +99,34 @@ You can disable either the memory or CPU metrics using the `profilers` argument:

The `visualization` directory contains some utilities for visualizing the output of the profiler.

## Dynamic Loading of Agent

1. Make sure you have the `tools.jar` available in your classpath during compilation and runtime. This JAR is usually found in the JAVA_HOME directory under the `/lib` folder for Oracle Java installations.
2. Make sure the `jvm-profiler` JAR is available during runtime.
3. During your application boostrap process, do the following:

```scala
val jarPath: String = s"$ABSOLUTE_PATH_TO/com.etsy.statsd-jvm-profiler-$VERSION.jar"
val agentArgs: String = s"server=$SERVER,port=$PORT"
attachJvmAgent(jarPath, agentArgs)

def attachJvmAgent(profilerJarPath: String, agentArgs: String): Unit = {
val nameOfRunningVM: String = java.lang.management.ManagementFactory.getRuntimeMXBean.getName
val p: Integer = nameOfRunningVM.indexOf('@')
val pid: String = nameOfRunningVM.substring(0, p)

try {
val vm: com.sun.tools.attach.VirtualMachine = com.sun.tools.attach.VirtualMachine.attach(pid)
vm.loadAgent(profilerJarPath, agentArgs)
vm.detach()
LOGGER.info("Dynamically loaded StatsD JVM Profiler Agent...");
} catch {
case e: Exception => LOGGER.warn(s"Could not dynamically load StatsD JVM Profiler Agent ($profilerJarPath)", e);
}
}
```


## Contributing
Contributions are highly encouraged! Check out [the contribution guidlines](https://github.com/etsy/statsd-jvm-profiler/blob/master/CONTRIBUTING.md).

Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Premain-Class>com.etsy.statsd.profiler.Agent</Premain-Class>
<Agent-Class>com.etsy.statsd.profiler.Agent</Agent-Class>
</manifestEntries>
</transformer>
</transformers>
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/etsy/statsd/profiler/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ private Agent() { }

static AtomicReference<Boolean> isRunning = new AtomicReference<>(true);
static LinkedList<String> errors = new LinkedList<>();

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

/**
* Start the profiler
*
Expand Down

0 comments on commit 378ab7a

Please sign in to comment.