Advanced Monika alert queries: A guide to operators and helpers

Denny Pradipta
Hyperjump Tech
Published in
6 min readNov 24, 2021
Photo by Etienne Girardet on Unsplash

This article is part two of “Forget predefined alerts, now you can create your own alert when your API is down with Monika which you should probably read first.

Let’s say that you have a health check API in your web app that returns a response body of the current status of the database, Redis, and the API service:

{
"db": "UP",
"redis": "UP",
"api": "UP"
}

And the implementation is that it will not return status code 500 unless all of the services are down. So, let’s assume that it will always return status code 200 unless all three services are down.

Luckily, you are using Monika to monitor your web app performances. But you want to make sure that everything is monitored thoroughly. As an example, you want to check if the health check API response object returns the redis key with the value UP. Or maybe, you want to create a separate alert just for the incidents that happened to the database service.

If you have read our previous article about creating your own Monika alerts, you are probably familiar that you can use operators to check the values of the response object, such as response.status != 200 to check if the response status code is not 200. But what if you want to check if the response body is an empty object or the value from the response body starts with a certain word?

This article will guide you to create alert queries using operators and helpers available in Monika. So, without further ado:

Configuring Monika with Operators and Helpers

We’re talking about our open-source synthetic monitoring software, not Monika from Doki Doki Literature Club. Monika is an open-source and free synthetic monitoring command-line application. The name Monika stands for “Monitoring Berkala”, which means “periodic monitoring” in the Indonesian language.

With Monika, you can add as many websites as you want to monitor. You can monitor several undesirable events such as service outages or slow services. In addition, you can configure Monika to send notifications of the incidents on your services through your favorite communication tools like SMTP mail, Telegram, WhatsApp (It’s free!), etc.

To run Monika, make sure you have installed Monika by running npm install -g @hyperjumptech/monika if you’re using NPM, but you can also download the prebuilt binary from our release page if you prefer to.

This section will be separated into two parts: Guide to Operators and Guide to Helpers.

Guide to Operators

Because we don’t have a health check API example, we can use an example REST API: https://reqres.in. In this example, we will be using the https://reqres.in/api/unknown endpoint. This endpoint will return a response like this:

Example https://reqres.in response for the /api/unknown endpoint

First, let’s create an example configuration for Monika. Open your text editor and save the lines of code below as monika.yml :

notifications:
- id: desktop
type: desktop
probes:
- id: sample_1
name: Sample Request
requests:
- method: GET
url: https://reqres.in/api/unknown
alerts:
- query: response.time > 1000
message: Response time is {{ response.time }} ms, expecting less than 1000ms
- query: response.status != 200
message: Status code is not 200. I think their service is down.
incidentThreshold: 2
recoveryThreshold: 2

Using this configuration, Monika will hit https://reqres.in/api/unknown endpoint. You will be alerted if the response time is longer than 1000 milliseconds and/or if the status code is not 200. As you can see here, the configuration above uses ‘greater than’ operator and ‘not equal to’ operator. There are many operators available, which you can see below:

All operators available

So, if we want to be alerted when if the first entry’s name is not cerulean, we could simply set the alert query like so:

- query: response.body.data.[0].name != "cerulean"
message: The first data entry should be Cerulean!

Guide to Helpers

The main purpose of helpers is to help (thank you Captain Obvious). While we developed Monika two months ago, we stumbled upon a bug that users cannot create an alert if the response body is empty. To resolve that issue, we use Lodash to improve Monika alerting query capability.

The available helper functions that you can use are:

  • has(object, property): Checks whether an object has searched a property.
    For example, has(response.body, "data") checks if there is a "data" property inside the response body
  • lowerCase(string): Converts string to lower case. For example, lowerCase(response.body.message) converts message string value to lower case
  • upperCase(string): Converts string to upper case. For example, upperCase(response.body.message) converts message string value to upper case
  • startsWith(string, target): Checks if a string starts with the given target string. For example, startsWith(response.body.message, "Hello") checks if the message string value starts with "Hello"
  • endsWith(string, target): Checks if a string ends with the given target string. For example, startsWith(response.body.message, "world!") checks if the message string value ends with "world!"
  • includes(collection, value): Checks if a value is in a collection. If collection is a string, it’s checked for a substring of value. For example, includes(response.body.prizes, "gold") checks if "gold" exists in the “prizes” array.
  • size(collection): Gets the length of array or string values. For example, size(response.body.data.items) gets the count of items.
  • isEmpty(value): Checks if the value is an empty object, empty array, empty string, null, or undefined. For example: isEmpty(response.body.data) checks whether the data property is empty or not.

Let’s use our previous configuration. As an example, we will be using the startsWith and isEmpty helper. We want to make sure that the third entry from the https://reqres.in endpoint response body starts with the word “true”:

notifications:
- id: desktop
type: desktop
probes:
- id: sample_1
name: Sample Request
requests:
- method: GET
url: https://reqres.in/api/unknown
alerts:
- query: response.time > 1000
message: Response time is {{ response.time }} ms, expecting less than 1000ms
- query: response.status != 200
message: Status code is not 200. I think their service is down.
- query: startsWith(response.body.data.[3].name, "true")
message: Third entry name should starts with "true"!
- query: isEmpty(response.body.data)
message: Data should not be empty!
incidentThreshold: 2
recoveryThreshold: 2

In our updated configuration, we will now receive alerts if:

  • The response time is greater than 1000 milliseconds
  • The response status code is not 200
  • The third entry name from the response body data object does not start with the word “true”
  • The response body data object is an empty object, null, or undefined.

Save the configuration as monika.yml and run Monika using this configuration by running monika -c monika.yml in your terminal.

Up and running!

Congratulations! You are now an alert queries master!

Closing

Alert queries using operators and helpers are quite handy if you use them the right way. And by separating the alerts based on the response data, it will be easier to troubleshoot problems when your website is down.

If you think that you need more helpers from Lodash to be used in the alert queries, open an issue or submit a PR in Monika Github repositories. Also if you’re having a problem with using Monika, don’t hesitate to start a discussion. If you like this article, don’t forget to clap and share this article with your friends!

That’s it for today, see you next time!

Hyperjump is an open-source-first company providing engineering excellence service. We aim to build and commercialize open-source tools to help companies streamline, simplify, and secure the most important aspects of its modern DevOps practices.

--

--

Denny Pradipta
Hyperjump Tech

Full-stack developer who loves to explore new technologies. Uses MongoDB, Express, React, and Node daily. Regularly writing for Hyperjump Technologies.