Skip to content

Instantly share code, notes, and snippets.

@kevin-lee
Created August 10, 2016 15:55
Show Gist options
  • Star 37 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save kevin-lee/cbfbde89d68299304b1b1a2e6371fe06 to your computer and use it in GitHub Desktop.
Save kevin-lee/cbfbde89d68299304b1b1a2e6371fe06 to your computer and use it in GitHub Desktop.
JVM Profiler with Docker

JProfiler with Docker

Docker

DockerFile

DockerFile should have JProfiler installation.

RUN wget <JProfiler file location> -P /tmp/ && \
  tar -xzf /tmp/<JProfiler file> -C /usr/local && \
  rm /tmp/<JProfiler file>

EXPOSE <port>

e.g.)

RUN wget http://download-aws.ej-technologies.com/jprofiler/jprofiler_linux_9_2.tar.gz -P /tmp/ && \
  tar -xzf /tmp/jprofiler_linux_9_2.tar.gz -C /usr/local &&\
  rm /tmp/jprofiler_linux_9_2.tar.gz

EXPOSE 8849

Run

docker run -p <port>:<port> your-docker 

e.g.)

docker run -p 8849:8849 your-docker 

JProfiler

Run Application with JProfiler Agent

java -jar my-app.jar -agentpath:/usr/local/jprofiler9/bin/linux-x64/libjprofilerti.so=port=<port>

e.g.)

java -jar my-app.jar -agentpath:/usr/local/jprofiler9/bin/linux-x64/libjprofilerti.so=port=8849

So in the DockerFile, it looks like

ENTRYPOINT ["java -jar","my-app.jar", 
  "-agentpath:/usr/local/jprofiler9/bin/linux-x64/libjprofilerti.so=port=8849"]
  1. Select 'Profile an application server, locally or remotely'.
  2. If the target application is running on any specific server listed, select it. Otherwise, choose Generic application.
  3. Select Linux X86/AMD64 for Platform of the remote computer on a remote computer.
  4. Select the JVM used in the Docker instance.
  5. To make JProfiler to wait for the application to start and send data, select Wait for a connection from the JProfiler GUI.
  6. Enter the remote address to the Remote address. If it's Docker for Mac, it is localhost. If Docker Machine is used, use the IP of the Docker Machine.
  7. Add the path to the JProfiler on the Docker where the jar file metioned above is using to the Remote installation directory. It looks like /usr/local/jprofiler<version>. e.g.) /usr/local/jprofiler9
  8. Set the port number or use the default (i.e. 8849).

VisualVM with Docker

Installation

VisualVM comes with the JDK so it doesn't require any extra installation or payment if JDK is already installed.

DockerFile

The following options should be added to java executable command.

-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=<port>
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=<port>
-Djava.rmi.server.hostname=<docker ip>

So it should be like

ENTRYPOINT ["java -jar", "app.jar",
  "-Dcom.sun.management.jmxremote=true",
  "-Dcom.sun.management.jmxremote.port=<port>",
  "-Dcom.sun.management.jmxremote.authenticate=false",
  "-Dcom.sun.management.jmxremote.ssl=false",
  "-Dcom.sun.management.jmxremote.local.only=false",
  "-Dcom.sun.management.jmxremote.rmi.port=<port>",
  "-Djava.rmi.server.hostname=<docker ip>"]

e.g.)

ENTRYPOINT ["java -jar", "my-app.jar",
  "-Dcom.sun.management.jmxremote=true",
  "-Dcom.sun.management.jmxremote.port=8849",
  "-Dcom.sun.management.jmxremote.authenticate=false",
  "-Dcom.sun.management.jmxremote.ssl=false",
  "-Dcom.sun.management.jmxremote.local.only=false",
  "-Dcom.sun.management.jmxremote.rmi.port=8849",
  "-Djava.rmi.server.hostname=localhost"]
  • Docker for Mac uses Hyperkit instead of Docker Machine through VirtualBox so the host location can be just localhost rather than the IP of the Docker Machine. If you're using Docker Machine, use the IP of the machine.

VisualVM

Run jvisualvm which is located at $JAVA_HOME/bin.

  1. File -> Add JMX Connection...
  2. Enter the host and port (e.g. localhost:8849).
@blakemorgan
Copy link

I've spent hours figuring out how to do this. Thank you!

@harishcholleti
Copy link

Seeing an issue with wget command not found with the below script. Any suggestions?

FROM

RUN wget http://XXXXXXXXX/jprofiler-local/jprofiler_linux_7_1_1.tar -P /tmp/ &&
tar -xzf /tmp/jprofiler_linux_7_1_1.tar -C /usr/local &&
rm /tmp/jprofiler_linux_7_1_1.tar

EXPOSE 8849

Log

Step 2/3 : RUN wget http://XXXXXXXX/jprofiler-local/jprofiler_linux_7_1_1.tar.tar -P /tmp/ && tar -xzf /tmp/jprofiler_linux_7_1_1.tar.tar -C /usr/local && rm /tmp/jprofiler_linux_7_1_1.tar
---> Running in b70b5809d810

"/bin/sh: wget: command not found"

Otherway,
I tried adding the "Step 2:RUN yum -y install wget" before RUN Wget then seeing a connection timeout issue.

http://192.18.10.29/yum/docker/dockerrepo-oel7/repodata/repomd.xml: [Errno 12] Timeout on http://192.17.10.29/yum/docker/dockerrepo-oel7/repodata/repomd.xml: (28, 'Connection timed out after 30006 milliseconds')

@kevin-lee
Copy link
Author

@blakemorgan Glad that it was helpful. :)

@kevin-lee
Copy link
Author

@harishcholleti Is it CentOS? Sorry I don't use CentOS or any Red Hat ones.
So I'm not sure if I'm the right one to ask but it looks like wget is not installed which is really weird.
I think it's more likely that wget is not in the PATH. Could you try which wget and get the path and use it or add the path to the PATH env var?

The simplest solution might be putting the following line in your Dockerfile.

RUN export PATH=$PATH:$(dirname $(which wget))

I'm not so sure if you need to use ENV instead of RUN but you can try both.
I don't need to set up Dockerfile these days so I forgot the things that were familiar before.

@harishcholleti
Copy link

harishcholleti commented Jun 25, 2020 via email

@kevin-lee
Copy link
Author

@harishcholleti Yeah once the image is built, you can run it without the public networks.

@bkrajendra
Copy link

How to provide the license information to jprofiler agent inside the container?

@bkrajendra
Copy link

With latest version of jProfiler, its zero config setup for containers.
We can directly profile a java process inside a container running on the remote or local machine.

@zfatima04
Copy link

I am running docker based application with JProfiler Agent on linux server x86 and then I am trying to use Jprofiler (UI) from windows machine using remote JVM option and linux sever ip port but it shows me error that no jprofiling agent is listening at port 8849. When I simply run a java application instead of docker container, connection is successful. Can you please help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment