logzio-nodejs
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -1,2 +0,1 @@ | ||
var request = require('request'); | ||
@@ -11,3 +10,3 @@ var stringifySafe = require('json-stringify-safe'); | ||
if (options.protocol != 'http' && options.protocol != 'https') | ||
if (options.protocol && options.protocol != 'http' && options.protocol != 'https') | ||
throw new Error('Invalid protocol defined'); | ||
@@ -17,12 +16,23 @@ | ||
this.protocol = options.protocol || 'http'; | ||
this.host = 'listener.logz.io'; | ||
this.port = this.protocol == 'http' ? 8090 : 8091; | ||
this.host = options.host || 'listener-4.logz.io'; | ||
this.port = this.protocol == 'http' ? 8070 : 8071; | ||
this.userAgent = 'Logzio-Logger NodeJS'; | ||
this.type = 'nodejs'; | ||
this.type = options.type || 'nodejs'; | ||
this.sendIntervalMs = options.sendIntervalMs || 10*1000; | ||
this.bufferSize = options.bufferSize || 100; | ||
this.debug = options.debug || false; | ||
this.numberOfRetries = options.numberOfRetries || 3; | ||
this.callback = options.callback || this._defaultCallback; | ||
this.timeout = options.timeout; | ||
// build the url for logging | ||
this.url = this.protocol + '://' + this.host + ':' + this.port + '?token=' + this.token; | ||
this.messages = []; | ||
this.bulkId = 1; | ||
}; | ||
exports.createLogger = function (options) { | ||
return new LogzioLogger(options); | ||
var l = new LogzioLogger(options); | ||
l._timerSend(); | ||
return l; | ||
}; | ||
@@ -39,41 +49,118 @@ | ||
LogzioLogger.prototype.log = function (msg, callback) { | ||
LogzioLogger.prototype._defaultCallback = function(err) { | ||
if (err) { | ||
console.error("logzio-logger error: "+err, err); | ||
} | ||
} | ||
var requestBody = undefined; | ||
if (typeof msg === 'string') { | ||
var msgJson = { message: msg }; | ||
if (this.type) msgJson.type = this.type; | ||
requestBody = jsonToString(msgJson); | ||
LogzioLogger.prototype._timerSend = function() { | ||
if (this.messages.length > 0) { | ||
this._debug("Woke up and saw " + this.messages.length + " messages to send. Sending now..."); | ||
this._popMsgsAndSend() | ||
} | ||
else if (typeof msg === 'object') { | ||
if (!msg.type && this.type) msg.type = this.type; | ||
requestBody = jsonToString(msg); | ||
var mythis = this; | ||
setTimeout( | ||
function() { | ||
mythis._timerSend(); | ||
}, | ||
this.sendIntervalMs | ||
); | ||
} | ||
LogzioLogger.prototype.log = function(log) { | ||
if (typeof log === 'string') { | ||
log = {message: msg}; | ||
if (this.type) log.type = this.type; | ||
} | ||
log.type = this.type; | ||
this.messages.push(log); | ||
if (this.messages.length >= this.bufferSize) { | ||
this._debug("Buffer is full - sending bulk"); | ||
this._popMsgsAndSend() | ||
} | ||
} | ||
LogzioLogger.prototype._popMsgsAndSend = function() { | ||
var bulk = this._createBulk(this.messages) | ||
this._debug("Sending bulk #"+bulk.id); | ||
this._send(bulk) | ||
this.messages = []; | ||
} | ||
LogzioLogger.prototype._createBulk = function(msgs) { | ||
var bulk = {}; | ||
// creates a new copy of the array. Objects references are copied (no deep copy) | ||
bulk.msgs = msgs.slice(); | ||
bulk.attemptNumber = 1; | ||
bulk.sleepUntilNextRetry = 2*1000; | ||
bulk.id = this.bulkId++; | ||
return bulk; | ||
} | ||
LogzioLogger.prototype._messagesToBody = function(msgs) { | ||
var body = ""; | ||
for (var i = 0; i < msgs.length; i++) { | ||
body = body + jsonToString(msgs[i]) + "\n"; | ||
} | ||
return body; | ||
} | ||
LogzioLogger.prototype._debug = function(msg) { | ||
if (this.debug) console.log("logzio-nodejs: "+msg); | ||
} | ||
LogzioLogger.prototype._send = function(bulk) { | ||
var mythis = this; | ||
function tryAgainIn(sleepTimeMs) { | ||
mythis._debug("Bulk #"+bulk.id+" - Trying again in "+sleepTimeMs+ "[ms], attempt no. "+bulk.attemptNumber); | ||
setInterval(function() { | ||
mythis._send(bulk) | ||
}, sleepTimeMs); | ||
} | ||
var body = this._messagesToBody(bulk.msgs); | ||
var options = { | ||
uri: this.url, | ||
method: 'POST', | ||
body: requestBody, | ||
body: body, | ||
headers: { | ||
'host': this.host, | ||
'accept': '*/*', | ||
'user-agent': this.userAgent, | ||
'content-type': 'text/plain', | ||
'content-length': Buffer.byteLength(requestBody) | ||
'host': this.host, | ||
'accept': '*/*', | ||
'user-agent': this.userAgent, | ||
'content-type': 'text/plain', | ||
'content-length': Buffer.byteLength(body) | ||
} | ||
}; | ||
if (typeof this.timeout != 'undefined') { | ||
options.timeout = this.timeout; | ||
} | ||
callback = callback || function() {}; | ||
var callback = this.callback; | ||
try { | ||
request(options, function (err, res, body) { | ||
request.post(options, function (err, res, body) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
// In rare cases server is busy | ||
if (err.code === 'ETIMEDOUT' || err.code == 'ECONNRESET'){ | ||
if (bulk.attemptNumber >= mythis.numberOfRetries) { | ||
callback(new Error("Failed after "+bulk.attemptNumber+" retries on error = "+err, err)); | ||
} else { | ||
var sleepTimeMs = bulk.sleepUntilNextRetry; | ||
bulk.sleepUntilNextRetry = bulk.sleepUntilNextRetry * 2; | ||
bulk.attemptNumber++; | ||
tryAgainIn(sleepTimeMs) | ||
} | ||
} else { | ||
callback(err); | ||
} | ||
} else { | ||
var responseCode = res.statusCode.toString(); | ||
if (responseCode !== '200') { | ||
callback(new Error('There was a problem with the request.\nResponse: ' + responseCode + ": " + body.toString())); | ||
} else { | ||
mythis._debug("Bulk #"+bulk.id+" - sent successfully"); | ||
callback(); | ||
} | ||
} | ||
var responseCode = res.statusCode.toString(); | ||
if (responseCode !== '200') | ||
callback(new Error('There was a problem with the request.\nReceived http response code: ' + responseCode)); | ||
callback(); | ||
}); | ||
@@ -84,2 +171,2 @@ } | ||
} | ||
}; | ||
} |
{ | ||
"name": "logzio-nodejs", | ||
"description": "A nodejs implementation for sending logs to Logz.IO cloud service", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"author": "Gilly Barr <gilly@logz.io>", | ||
"contributors": [ | ||
{ | ||
"name": "Gilly Barr", | ||
"email": "gillyb@gmail.com" | ||
}, | ||
{ | ||
"name": "Asaf Mesika", | ||
"email": "amesika@logz.io" | ||
} | ||
], | ||
"repository": { | ||
@@ -21,6 +31,18 @@ "type": "git", | ||
}, | ||
"devDependencies": { | ||
"assert": "^1.3.0", | ||
"async": "1.4.2", | ||
"mocha": "^2.3.3", | ||
"nock": "^2.13.0", | ||
"should": "^7.1.0", | ||
"sinon": "^1.17.1" | ||
}, | ||
"main": "./lib/logzio-nodejs", | ||
"engines": { | ||
"node": ">= 0.8.0" | ||
}, | ||
"license": "(Apache-2.0)", | ||
"scripts": { | ||
"test": "node_modules/.bin/mocha -w" | ||
} | ||
} |
# logzio-nodejs | ||
NodeJS logger for LogzIO | ||
NodeJS logger for LogzIO. | ||
The logger stashes the log messages you send into an array which is sent as a bulk once it reaches its size limit (100 messages) or time limit (10 sec) in an async fashion. | ||
It contains a simple retry mechanism which upon connection reset (server side) or client timeout, wait a bit (default interval of 2 seconds), and try this bulk again (it does not block other messages from being accumulated and sent (async). The interval increases by a factor of 2 between each retry, until we reached the maximum allowed attempts (3). | ||
By default any error is logged to the console. This can be changed by supplying a callback function. | ||
Sample usage : | ||
## Sample usage | ||
```javascript | ||
@@ -24,1 +28,16 @@ var logger = require('logzio-nodejs').createLogger({ | ||
``` | ||
## Options | ||
* **token** | ||
Mandatory. Your API logging token. Look it up in the Device Config tab in Logz.io | ||
* **type** - Log type. Help classify logs into different classifications | ||
* **protocol** - 'http' or 'https'. Default: http | ||
* **sendIntervalMs** - Time in milliseconds to wait between retry attempts. Default: 2000 (2 sec) | ||
* **bufferSize** - The maximum number of messages the logger will accumulate before sending them all as a bulk. Default: 100. | ||
* **numberOfRetries** - The maximum number of retry attempts. Default: 3 | ||
* **debug** - Should the logger print debug messages to the console? Default: false | ||
* **callback** - a callback function called when an unrecoverable error has occured in the logger. The function API is: function(err) - err being the Error object. | ||
* **timeout** - the read/write/connection timeout in milliseconds. | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25428
7
289
43
6
1