Wednesday, August 24, 2016

Configure JProfiler 9.2 to profiling applications running in Docker containers

Recently, I worked on a task to address a memory issue in our applications. And I was using JProfiler 9.2 to analyze the memory usage. I run our applications in Docker containers, so I have to attach JProfiler to remote JVM to do the profiling. Below is a step by step guide on how to make JProfiler 9.2 working with Docker. P.S. I'm using a Linux system.

These steps are to be done in Docker containers:

1. Download JProfiler 9.2 in Docker image and expose port 8849 by adding the following lines in the Dockerfile file and rebuild the Docker image.

RUN wget http://download-keycdn.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

ENV JPAGENT_PATH="-agentpath:/usr/local/jprofiler9/bin/linux-x64/libjprofilerti.so=nowait"
EXPOSE 8849

2. Start the Docker container.

As Will Humphreys's comments below. Start your docker container with port 8849 mapped to your host's port 8849.
  docker run -p 8849:8849 imageName

If docker compose is in use. Map port 8849 to the host port 8849  by adding "8849:8849" to the ports section in the docker-compose file.
  
  ports:
      - "8849:8849"

3. Get inside the Docker container by running the command below.

docker exec -it [container-name] bash

4. Start attach mode of JProfiler in the Docker container by running these commands inside the docker container.

cd /usr/local/jrofiler9/
bin/jpenable

JProfiler should promote you to enter the mode and the port. Enter '1' and '8849' as shown in the screen shot below.



Then you should see the JProfiler log information in your application server's log. See example screen shot below.












Alternatively, if you want to enable JProfiler agent at your web server start up and wait for JProfiler GUI connecting from host, instead of putting "ENV JPAGENT_PATH="-agentpath:/usr/local/jprofiler9/bin/linux-x64/libjprofilerti.so=nowait"" in the Dockerfile. Add following line to the JAVA_OPTS. For tomcat, it will be CATALINA_OPTS. Note: the config.xml will be the place to put your JProfiler license key.


JAVA_OPTS="$JAVA_OPTS -agentpath:/usr/local/jprofiler9/bin/linux-x64/libjprofilerti.so=port=8849,wait,config=/usr/local/jprofiler9/config.xml"

Now you are done at the docker container side. The container is ready to be attached to 
your JProfiler GUI. The steps below are to be done on the host machine.


1. Download JProfiler 9.2 from https://www.ej-technologies.com/download/jprofiler/files and install it.
2. Open JProfiler and open a new session by press Ctrl + N or Click 'New Session' in Session menu.
3. Select 'Attach to profiled JVM (local or remote)' in Session Type section. Enter the IP address and 8849 as profiling port in Profiled JVM Settings section. Leave the other settings as default. Then click OK.



If you don't know the IP address of the Docker container, go inside it and type 'ifconfig'. If 'ifconfig' is not found, install it by 'yum -y install net-tools' for centOS system. Or whatever command for the other systems.

4. A Session Startup window should be shown, leave all default settings and click OK.



JProfiler should start to transform classes and connect to your JVM in the Docker container.



Once it finishes the connecting process, you should be able to see the profiling charts showing up.





















PS. If you have a license key, the way to enter it to the JProfiler inside docker container is opening $JPROFILER_HOME/config.xml, and insert your key there as below. If config.xml is not existing, copy it from $HOME/.jprofiler9 on your host machine.



  
  ...