- Lab
- A Cloud Guru
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.
Path Info
Table of Contents
-
Challenge
Add the Prometheus client and track any default metrics.
-
Move into the
forethought
directory:$ cd forethought
-
Install the
prom-client
vianpm
, Node.js's package manager:$ npm install prom-client --save
-
Open the
index.js
file, where we'll be adding all of our metrics code:$ $EDITOR index.js
-
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. -
Enable default metrics scraping:
const collectDefaultMetrics = prom.collectDefaultMetrics; collectDefaultMetrics({ prefix: 'forethought_' });
-
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()); });
-
-
Challenge
Add the `forethought_tasks_added` metric.
-
Define the metric:
const tasksadded = new prom.Counter({ name: 'forethought_tasks_added', help: 'The number of items added to the to-do list, total' });
-
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(); });
-
-
Challenge
Add the `forethought_tasks_complete` metric.
-
Define the metric:
const tasksdone = new prom.Counter({ name: 'forethought_tasks_complete', help: 'The number of items completed' });
-
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("/"); });
-
-
Challenge
Add the `forethought_current_tasks` metric.
-
Define the metric:
const taskgauge = new prom.Gauge({ name: 'forethought_current_tasks', help: 'Amount of incomplete tasks' });
-
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(); });
-
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("/"); });
-
Save and exit.
-
-
Challenge
Add the `forethought_response_time_summary` metric.
-
Add the
response-time
module:$ npm install response-time --save
-
Reopen the
index.js
file. -
Define the metric:
const responsetimesumm = new prom.Summary ({ name: 'forethought_response_time_summary', help: 'Latency in percentiles', });
-
Add
response-time
:var responseTime = require('response-time');
-
Write the code to retrieve the response time:
app.use(responseTime(function (req, res, time) { responsetimesumm.observe(time); }));
-
-
Challenge
Add the `forethought_response_time_histogram` metric.
-
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] });
-
Call the histogram in the existing
response-time
code:app.use(responseTime(function (req, res, time) { responsetimesumm.observe(time); responsetimehist.observe(time); }));
-
-
Challenge
Reimage the application and redeploy the container; add to Prometheus.
-
Stop the current Docker container for our application:
$ docker stop ft-app
-
Remove the container:
$ docker rm ft-app
-
Remove the image:
$ docker image rm forethought
-
Rebuild the image:
$ docker build -t forethought .
-
Deploy the new container:
$ docker run --name ft-app -p 80:8080 -d forethought
-
Switch to the
monitoring
server. -
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.
-
Restart Prometheus:
$ sudo systemctl restart prometheus
-
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.