Skip to content
This repository was archived by the owner on Apr 21, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ module.exports = {
, REQUEST_WITH_CREDENTIALS: false
, BACKOFF_PERIOD: 3000
, FAILED_BUF_RETENTION_LIMIT: 10000000
, RETRY_TIMES: 3
};
28 changes: 21 additions & 7 deletions lib/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,20 @@ function Logger(key, options) {
this._flushLimit = configs.FLUSH_BYTE_LIMIT;
}

if (options.retryTimes && Number.isInteger(options.retryTimes)) {
this._retryTimes = options.retryTimes;
} else {
this._retryTimes = configs.RETRY_TIMES;
}

if (options.flushInterval && Number.isInteger(options.flushInterval)) {
this._flushInterval = options.flushInterval;
} else {
this._flushInterval = configs.FLUSH_INTERVAL;
}

if (options.retryTimeout && Number.isInteger(options.retryTimeout)) {
this._retryTimeout = options._retryTimeout;
this._retryTimeout = options.retryTimeout;
} else {
this._retryTimeout = configs.BACKOFF_PERIOD;
}
Expand All @@ -131,6 +137,7 @@ function Logger(key, options) {
this._buf = [];
this._meta = {};
this._isLoggingBackedOff = false;
this._attempts = 0;

this.source = {
hostname: options.hostname || os.hostname()
Expand Down Expand Up @@ -313,6 +320,7 @@ Logger.prototype._sendRequest = function(config, instance) {
.then((response) => {
if (response && response.status === 200) {
instance._isLoggingBackedOff = false;
instance._attempts = 0;
return instance.callback(null, {
lines: instance.__dbgLines
, httpStatus: response.status
Expand All @@ -324,8 +332,14 @@ Logger.prototype._sendRequest = function(config, instance) {
.catch((err) => {
if (err.response) instance._isLoggingBackedOff = true;
// Return to buffer
instance._buf = JSON.parse(config.data).ls;
instance._bufByteLength = instance.__bufSizePreserve;
instance._buf = instance._buf.concat(JSON.parse(config.data).ls);
instance._bufByteLength += instance.__bufSizePreserve;
if (!instance._flusher && instance._attempts < instance._retryTimes) {
instance._attempts += 1;
instance._flusher = setTimeout(() => {
instance._flush(instance.callback);
}, instance._retryTimeout);
}

let message = 'An error occured while making the request.';
if (err && err.response) {
Expand All @@ -339,14 +353,15 @@ Logger.prototype._flush = function(callback) {
if (!callback || typeof callback !== 'function') {
throw new Error('flush function expects a callback');
}

clearTimeout(this._flusher);
this._flusher = null;

if (this._buf.length === 0) {
debug('Nothing to flush');
return callback();
}

clearTimeout(this._flusher);
this._flusher = null;

const data = stringify({ e: 'ls', ls: this._buf });
this._req.qs.now = Date.now();

Expand Down Expand Up @@ -374,7 +389,6 @@ Logger.prototype._flush = function(callback) {
this._sendRequest(_config, this);
};


/*
* Populate short-hand for each supported Log Level
*/
Expand Down
65 changes: 41 additions & 24 deletions test/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,77 +532,94 @@ describe('ambient meta', function() {

describe('HTTP Exception Handling', function() {
let httpExcServer;
let countHits = 0;
let countServertHits = 0;
let statusCode = 302;
let edgeCaseFlag = false;
let willEventuallySucceed = false;

const port = 1336;
const retryTimeout = 500;
const retryTimes = 2;
const options = testHelper.createOptions({
port: port
, retryTimeout
, retryTimes

});

let whenSuccessConnection = 0;
beforeEach(function(done) {
httpExcServer = http.createServer(function(req, res) {
if (edgeCaseFlag && countHits >= 1) {
if (willEventuallySucceed && countServertHits >= 1) {
statusCode = 200;
whenSuccessConnection = Date.now();
}
res.writeHead(statusCode, {'Content-Type': 'text/plain'});
res.write('Hello World');
res.end(() => {++countHits;});
res.end(() => {++countServertHits;});
});
httpExcServer.on('listening', done);
httpExcServer.listen(port);
});

afterEach(function(done) {
countHits = 0;
countServertHits = 0;
httpExcServer.close();
httpExcServer.on('close', function() {
httpExcServer = null;
done();
});
willEventuallySucceed = false;
sentMeta = [];
body = '';
statusCode = 302;
whenSuccessConnection = 0;
});
const httpExcLogger = Logger.createLogger(testHelper.apikey, options);

it('when fails to connect, it should put the _isLoggingBackedOff flag on', function(done) {
it('when fails to connect, it should retry within retryTimeout period', function(done) {
this.timeout(retryTimeout * 3 + 400);
willEventuallySucceed = true;
const logSentTime = Date.now();
httpExcLogger.debug('The line');
setTimeout(function() {
assert(httpExcLogger._isLoggingBackedOff === true);
assert(whenSuccessConnection - logSentTime >= retryTimeout);
assert(httpExcLogger._buf.length === 0);
done();
}, retryTimeout * 3 + 200);
});
it('when fails to connect, it should retry only options.retryTimes and save the log until the next one comes in', function(done) {
this.timeout(retryTimeout * 4 + 400);
httpExcLogger.debug('The line');

setTimeout(function() {
assert(countServertHits === retryTimes + 1);
assert(httpExcLogger._buf.length === 1);
done();
}, configs.FLUSH_INTERVAL + 200);
}, retryTimeout * 4);
});
it('*!!depends on the previouce test!!* Send the log after the previouse one has failed', function(done) {
this.timeout(3500);
edgeCaseFlag = true;
countHits = 1;
it('*!!depends on the previous test!!* Include the log from the previously failed flush', function(done) {
this.timeout(retryTimeout + 300);
willEventuallySucceed = true;
countServertHits = 1;
const thisSendTime = Date.now();
httpExcLogger.debug('The second line');
assert(httpExcLogger._buf.length === 2);
setTimeout(function() {
assert(whenSuccessConnection - thisSendTime >= configs.BACKOFF_PERIOD);
assert(httpExcLogger._buf.length === 0);
assert(httpExcLogger._isLoggingBackedOff === false);
assert(whenSuccessConnection - thisSendTime >= retryTimeout);
done();
}, configs.BACKOFF_PERIOD + 200);
}, retryTimeout + 200);
});
it('*!!depends on the previouce test!!* Should clear backoff after success', function(done) {
it('*!!depends on the previous test!!* Should clear backoff after success and nullify attempts', function(done) {
this.timeout(3500);
edgeCaseFlag = true;
countHits = 1;
willEventuallySucceed = true;
countServertHits = 1;
const thisSendTime = Date.now();
httpExcLogger.debug('The second line');
setTimeout(function() {
assert(whenSuccessConnection - thisSendTime < configs.BACKOFF_PERIOD);
assert(httpExcLogger._buf.length === 0);
assert(httpExcLogger._isLoggingBackedOff === false);
assert(whenSuccessConnection - thisSendTime < retryTimeout);
assert(httpExcLogger._attempts === 0);
done();
}, configs.BACKOFF_PERIOD + 200);
}, retryTimeout + 200);
});
it('should not exceed the failed buf retention limit', function(done) {
this.timeout(3500);
Expand All @@ -616,7 +633,7 @@ describe('HTTP Exception Handling', function() {
const byteSizeOfBuf = sizeof(tooManyFails._buf[0]) * tooManyFails._buf.length;
assert(byteSizeOfBuf <= opts.failedBufRetentionLimit);
done();
}, configs.BACKOFF_PERIOD + 200);
}, retryTimeout + 200);
});
it('flushAll should recieve err message', function(done) {
const opts = testHelper.createOptions({port: port});
Expand Down
2 changes: 2 additions & 0 deletions test/testHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ module.exports.createOptions = function({
, failedBufRetentionLimit = null
, retryTimeout = null
, flushInterval = null
, retryTimes = 3
, shimProperties
} = {}) {
return {
Expand All @@ -116,6 +117,7 @@ module.exports.createOptions = function({
, failedBufRetentionLimit: failedBufRetentionLimit
, retryTimeout: retryTimeout
, flushInterval: flushInterval
, retryTimes
, shimProperties
};
};