uncrafted


App statistics in 5 minutes using Chronograf, Telegraf, and InfluxDB with node.js

Hey! We all know how useful app statistics is to find memory spikes, CPU spikes and other problems, but there is no easy way to see these stats without either writing a lot of code or having a slow or incompatible solution. I have a simple fast and elegant solution to do this, and more!

We will be using InfluxDB to store our data, Telegraf to process our data, and Chronograf to display the data. All these products are free and are made by InfluxData and are regularly updated and completely compatible.

I tested this on a Lubuntu 19.10 VM (Ubuntu 19.10 LTS) but should work on most other Ubuntu/Debian distributions. I will also be using node.js, but this should be quite easy to run on other languages.

Getting Started

First we need to install the needed software:

We will be using apt to install these packages, but feel free to use anything else if it works.

First we want to add the apt repository by running these commands, if something doesn’t work, or if you have a system other than ubuntu, click me to see their guide on adding the repo.

wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add -
source /etc/lsb-release
echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list

Or if you’re on Debian:

wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add -
source /etc/os-release
echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list

Now that we added the package we need to update the package lists

sudo apt-get update

After that’s done let’s install everything we need

sudo apt-get install influxdb chronograf telegraf kapacitor

Once those packages are installed, start the InfluxDB services

sudo service influxdb start
sudo service telegraf start
sudo service kapacitor start
sudo service chronograf start

If everything works, then we could set everything up!

First visit http://yourip:8888/ and procced with the default set-up, although this is not the most secure, it will be ok if you don’t open InfluxDB ports to the public.

Now you could go to the hosts list, and click on your host you will see system stats, but we also want application stats.

Adding the node.js integration

First we need to create a new node.js project.

Create a file called server.js and open it in your favorite editor.

Now let’s install some npm packages.

First, install appmetrics to monitor you app

npm install appmetrics

And that’s it! You’ve installed all the needed packages.

Go back to your code and initialize appmetrics and http

const appmetrics = require('appmetrics');
const monitoring = appmetrics.monitor();
const http = require('http');

Awesome! Now if we run our app (node server.js) nothing will happen, that’s because we are recording data but not doing anything with it, let’s change that.

Add this code

monitoring.on('cpu', function (cpu) {
  console.log('[' + new Date(cpu.time) + '] CPU: ' + cpu.process);
});

This will log the CPU percentage.

Your code should look like:

const appmetrics = require('appmetrics');
const monitoring = appmetrics.monitor();
const http = require('http');

monitoring.on('cpu', function (cpu) {
  console.log('[' + new Date(cpu.time) + '] CPU: ' + cpu.process);
});

If you run this, the app will stop without logging the CPU, this is because there is nothing else running in this app, so we need to add something like a http server, you shouldn’t need to do this on a project that already has other code.

Now your code should look like this:

const appmetrics = require('appmetrics');
const monitoring = appmetrics.monitor();
const http = require('http');

monitoring.on('cpu', function (cpu) {
  console.log('[' + new Date(cpu.time) + '] CPU: ' + cpu.process);
});

http.createServer(function (req, res) {
  res.write('Awesome app here!');
  res.end();
}).listen(8080);

Now if you run this app (node server.js) after a few seconds you should see the CPU stats!

But this is only logged in the console, not in Chronograf so we just need to make a request to Telegraf with the stats and then you should be able create a new dashboard in Chronograf and add a panel with the stats.

First we will need to make the app not output the stats to console, but to Telegraf.

Before we write the code we need to edit a small part of the Telegraf config

Open the file /etc/telegraf/telegraf.conf with root (sudo nano /etc/telegraf/telegraf.conf) and uncomment the line where it says [[inputs.http_listener]]. Now save and close the file and run the command sudo service telegraf restart

Then replace the old monitoring.on function with this one

monitoring.on('cpu', function (cpu) {
  const postData = `cpu_percentage,host=AwesomeApp process=${cpu.process},system=${cpu.system} ${cpu.time}`;

  const req = http.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);
    console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
      console.log(`BODY: ${chunk}`);
    });
    res.on('end', () => {
      console.log('No more data in response.');
    });
  });

  req.on('error', (e) => {
    console.error(`problem with request: ${e.message}`);
  });
  req.write(postData);
  req.end();
});

Last, before the monitoring.on function add this object

const options = {
  port: 8186,
  path: '/write?precision=ms',
  method: 'POST',
  headers: {'Content-Type': 'application/x-www-form-urlencoded'}
};

And that’s it! Save the file and try to run it! (node server.js)

Your final code will look something like this:

const appmetrics = require('appmetrics');
const monitoring = appmetrics.monitor();
const http = require('http');

const options = {
  port: 8186,
  path: '/write?precision=ms',
  method: 'POST',
  headers: {'Content-Type': 'application/x-www-form-urlencoded'}
};

monitoring.on('cpu', function (cpu) {
  const postData = `cpu_percentage,host=AwesomeApp process=${cpu.process},system=${cpu.system} ${cpu.time}`;

  const req = http.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);
    console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
      console.log(`BODY: ${chunk}`);
    });
    res.on('end', () => {
      console.log('No more data in response.');
    });
  });

  req.on('error', (e) => {
    console.error(`problem with request: ${e.message}`);
  });
  req.write(postData);
  req.end();
});

http.createServer(function (req, res) {
  res.write('Awesome app here!');
  res.end();
}).listen(8080);

If the code runs with no errors then it should be sending the data to Telegraf! But if you got to Chronograf you won’t yet see this data, that’s because we haven’t yet created a dashboard for your app.

So head over to the Chronograf URL you visited before and press Dashboards -> Create New Dashboard then press Add Data and select telegraf.autogen then select host and then check AwesomeApp then in the fields column select process or system and press the checkmark.

That’s it! You now have a nice way to see the stats for your app!


[05/13/2020]

<- Go Home