Playing with InfluxDB
• Mark Eschbach
At Virta we used InfluxDB to capture a lot of metrics. Although I revived the database from death several times I never really had the time to learn Influx. My recent Stack Overflow question is a great example.
Enhancing my platform at home, at this juncture I would like to use Influx to record various metrics. Originally I
built a Node application to pull thermal sensor data from my workstation. This resulted in the jc
and i2c
drivers
locking up due to polling every second; InfluxDB worked fine with the exception of that time it just stopped responding.
Next step I would like to use Influx to measure request and response wall clock time on a NodeJS application.
This is a canonical problem to be resolved in this space. In the future it would be nice to swap out Influx for other metrics capture platforms or possibly a distributed tracing system like Zipkin. But for now, just capturing metrics provides me with a lot of data.
In node the base setup should be fairly straightforward:
const express = require("express");
const influx = require("influx");
const uuidv4 = require("uuid/v4");
const serverID = uuidv4();
function instrumentRequestTime( database ){
const sink = new influx.InfluxDB({
hosts: [{host:"localhost"}],
database,
batchSize: 100
});
return function( req, resp, next ){
const start = Date.now();
const requestID = uuidv4();
req.id = requestID;
function endedRequest(){
const end = Date.now();
const timeTaken = end - start;
console.log("Time taken: ", timeTaken);
sink.writePoints([{
measurement: "request-response",
tags: {
serverID,
requestID,
path: req.path,
method: req.method,
protocol: req.protocol,
route: "" || "[null]",
statusCode: resp.statusCode
},
fields: { elapsed: timeTaken }
}]);
}
resp.on("finish", endedRequest);
if( next ){
next();
}
}
}
const restIface = express();
restIface.use(instrumentRequestTime("test"));
restIface.get("/delay", function(req,resp){
setTimeout(function(){
resp.json({good:true});
}, 1000);
});
restIface.listen(9999, function(){
console.log("Listening", {serverID});
});
This code works well. It works so well when invoked 300+ times a second it will cause InfluxDB to fall over. At least with version 1.7.5. While searching for solutions it looks like Influx is plagued by a number of problems across different versions. Using 1.7.4 resulted in a database which did not fail on insert.
Changing the route
parameter for the point to route: (req.route || {}).path || "-"
will result in the path show
what a developer would expect to debug. Overall I will try to implement something like this in a future time slot.