author: Emmanuel Odeke and Henry Ventura summary: Node.js Metrics Quickstart environments: Web id: nodemetrics
Duration: 0:07
By the end of this tutorial, we will do these four things to obtain metrics using OpenCensus:
- Create quantifiable
metrics(numerical) that we will record - Create tags that we will associate with our metrics
- Organize our metrics, similar to writing a report, in to a
View - Export our views to a backend (Stackdriver in this case)
Requirements:
- Node.js 6 or above and
npm(already comes with Node.js) - Google Cloud Platform account and project
- Google Stackdriver Monitoring enabled on your project
Positive : For assistance setting up Stackdriver, Click here for a guided codelab.
Duration: 0:06
First, let's create a folder called repl-app for our project and navigate inside it:
mkdir repl-app
cd repl-appThen, let's install the OpenCensus and Stackdriver packages with:
npm install @opencensus/core
npm install @opencensus/exporter-stackdriverDuration: 0:05
Positive : Unsure how to write and execute Node.js code? Click here.
We will be a simple "read-evaluate-print-loop" (REPL) app. In there we'll collect some metrics to observe the work that is going on within this code, such as:
- Latency per processing loop
- Number of lines read
- Line lengths
First, create a file called repl.js:
touch repl.jsNext, put the following code inside of repl.js:
const fs = require('fs');
const readline = require('readline');
// Creates a stream to read our file
const stream = fs.createReadStream("./test.txt");
// Creates an interface to read and process our file line by line
const lineReader = readline.createInterface({ input: stream });
// REPL is the read, evaluate, print and loop
lineReader.on("line", function (line) { // Read
const processedLine = processLine(line); // Evaluate
console.log(processedLine); // Print
});
/**
* Takes a line and process it.
* @param {string} line The line to process
*/
function processLine(line) {
// Currently, it just capitalizes it.
return line.toUpperCase();
}Then, let's create our text file that we'll feed the REPL. Let's call it test.txt:
touch test.txtAnd put the following lines inside of test.txt:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
Now, you can run the code via node repl.js and see it working.
Duration: 00:03
To enable metrics, we'll import a few items from OpenCensus Core package.
const { Stats, MeasureUnit, AggregationType } = require('@opencensus/core');First, we will create the variables needed to later record our metrics.
// Our Stats manager
const stats = new Stats();
// The latency in milliseconds
const mLatencyMs = stats.createMeasureDouble("repl/latency", MeasureUnit.MS, "The latency in milliseconds per REPL loop");
// Counts/groups the lengths of lines read in.
const mLineLengths = stats.createMeasureInt64("repl/line_lengths", MeasureUnit.BYTE, "The distribution of line lengths");Duration: 00:02
We now determine how our metrics will be organized by creating Views. We will also create the variable needed to add extra text meta-data to our metrics -- methodTagKey, statusTagKey, and errorTagKey.
const methodTagKey = "method";
const statusTagKey = "status";
const errorTagKey = "error";
const latencyView = stats.createView(
"demo/latency",
mLatencyMs,
AggregationType.DISTRIBUTION,
[methodTagKey, statusTagKey, errorTagKey],
"The distribution of the latencies",
// Bucket Boundaries:
// [>=0ms, >=25ms, >=50ms, >=75ms, >=100ms, >=200ms, >=400ms, >=600ms, >=800ms, >=1s, >=2s, >=4s, >=6s]
[0, 25, 50, 75, 100, 200, 400, 600, 800, 1000, 2000, 4000, 6000]
);
const lineCountView = stats.createView(
"demo/lines_in",
mLineLengths,
AggregationType.COUNT,
[methodTagKey],
"The number of lines from standard input"
)
const lineLengthView = stats.createView(
"demo/line_lengths",
mLineLengths,
AggregationType.DISTRIBUTION,
[methodTagKey],
"Groups the lengths of keys in buckets",
// Bucket Boudaries:
// [>=0B, >=5B, >=10B, >=15B, >=20B, >=40B, >=60B, >=80, >=100B, >=200B, >=400, >=600, >=800, >=1000]
[0, 5, 10, 15, 20, 40, 60, 80, 100, 200, 400, 600, 800, 1000]
)We will later use this tag key, to record what method is being invoked. In our scenario, we will only use it to record that "repl" is calling our data.
Again, this is arbitrary and purely up the user. For example, if we wanted to track what operating system a user is using, we could create a tag key "operating_system" and later, when we use it, we will be given an opportunity to enter values such as "windows" or "mac".
Now we will record the desired metrics. To do so, we will use stats.record() and pass in our measurements.
lineReader.on("line", function (line) {
// Registers the Tags for our measurements
const tags = {method: "repl", status: "OK"};
try {
// ...
stats.record({
measure: mLineLengths,
tags,
value: processedLine.length
});
} catch (err) {
tags.status = "ERROR";
tags.error = err.message;
}
stats.record({
measure: mLatencyMs,
tags,
value: (new Date()) - startTime.getTime()
});
// Restarts the start time for the REPL
startTime = new Date();
});Duration: 00:01
We will be adding the Stackdriver package: @opencensus/exporter-stackdriver, create the Stackdriver exporter and pass it to the stats manager:
const { Stats, MeasureUnit, AggregationType } = require('@opencensus/core');
const { StackdriverStatsExporter } = require('@opencensus/exporter-stackdriver');
const fs = require('fs');
const readline = require('readline');
// Create the Stats manager
const stats = new Stats();
// Add your project id to the Stackdriver options
const exporter = new StackdriverStatsExporter({projectId: "your-project-id"});
// Pass the created exporter to Stats
stats.registerExporter(exporter);Duration: 00:00
Once registed, the Stackdriver exporter will be notified on every view registered and measurement recorded. It will translate and send the collected data on its own. Now, simply go to the monitoring console and check the collected data.
Each bar in the heatmap represents one run of the program, and the colored components of each bar represent part of the latency distribution.