Automatic setup with apm-agent-attach-standalone.jaredit

This installation method is experimental.

You can use the attacher as a standalone application on the command line or include it in your application to programmatically attach to the current JVM.

This installation method does not require you to alter the configuration of your application server and can be used to conveniently instrument all JVMs on a particular host.

The apm-agent-attach-standalone.jar is a small Java program which attaches the Elastic APM Java agent to a specific JVM or to all JVMs of the same host it runs on.

Supported environmentsedit

The attachment is supported on Windows, Unix and Solaris operating systems on HotSpot-based JVMs (like OpenJDK and Oracle JDK) and OpenJ9.

Some flags, like --include and --exclude require the jps command to be installed, which is part of the JDK distribution and does not typically come with the JRE distribution.

Caveatsedit

The OS user executing apm-agent-attach-standalone.jar and the OS user of the application(s) to be monitored (the JVMs to attach to) has to be the same.

When attaching to a J9 VM, you have to explicitly set the --pid <pid> argument, or have jps installed.

Currently, this does not work in combination with OSGi containers (which includes most application servers). The symptom is that there will be a lot of exceptions like this: java.lang.NoClassDefFoundError: co/elastic/apm/agent/servlet/ServletApiAdvice.

Downloadedit

You can download the attach program from maven central: maven central

As of version 1.9.0, you will have to download the standalone jar instead of the normal jar distribution.

Usageedit

Attach to a JVM with a specific PIDedit

Attaches the agent to a JVM with a specific process ID. Optionally, you can pass in arguments to configure the agent. See Options for the format of the agent arguments.

java -jar apm-agent-attach-standalone.jar --pid <pid> [--args <agent_arguments>]

Example: The following command attaches the agent to the JVM with the PID 42 and exits. Additionally, it applies some configuration options.

java -jar apm-agent-attach-standalone.jar --pid 42 \
    --args 'service_name=my-cool-service;server_urls=http://localhost:8200'
Attach to a filtered set of JVMs on a certain hostedit

Attaches the agent to all matching JVMs on the host which confirm to the optional include and exclude filters.

java -jar apm-agent-attach-standalone.jar [-include <include_pattern>...]
       [-exclude <exclude_pattern>...] [--continuous]
       [--args <agent_arguments> | --args-provider <args_provider_script>]

Example: The following command attaches the agent to all JVMs whose main class contains MyApplication or which are started from a jar file named my-application.jar. It also makes the attacher run continuously so that it attaches the agent on starting JVMs which match the include pattern. Additionally, it applies some configuration options.

java -jar apm-agent-attach-standalone.jar \
    --include '.*MyApplication.*' '.*/my-application.jar' \
    --continuous \
    --args 'service_name=my-cool-service;server_urls=http://localhost:8200'
List running JVMsedit

Lists all currently running JVMs, including their PID and their main class name or the path to their jar file.

java -jar apm-agent-attach-standalone.jar --list
Optionsedit
-l, --list
Lists all running JVMs. Same output as jps -lv.
-p, --pid <pid>

PID of the JVM to attach. If not provided, attaches to all currently running JVMs which match the --exclude and --include filters.

This option cannot be used in conjunction with --continuous, --exclude, --include and --args-provider

-c, --continuous

If provided, this program continuously runs and attaches to all running and starting JVMs which match the --exclude and --include filters.

This option cannot be used in conjunction with --pid

-e, --exclude <exclude_pattern>…​

A list of regular expressions of fully qualified main class names or paths to JARs of applications or any JVM system property of the java process the java agent should not be attached to. (Matches the output of jps -lv)

This option cannot be used in conjunction with --pid and requires the jps command to be installed

-i, --include <include_pattern>…​

A list of regular expressions of fully qualified main class names or paths to JARs of applications or any JVM system property of the java process the java agent should be attached to. (Matches the output of jps -lv)

This option cannot be used in conjunction with --pid and requires the jps command to be installed

-a, --args <agent_arguments>

If set, the arguments are used to configure the agent on the attached JVM (agentArguments of agentmain).

The syntax of the arguments is key1=value1;key2=value1,value2. See Configuration for all available configuration options.

This option cannot be used in conjunction with --args-provider

-C --config <key=value>…​

This repeatable option sets one agent configuration option.

Example: --config server_urls=http://localhost:8200,http://localhost:8201

-A, --args-provider <args_provider_script>

The name of a program which is called when a new JVM starts up. The program gets the pid and the main class name or path to the JAR file as an argument and returns an arg string which is used to configure the agent on the attached JVM (agentArguments of agentmain). When returning a non-zero status code from this program, the agent will not be attached to the starting JVM.

The syntax of the arguments is key1=value1;key2=value1,value2. See Configuration for all available configuration options.

This option cannot be used in conjunction with --pid and --args

Dockeredit

Use this script to automatically attach to all docker containers running on a host. This script does not return but continuously listens for starting containers which it also attaches to.

This script is experimental and might not work with all containers. Especially the jq --raw-output .[0].Config.Cmd[0]) == java might vary.

attach.sh. 

#!/usr/bin/env bash
set -ex

attach () {
    # only attempt attachment if this looks like a java container
    if [[ $(docker inspect ${container_id} | jq --raw-output .[0].Config.Cmd[0]) == java ]]
    then
        echo attaching to $(docker ps --no-trunc | grep ${container_id})
        docker cp ./apm-agent-attach-*-standalone.jar ${container_id}:/apm-agent-attach-standalone.jar
        docker exec ${container_id} java -jar /apm-agent-attach-standalone.jar --config
    fi
}

# attach to running containers
for container_id in $(docker ps --quiet --no-trunc) ; do
    attach
done

# listen for starting containers and attach to those
docker events --filter 'event=start' --format '{{.ID}}' |
while IFS= read -r container_id
do
    attach
done

Troubleshootingedit

If you get a message like no main manifest attribute, in apm-agent-attach.jar, you are using the wrong artifact. Use the one which ends in -standalone.jar.