API with NestJS #51. Health checks with Terminus and Datadog

JavaScript NestJS TypeScript

This entry is part 51 of 177 in the API with NestJS

We should be aware of whether our application is healthy. One way to do that would be to make various API requests to confirm it manually. It might not be the most elegant solution, though. The answer can be health checks. With them, we can verify if various aspects of our system work properly. Creating a health check boils down to exposing an endpoint that tests our application and throws an error if it is unhealthy. Thanks to tools such as Datadog, we can periodically call the health check endpoint to make sure that everything works as expected.

Introducing Terminus

NestJS comes with a tool called Terminus that can help us implement our health check.

To use it, we should create a new controller.

health.controller.ts

We also need to put it into a module that imports the .

health.module.ts

By doing the above, we achieve a straightforward health check.

With the above endpoint so far, we can know whether our API started or not. However, it is not much information, so let’s add additional checks.

Using built-in health indicators

Terminus comes with a set of health indicators that can check if a particular service is healthy or not. A good example is the .

health.controller.ts

Under the hood, the performs a simple  SQL query to our database to verify that it is up and running and we’ve established a connection. If any of our health indicators fail, the endpoint responds with 503 Service Unavailable instead of 200 OK.

Our endpoint responds with a few properties:

  • – if any of our health indicators fail, the status is set to . If our application is currently shutting down, the status is .
  • – contains information about each health indicator that is healthy and has the status ,
  • – has information about every health indicator that is unhealthy and has the status ,
  • – contains the information about every health indicator that we have.

A list of other built-in health indicators

Terminus has more health indicators that we can use, such as:

Having the above in mind, let’s use more of the built-in health indicators.

health.controller.ts

Custom health indicators

While there are quite a few of the built-in indicators, they are far from covering every case. Thankfully, we can set up a custom health indicator. To do that, we need to extend the class.

For example, in the 12th part of this series, we’ve used Elasticsearch. Let’s write a health indicator that checks if our instance of Elasticsearch is up and running.

elasticsearchHealthIndicator.ts

We need to register the as a provider before using it.

health.module.ts

Please notice that I’ve imported the that we’ve created in the 12th part of this series.

The last step is to use the in our health check:

health.controller.ts

Our health check will now check Elasticsearch and verify if it is up and running.

Performing health checks with Datadog

Although the endpoint that we’ve created looks useful, we’ve been using it manually so far. Fortunately, there are services such as Datadog that can call this endpoint for us periodically.

To do that, we need to set up an account and create a new synthetic test.

When we’re there, we need to create a new API test.

If your API isn’t deployed yet, but you want to try the above solution, you can use ngrok to share your localhost API with the world.

When defining our test, we first need to specify the URL of our health check:

You might want to avoid exposing the health of our application to the outside world and require some kind of authentication to access the endpoint for security reasons. If you do that, click Advanced Options where you can provide additional request options.

We also need to specify when our test is perceived as successful and what locations we want Datadog to request our API from. Since if any of our health indicators fail, the endpoint responds with 503 Service Unavailable, let’s check if our endpoint responds with 200 OK.

It is also important to specify the frequency of the test and define alert conditions. If something goes wrong, the team can be notified.

Thanks to doing all of the above, Datadog will monitor our health check endpoint and alert us if something goes wrong. We can also view the history of the tests for more details.

Summary

In this article, we’ve created a health check endpoint with a tool called Terminus. While doing so, we’ve used various health indicators built into NestJS and created a custom one. We’ve set up Datadog to periodically request our health check endpoint and alert us about downtime to benefit from it more.

Health checks are more than just a way to check if our API is up. We can validate the connection to our database or even test its performance to notice potential issues. We should create health checks based on the environment of our application and include services our app depends on. Feel free to write more custom health indicators and fiddle more with Datadog to help you keep your API more reliable and stable.

Series Navigation<< API with NestJS #50. Introduction to logging with the built-in logger and TypeORMAPI with NestJS #52. Generating documentation with Compodoc and JSDoc >>
Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Vladislav
Vladislav
3 years ago

Pretty cool stuff, thanks for Your work!

Denis
Denis
3 years ago

In .check([]) we have array with health indicators. Is there any chance to return all failed healthchecks not only first rejected?