Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.
  • Labs icon Lab
  • A Cloud Guru
Google Cloud Platform icon
Labs

Application Monitoring with Prometheus

When it comes to monitoring, keeping track of our CPU, memory, and other infrastructure metrics often isn't enough. Beyond the common infrastructure-based metrics we expose via tools such as the Node Exporter, we also want to instrument our application to send out metrics related to the app itself. This is done by using the Prometheus client library available to our application's language. Once we have the client library set up in our application, we can then define any metrics we wish to collect and write the code to support them. We can also have the Prometheus client record a number of default metrics already included in the library and available to us. Once finished, we'll have added metrics for our to-do application that track added and removed tasks, as well as response times across our app.

Google Cloud Platform icon
Labs

Path Info

Level
Clock icon Intermediate
Duration
Clock icon 30m
Published
Clock icon Apr 05, 2019

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Add the Prometheus client and track any default metrics.

    1. Move into the forethought directory:

      $ cd forethought
      
    2. Install the prom-client via npm, Node.js's package manager:

      $ npm install prom-client --save
      
    3. Open the index.js file, where we'll be adding all of our metrics code:

      $ $EDITOR index.js
      
    4. Require the use of the prom-client by adding it to our variable list:

      var express = require('express');
      var bodyParser = require('body-parser');
      var app = express();
      const prom = require('prom-client');
      

      With prom being the name we'll use when calling the client library.

    5. Enable default metrics scraping:

      const collectDefaultMetrics = prom.collectDefaultMetrics;
      collectDefaultMetrics({ prefix: 'forethought_' });
      
    6. Use Express to create the /metrics endpoint and call in the Prometheus data:

      app.get('/metrics', function (req, res) {
        res.set('Content-Type', prom.register.contentType);
        res.end(prom.register.metrics());
      });
      
  2. Challenge

    Add the `forethought_tasks_added` metric.

    1. Define the metric:

       const tasksadded = new prom.Counter({
         name: 'forethought_tasks_added',
         help: 'The number of items added to the to-do list, total'
       });
      
    2. Call the new metric in the addtask post function so it increases by one every time the function is called while adding a task:

       // add a task
       app.post("/addtask", function(req, res) {
         var newTask = req.body.newtask;
         task.push(newTask);
         res.redirect("/");
         tasksadded.inc();
       });
      
  3. Challenge

    Add the `forethought_tasks_complete` metric.

    1. Define the metric:

       const tasksdone = new prom.Counter({
         name: 'forethought_tasks_complete',
         help: 'The number of items completed'
       });
      
    2. Call the new metric in the /removetask post function so it increases by one every time the function is called:

       // remove a task
       app.post("/removetask", function(req, res) {
         var completeTask = req.body.check;
         if (typeof completeTask === "string") {
           complete.push(completeTask);
           task.splice(task.indexOf(completeTask), 1);
         }
         else if (typeof completeTask === "object") {
           for (var i = 0; i < completeTask.length; i++) {
             complete.push(completeTask[i]);
             task.splice(task.indexOf(completeTask[i]), 1);
             tasksdone.inc()
           }
         }
         res.redirect("/");
       });
      
  4. Challenge

    Add the `forethought_current_tasks` metric.

    1. Define the metric:

       const taskgauge = new prom.Gauge({
         name: 'forethought_current_tasks',
         help: 'Amount of incomplete tasks'
       });
      
    2. Add an increase to the /addtask method:

       // add a task
       app.post("/addtask", function(req, res) {
         var newTask = req.body.newtask;
         task.push(newTask);
         res.redirect("/");
         tasksadded.inc();
         taskgauge.inc();
       });
      
    3. Add a decrease to the /removetask method:

       // remove a task
       app.post("/removetask", function(req, res) {
         var completeTask = req.body.check;
         if (typeof completeTask === "string") {
           complete.push(completeTask);
           task.splice(task.indexOf(completeTask), 1);
         }
         else if (typeof completeTask === "object") {
           for (var i = 0; i < completeTask.length; i++) {
             complete.push(completeTask[i]);
             task.splice(task.indexOf(completeTask[i]), 1);
             tasksdone.inc();
             taskgauge.dec();
           }
         }
         res.redirect("/");
       });
      
    4. Save and exit.

  5. Challenge

    Add the `forethought_response_time_summary` metric.

    1. Add the response-time module:

       $ npm install response-time --save
      
    2. Reopen the index.js file.

    3. Define the metric:

       const responsetimesumm = new prom.Summary ({
         name: 'forethought_response_time_summary',
         help: 'Latency in percentiles',
       });
      
    4. Add response-time:

       var responseTime = require('response-time');
      
    5. Write the code to retrieve the response time:

       app.use(responseTime(function (req, res, time) {
         responsetimesumm.observe(time);
       }));
      
  6. Challenge

    Add the `forethought_response_time_histogram` metric.

    1. Define the metric:

       const responsetimehist = new prom.Histogram ({
         name: 'forethought_response_time_histogram',
         help: 'Latency in history form',
         buckets: [0.1, 0.25, 0.5, 1, 2.5, 5, 10]
       });
      
    2. Call the histogram in the existing response-time code:

       app.use(responseTime(function (req, res, time) {
         responsetimesumm.observe(time);
         responsetimehist.observe(time);
       }));
      
  7. Challenge

    Reimage the application and redeploy the container; add to Prometheus.

    1. Stop the current Docker container for our application:

       $ docker stop ft-app
      
    2. Remove the container:

       $ docker rm ft-app
      
    3. Remove the image:

       $ docker image rm forethought
      
    4. Rebuild the image:

       $ docker build -t forethought .
      
    5. Deploy the new container:

       $ docker run --name ft-app -p 80:8080 -d forethought
      
    6. Switch to the monitoring server.

    7. Add our application endpoint to Prometheus (replacing PRIVATE_IP with the private IP for the Application server listed on the lab page):

       $ sudo $EDITOR /etc/prometheus/prometheus.yml
      
         - job_name: 'forethought'
           static_configs:
           - targets: ['PRIVATE_IP:80']
      

      Save and exit.

    8. Restart Prometheus:

       $ sudo systemctl restart prometheus
      

The Cloud Content team comprises subject matter experts hyper focused on services offered by the leading cloud vendors (AWS, GCP, and Azure), as well as cloud-related technologies such as Linux and DevOps. The team is thrilled to share their knowledge to help you build modern tech solutions from the ground up, secure and optimize your environments, and so much more!

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.

Start learning by doing today

View Plans