StruggleLion
StruggleLion

Reputation: 99

How to use SpringBoot actuator over JMX

I am having existing Spring Boot application and I want to do monitoring the application through actuator.I tried with http endpoints and it is working fine for me. Instead of http end points I need JMX end points for my existing running application.

Upvotes: 2

Views: 8709

Answers (2)

Archimedes Trajano
Archimedes Trajano

Reputation: 41290

Assuming you're using a Docker image where the entry point is the Spring Boot app using java in which case the PID is "1" and so would the Attach API's Virtual Machine ID. You can implement a health probe as follows.

import com.sun.tools.attach.spi.AttachProvider;
import java.util.Map;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class HealthProbe {

  public static void main(String[] args) throws Exception {

    final var attachProvider = AttachProvider.providers().get(0);
    final var virtualMachine = attachProvider.attachVirtualMachine("1");
    final var jmxServiceUrl = virtualMachine.startLocalManagementAgent();

    try (final var jmxConnection = JMXConnectorFactory.connect(new JMXServiceURL(jmxServiceUrl))) {
      final MBeanServerConnection serverConnection = jmxConnection.getMBeanServerConnection();

      @SuppressWarnings("unchecked")
      final var healthResult =
          (Map<String, ?>)
              serverConnection.invoke(
                  new ObjectName("org.springframework.boot:type=Endpoint,name=Health"),
                  "health",
                  new Object[0],
                  new String[0]);
      if ("UP".equals(healthResult.get("status"))) {
        System.exit(0);
      } else {
        System.exit(1);
      }
    }
  }
}

This will use the Attach API and make the original process start a local management agent.

The org.springframework.boot:type=Endpoint,name=Health object instance would have it's health method invoked which will provide a Map version of the /actuator/health output. From there the value of status should be UP if things are ok.

Then exit with 0 if ok, or 1 otherwise.

This can be embedded in an existing Spring Boot app so long as loader.main is set. The following is the HEALTHCHECK probe I used

HEALTHCHECK --interval=5s --start-period=60s \
    CMD ["java", \
         "-Dloader.main=net.trajano.swarm.gateway.healthcheck.HealthProbe", \
         "org.springframework.boot.loader.PropertiesLauncher" ]

This is the technique I used in distroless Docker Image.

Side note: Don't try to put this in a CommandLineRunner interface because it will try to pull the configuration from the main app and you likely won't need the whole web stack.

Upvotes: 1

Dina Bogdan
Dina Bogdan

Reputation: 4698

If you add spring-boot-starter-actuatordependency in your build.gradle or pom.xml file you will have JMX bean enabled by default as well as HTTP Endpoints.

You can use JConsole in order to view your JMX exposed beans. You'll find more info about this here.

More details about how to access JMX endpoints here.

Upvotes: 3

Related Questions