Friends of OpenJDK Today

Remotely Recording a JFR Log from a Container (Without Using the Command Line)

May 07, 2024

Author(s)

  • Avatar photo
    Matt Van Order

    Java developer with years of experience developing systems for television and news broadcasting. Senior Technical Writer at Azul, with a focus on Azul Platform Prime.

Java Flight Recorder (JFR) is the go-to technology for recording and viewing JVM and system metrics.

JFR records JFR logs which reveal much about the running application, the health of the JVM and the stability of the system. JFR logs are easily obtained by simply going into the command line / terminal and entering a few commands.

But what if you don't have access to the command line or terminal directly on the system where the JVM is running, like when the JVM is running in a container?

Don't worry. In this quick guide, you can learn how to do just that with a little configuration using JVM's JMX connector and Azul Mission Control.

Setting up JMX on your JVM

Before you can access your JVM outside of the command line / terminal, you must set up your JVM to be discoverable and accessible over remote connections. You can accomplish this simply by enabling the JVM's JMX connector.

Configure your Java application with the following VM parameters:

  • -Dcom.sun.management.jmxremote: enables JMX/JMXRMI connectivity.
  • -Dcom.sun.management.jmxremote.host=[IP/Hostname]: Sets the address for JMX connection. Use an external IP address or host name of the computer or container where the Java program is running.
  • -Dcom.sun.management.jmxremote.port=[port]: Sets the TCP port for JMX connection.
  • -Djava.rmi.server.hostname=[IP/Hostname]: Sets the address for JMXRMI connection. Use the same IP/hostname you used for JMX connection.
  • -Dcom.sun.management.jmxremote.rmi.port=[port]: Sets the TCP port for JMXRMI connection. Use the same TCP port you used for JMX connection.
  • -Dcom.sun.management.jmxremote.local.only=false: If you are connecting to the JVM from a different machine, you have to unbind ports from localhost.
  • Additionally, you may want to enable JMX authentication/SSL using:
    • ‑Dcom.sun.management.jmxremote.authenticate=true
    • -Dcom.sun.management.jmxremote.ssl=true

For example:

-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.host=192.168.0.166 \
-Dcom.sun.management.jmxremote.port=7091 \
-Djava.rmi.server.hostname=192.168.0.166 \
-Dcom.sun.management.jmxremote.rmi.port=7091 \
-Dcom.sun.management.jmxremote.local.only=false \
‑Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \

Connecting to a Remote JVM Using Azul Mission Control

If you don't have Azul Mission Control yet, head over to the Azul Mission Control download page.

In Azul Mission Control, go to the JVM Browser and click the Add JVM Connection button to create a new custom JVM connection.

Specify the host name/IP address of the remote system and the JMX port number.

If JMX authentication is enabled, enter User and Password.

Click Test Connection to make sure your remote JVM is reachable and click Finish.

Your remote JVM now appears in the JVM Browser.

Depending on your network and container setup, port forwarding may need to be set up. Contact your network's administrator if you need help with port forwarding.

Recording a JFR from your Remote JVM

Now that you're connected to your JVM remotely, it's time to make a JFR recording.

In Azul Mission Control, go to the JDK Browser, right-click your remote JVM connection and select Start Flight Recording...

Select your preferred options and time intervals (either a fixed time recording or continuous recording based on the JFR log's size and/or age), and click Finish.

Your remote JFR recording has begun. You're almost there!

Check the progress of the recording by expanding the remote JVM connection in the JVM Browser.

Once your recording has finished, your JFR log opens automatically in Azul Mission Control.

You can now check the Outline tab to take a deeper look into your JVM's performance portfolio.

Topics:

Related Articles

View All
  • A Closer Look at JFR Streaming

    Since JDK 14, there is a new kid on the block – Java Flight Recorder streaming, which enables developers to subscribe to JFR data.

    It is a feature allowing a developer to subscribe to select JFR data and to decide what to do with that data in the host process. JFR events can also be consumed from a separate process by pointing to the file repo of a separate JVM process – the mechanism is the same.

    Read More
    Avatar photo
    August 17, 2020
  • Analyze JFR Recordings

    Continuing from part 1, to exploit the recording by analyzing it, we have a tool named jfr that ships with the JDK. On Linux the alternative jdk management may not be aware of jfr, which means you may need to use the full path to this executable.

    The first interesting thing to do is to get an overview of the recording, the summary sub-command displays an histogram of the events.

    Read More
    Avatar photo
    November 05, 2020
  • Control JFR Programmatically

    While from JDK 14 events can be consumed on the fly, previous JDK versions (from JDK 11) offer a public API useful enough to control Flight Recorder programmatically or to read events from a JFR file.

    Such API facilities are useful especially when combined with other technologies like Spring Actuators. Yet when there’s available integration or when using these integrations is too late, like recording startup, the most actionable way to get recording is from the command line.

    Read More
    Avatar photo
    November 19, 2020

Author(s)

  • Avatar photo
    Matt Van Order

    Java developer with years of experience developing systems for television and news broadcasting. Senior Technical Writer at Azul, with a focus on Azul Platform Prime.

Comments (0)

Your email address will not be published. Required fields are marked *

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard