Dropwizard Health Check Configuration Example

We have already seen how dropwizard is so effective in developing self-contained REST APIs and even REST client services as well. Dropwizard contains almost all the needed packages to build APIs in a very easy way without making things complex. One of the easily implemented features of dropwizard is the health check service which can be used for monitoring the status of the application/components that you are creating – in runtime.

1. Implementing Dropwizard Health Check

DropWizard health check is implemented by extending the HealthCheck class and returning Result.healthy() if everything is alright and Result.unhealthy() if something is not working – as expected.

1.1. Extend HealthCheck class

import com.codahale.metrics.health.HealthCheck;

public class ApplicationHealthCheck extends HealthCheck {

  @Override
  protected Result check() throws Exception {
    boolean status = true;

    //Check application health and set the status accordingly

    if(status == false)
      return Result.unhealthy("message");
    return Result.healthy();
  }
}

1.2. Register with Environment

To register this AppHealthCheck class with dropwizard application, use Environment.healthChecks() registry.

public class App extends Application<ApplicationConfiguration> {

  @Override
  public void initialize(Bootstrap<ApplicationConfiguration> b) {
  }

  @Override
  public void run(ApplicationConfiguration c, Environment e) throws Exception {

    ...

    LOGGER.info("Registering Application Health Check");
    e.healthChecks().register("application", new ApplicationHealthCheck());

    ...
  }

  public static void main(String[] args) throws Exception {
    new App().run(args);
  }
}

2. Validating Application Health

Dropwizard will an HTTP resource endpoint on /healthcheck on the admin port (default 8081). Dropwizard also includes a check for deadlocks by default along with any custom health checks.

HTTP GET http://localhost:8081/healthcheck

Above health check URL will return some results as below:

{
	"APIHealthCheck": {
		"healthy": true
	},
	"deadlocks": {
		"healthy": true
	}
}

3. Custom REST Resource to Run Health Checks

If you do not want to use the admin port then you can also create a custom REST resource that will run health checks for you, and return the result in your desired response format.

To run all health checks and get all their results, you will call registry.runHealthChecks() inside REST resource.

import com.codahale.metrics.health.HealthCheck.Result;
import com.codahale.metrics.health.HealthCheckRegistry;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.util.Map.Entry;
import java.util.Set;

@Produces(MediaType.APPLICATION_JSON)
@Path("/status")
public class HealthCheckController {

  private HealthCheckRegistry registry;

  public HealthCheckController(HealthCheckRegistry registry) {
    this.registry = registry;
  }

  @GET
  public Set<Entry<String, Result>> getStatus() {
    return registry.runHealthChecks().entrySet();
  }
}

Now when we call this REST API using http://localhost:8080/health-check, we get responses like below:

[
  {
    "APIHealthCheck": {
      "healthy": true,
      "message": null,
      "error": null
    }
  },
  {
    "deadlocks": {
      "healthy": true,
      "message": null,
      "error": null
    }
  }
]

You can customize the messages as per your need.

4. Demo

To demonstrate the above functionalities, I have modified the code given in dropwizard hello world application.

public class ApplicationHealthCheck extends HealthCheck {

  private final Client client;

  public ApplicationHealthCheck(Client client) {
    super();
    this.client = client;
  }

  @Override
  protected Result check() throws Exception {
    
    WebTarget webTarget = client.target("http://localhost:8080/employees");
    
    Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
    
    Response response = invocationBuilder.get();
    ArrayList<Employee> employees = response.readEntity(ArrayList.class);
    if (employees != null && !employees.isEmpty()) {
      return Result.healthy();
    }
    return Result.unhealthy("API Failed");
  }
}

App.java

@Override
public void run(ApplicationConfiguration c, Environment e) throws Exception {

  LOGGER.info("Registering Jersey Client");
  final Client client = new JerseyClientBuilder(e)
      .using(c.getJerseyClientConfiguration())
      .build(getName());
  e.jersey().register(new APIController(client));

  LOGGER.info("Registering Application Health Check");
  e.healthChecks().register("application", new ApplicationHealthCheck(client));
}

Now validate the default and custom health check URLs:

4.1. Default URL

HTTP GET http://localhost:8081/healthcheck

Dropwizard health check on admin port
Dropwizard health check on admin port

4.2. Custom Health Check URL

http://localhost:8080/status

Dropwizard health check on application port
Dropwizard health check on application port

Let me know of your questions in the comments section.

Happy Learning !!

Sourcecode on Github

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.