From 6882ddfb65fbcf9e03af094d400f9c57652c6b41 Mon Sep 17 00:00:00 2001 From: Joey Cumines Date: Sat, 12 May 2018 02:46:50 +1000 Subject: [PATCH 1/2] feat(logResponse): add more useful log method for http responses that prints out headers (that have influxdb errors) --- lib/influxdb.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/lib/influxdb.js b/lib/influxdb.js index 4be292a..1638d70 100644 --- a/lib/influxdb.js +++ b/lib/influxdb.js @@ -142,7 +142,73 @@ function millisecondsSince(start) { InfluxdbBackend.prototype.log = function (msg) { util.log('[influxdb] ' + msg); -} +}; + +InfluxdbBackend.prototype.logResponse = function (msg, response) { + var output = '' + msg; + + if (output === '') { + output = 'response'; + } + + output = JSON.stringify(output); + + if (response !== null && typeof response === 'object') { + // build status code line + var temp = ''; + + if (typeof response.statusCode === 'number' && response.statusCode > 0) { + temp += response.statusCode; + } + + output += ' ' + JSON.stringify(temp); + + // build status text + temp = ''; + + if (typeof response.statusText === 'string' && response.statusText !== '') { + temp += response.statusText + } + + output += ' ' + JSON.stringify(temp); + + // build method + address + temp = ''; + + if (response.request !== null && typeof response.request === 'object') { + if (typeof response.request.method === 'string' && response.request.method !== '') { + temp += response.request.method; + } + + if (typeof response.request.url === 'string' && response.request.url !== '') { + if (temp !== '') { + temp += ' '; + } + + temp += response.request.url; + } + } + + output += ' ' + JSON.stringify(temp); + + // build headers + temp = []; + + if (response.headers !== null && typeof response.headers === 'object') { + for (var key in response.headers) { + if (!response.headers.hasOwnProperty(key)) { + continue; + } + + temp.push('' + key + ' = ' + response.headers[key]); + } + } + + output += ' ' +JSON.stringify(temp.join('; ')); + } + + this.log(output); +}; InfluxdbBackend.prototype.logDebug = function (msg) { if (this.debug) { @@ -156,7 +222,7 @@ InfluxdbBackend.prototype.logDebug = function (msg) { util.log('[influxdb] (DEBUG) ' + string); } -} +}; /** * Flush strategy handler @@ -565,7 +631,7 @@ InfluxdbBackend.prototype.httpPOST_v14 = function (points) { self.influxdbStats.httpResponseTime = millisecondsSince(startTime); if (status >= 400) { - self.log(protocolName + ' Error: ' + status); + self.logResponse(protocolName + ' Error', res); } }); From 8d2fb361e099d21b29985acf7e545ff550bbf7a2 Mon Sep 17 00:00:00 2001 From: Joey Cumines Date: Sat, 12 May 2018 03:36:43 +1000 Subject: [PATCH 2/2] fix(influxdb-sets): avoid attempting to send more than one data type (e.g. unique strings) as it will fail / not work properly --- lib/influxdb.js | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/lib/influxdb.js b/lib/influxdb.js index 1638d70..be148f0 100644 --- a/lib/influxdb.js +++ b/lib/influxdb.js @@ -264,9 +264,48 @@ InfluxdbBackend.prototype.processFlush = function (timestamp, metrics) { } for (set in sets) { - sets[set].map(function (v) { - points.push(self.assembleEvent(set, [{value: v, time: timestamp,type:"set"}])); - }) + // influxdb only allows one type per measurement per shard - check for any non-int values + var nonIntInSet = false; + for (var i = 0; i < sets[set].length; i++) { + var setValueStr = '' + sets[set][i]; // take the string value for checking... + var setValueInt = parseInt(setValueStr); // convert to int (well... float...) + // and check it's sane + if (!isFinite(setValueInt) || isNaN(setValueInt)) { + nonIntInSet = true; + break; + } + // convert setValueInt back to a string + setValueInt = '' + setValueInt; + // compare with the original, which is difficult because javascript numbers == float :( + if (setValueInt.length !== setValueStr.length) { + nonIntInSet = true; + break; + } + for (var j = 0; j < setValueStr.length; j++) { + var setValueStrChar = setValueStr.charAt(j); + // we only check the first 5 chars for exact match, after that we just check if numeric + if (j >= 5) { + if (setValueStrChar < '0' || setValueStrChar > '9') { + nonIntInSet = true; + break; + } + } else { + if (setValueInt.charAt(j) !== setValueStrChar) { + nonIntInSet = true; + break; + } + } + } + if (nonIntInSet) { + break; + } + } + if (!nonIntInSet) { // only add the original set values if they are all ints + sets[set].map(function (v) { + points.push(self.assembleEvent(set, [{value: v, time: timestamp,type:"set"}])); + }); + } + // add the actual count points.push(self.assembleEvent(set , [{value: sets[set].length, time: timestamp,type:"set_count"}])); }