Writing a custom health check

Another critical feature needed when we take our application to production is monitoring it. In the olden days, people would set up a CRON job to ping a server and see if it was up. More intricate systems would track disk usage, memory usage, and ideally page someone when the database was at 95%, so it could be saved before falling over.

Spring Boot provides a new era in health check monitoring. To kick things off, launch the application and visit /application/health:

    {
        status: "UP",
        diskSpace: {
            status: "UP",
            total: 498937626624,
            free: 96519303168,
            threshold: 10485760
        },
        mongo: {
            status: "UP",
            version: "3.4.6"
        }
    }  

Out of the box, this provides us with an endpoint we can ping and additionally, gives us some information regarding disk space. It also includes an automatically included MongoDB health check.

But what if we needed to write our own health check? Perhaps, there is a system we are dependent upon. Knowing if this upstream service is unavailable could prove valuable.

To write our own health check, we merely need to write a Spring component that implements Spring Boot's HealthIndicator interface:

    @Component 
    public class LearningSpringBootHealthIndicator 
     implements HealthIndicator { 
 
       @Override 
       public Health health() { 
         try { 
           URL url = 
             new URL("http://greglturnquist.com/books/learning-spring-
boot"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); int statusCode = conn.getResponseCode(); if (statusCode >= 200 && statusCode < 300) { return Health.up().build(); } else { return Health.down() .withDetail("HTTP Status Code", statusCode) .build(); } } catch (IOException e) { return Health.down(e).build(); } } }

Let's dissect this custom health indicator:

  • @Component marks this class so that Spring Boot picks it up and registers it automatically.
  • By implementing the HealthIndicator interface, Spring Boot will include it along with the pre-built health checks when we hit /application/health.
  • The name LearningSpringBootHealthIndicator is used to create the indicator. HealthIndicator will be trimmed off, and the remaining text will be formatted with lazy camel style.
  • There is but one method in this interface (meaning you could implement it using a Java 8 lambda), health(). It uses some plain old Java APIs to open a connection to a remote URL and fetch a status code. If the status code is good, it will build a Health status code of UP. Otherwise, it will build a Health status code of DOWN while also giving us the failed HTTP status code.
  • Finally, if any other exceptions occur, we will also get a Health status code of DOWN but with the information from the exception instead of a commonly coded error path.

Let's relaunch the application and see what our /application/health endpoint reports:

    {
      "status": "UP",
      "details": {
        "mongo": {
          "status": "UP",
          "details": {
            "version": "3.4.6"
          }
        },
        "diskSpace": {
          "status": "UP",
          "details": {
            "total": 498937626624,
            "free": 43632435200,
            "threshold": 10485760
          }
        },
        "learningSpringBoot": {
          "status": "UP"
        }
      }
    }  

We can see our new health indicator, learningSpringBoot, listed with its status of UP.

To simulate a failure, let's alter the URL by switching the domain in the code to greglturnquist.io and see what happens:

    URL url = new URL("http://greglturnquist.io/books/learning-spring-
boot");

When we restart and ping /application/health, this is the outcome:

    {
      "status": "DOWN",
      "details": {
        "mongo": {
          "status": "UP",
          "details": {
            "version": "3.4.6"
          }
        },
        "diskSpace": {
          "status": "UP",
          "details": {
            "total": 498937626624,
            "free": 43629961216,
            "threshold": 10485760
          }
        },
        "learningSpringBoot": {
          "status": "DOWN",
          "details": {
            "error": "java.net.UnknownHostException: greglturnquist.io"
          }
        }
      }
    }  

A few things have happened:

  • Our learningSpringBoot indicator now reports DOWN. It's not due to some HTTP status code, but instead ConnectionException caused by not being able to form a connection.
  • While diskSpace and mongo are UP, the DOWN status of this indicator percolates to the top-level status, switching it to DOWN.

If we change the URL to simply http://greglturnquist.com/foo and restart, we can see a different status:

In this situation, we still have a DOWN status, but the HTTP status code 404 is reported. Both of these indicators can be quite informative for the DevOps team watching our application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.19.185