How to Monitor REST APIs Using Prometheus and Grafana

When you move your API to a production server, you need to monitor the service to debug issues and ensure the best end-user experience. Monitoring allows you to collect insights and perform different analyses on the API performance. If an API fails on some parameters or performs very slowly, this data enables you to understand and rectify those issues.

There are many different ways to monitor an API. In this article, we’ll outline one strategy to implement API monitoring. Below, we’ll learn how to monitor a REST API using Prometheus and Grafana.

What is Prometheus?

Prometheus is an open-source API monitoring tool that scrapes API data from intermediary pushes for short-lived jobs. It can be used to collect and store data with a timestamp of when an event occurs, or the API is called.

What is Grafana?

Grafana is an open-source monitoring dashboard that can be connected to different data sources. In this tutorial, Prometheus will act as a data source where all the data will be available on port 9090, and Grafana will fetch these data points and display them in the dashboard.

Now, let’s start with our tutorial.

Prerequisites

Step 1: Project Setup

Open your terminal, create a new folder using the below command and open it on your terminal:

mkdir prometheus_graphana
cd prometheus_graphana

Now let’s open the folder in VS Code.

Step 2: Prometheus Setup

Once you open the folder in VS Code, create a new file called docker-composer.yml and paste the below code:

version: "3"  
services:  
 prometheus:
      image: prom/prometheus:latest
      ports:
      -9090:9090

Code Explanation:

Docker Composer file allows us to install all the project dependencies; hence in our case, one of the biggest dependencies is Prometheus. So we’re telling the docker-compose file to fetch the latest version of Prometheus and assign it to port 9090.

Testing Docker Composer File

Before moving forward, let’s try to verify our composer file. Run the below command to verify the composer file:

docker-compose up

If everything is correct and the Docker server is running on your localhost, you should see the output like this:

Now, let’s head over to the URLhttp://localhost:9090 in a browser. You should see the below page:

Right now, Prometheus is tracking its server because we haven’t specified any server to Prometheus for tracking and collecting metrics.

Again in your browser, if you head over to the URLhttp://localhost:9090/metrics, you should see the below page:

Now, our Prometheus installation is complete. Let’s move ahead with the next steps.

Step 3: Updating Volume Path for Prometheus

By default, Prometheus uses the YAML file from path: /etc/prometheus/prometheus.yml. Now, we need to add our own prometheus.yml file and inform Prometheus to use that one.

Add the below line of code at the end of docker-composer.yml:

volumes:
      - "./prometheus.yml:/etc/prometheus/prometheus.yml"

The file should look something like this:

Create a new file called prometheus.yml and paste the below code:

global:
 scrape_interval:     15s
 evaluation_interval:  15s

scrape_configs:
 -job_name: prometheus
  static_configs:
   - targets: ['localhost:9090']

On running the command docker-compose up, you should see the below error:

It’s throwing an error because the Docker server is not allowed to mount files from that folder. So we need to add the path into our Docker server first. Open the Docker server GUI app, go to Settings -> Resources -> File Sharing, and click on the “+” button.

Select the folder prometheus_graphana, which is our root directory, and click on Apply & Restart.

Now, if you run the command docker-compose up, it’ll successfully get executed with the below output:

We’re now done with setting up Prometheus. Now, let’s move ahead with creating a Flask app. (To create an API using the Flask framework, you can reference our separate tutorial here.)

Step 4: Creating a Flask App

Create a new folder inside prometheus_graphana called flask_api. Inside flask_api folder create two files: Dockerfile and app.py.

In Dockerfile, paste the below code:

FROM python:3.8.2-alpine

RUN pip3 install --upgrade pip && pip3 install --no-cache-dir Flask flask_prometheus_metrics

EXPOSE 5000

CMD ["python3", "app.py"]

Code Explanation:

We’ll be creating a container inside which we will use Python 3.8 Alpine image. Once the Docker image is imported, we’ll install Flask and flask_prometheus_metrics.

After that, it’ll expose the API endpoints on port 5000. As of now, we only have told Docker to expose 5000 port. The CMD will execute the Flask app.

Now in app.py, paste the below code:

from flask import Flask, request, jsonify
from prometheus_client import make_wsgi_app
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.serving import run_simple
from flask_prometheus_metrics import register_metrics
app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'This is my first API call!'

@app.route('/post', methods=["POST"])
def testpost():
     input_json = request.get_json(force=True) 
     dictToReturn = {'text':input_json['text']}
     return jsonify(dictToReturn)

# provide app's version and deploy environment/config name to set a gauge metric
register_metrics(app, app_version="v0.1.2", app_config="staging")

# Plug metrics WSGI app to your main app with dispatcher
dispatcher = DispatcherMiddleware(app.wsgi_app, {"/metrics": make_wsgi_app()})

run_simple(hostname="0.0.0.0", port=5000, application=dispatcher)

Step 5: AAdd Flask App to Docker-composer.yml File

We now need to add our Flask app into the docker-composer file to run them using a single command. So open the docker-compoer.yml file and paste the below code at the bottom of the file under the services section:

app:
      container_name: app
      build: ./flask_api/.
      ports:
      - "5000:5000"
      volumes:
      - "./flask_api/app.py:/app.py"

Your final docker-composer.yml file should look like this:

In the file prometheus.yml, change the localhost:9090 to localhost:5000. Now, let’s try validating all the files using the command docker-compose up. On successful execution, you should see the below output in your terminal:

Now let’s keep the services running.

Step 6: Installing and Setting up Grafana

Note: This step will install Grafana on a Mac device. If you’re using other operating systems, you can go to this link and follow the steps in the official documentation for your OS.

Open another terminal and use the below command to install Grafana:

brew install grafana

Once you have successfully installed the Grafana, use the below command to run it:

brew services start grafana

Now go to the URL: http://localhost:3000/login and enter admin as username/password. After login and updating the password, you should see the below page:

Step 7: Adding the Data Source and Creating the Dashboard

Click on Add your first data source and select Prometheus. In the URL field, paste http://localhost:9090 and then click on the Save & Test button:

Now, go back to page localhost:3000 and click on Create your first dashboard. It’ll redirect you to the dashboard creation page, where you must select Add a new panel. It’ll open the below page:

Here, select the metrics you want to show in the graph. For instance, we’re going to select go_gc_duration_seconds and click on the “Save” button at the top-right of the page.

After saving the dashboard, it’ll load the graph:

We’re done now! This graph will show the job name, latency in seconds, and the time the API is hit.

Final Words

You can add a lot of different charts and monitor your API using Grafana. Prometheus can fetch various metrics that different charts will use in Grafana.