Skip to content
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 config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module.exports = {
DEBUG: false,
RUM_SCRIPT_URL: 'https://stckjs.stackify.com/stckjs.js',
RUM_KEY: '',
EVENT_ERROR: 'stackifyError',
_checkRum: function (settings) {
let rumScriptUrl = (typeof(process.env['RETRACE_RUM_SCRIPT_URL']) !== 'undefined') ? process.env['RETRACE_RUM_SCRIPT_URL'] : null;
if (rumScriptUrl) {
Expand Down
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ var api = require('./lib/api'), // wrappers for API calls
exception = require('./lib/exception'), // exception handler module
logger = require('./lib/logger'), // logging methods module
CONFIG = require('./config/config'), // config
event = require('./lib/event'), // event emitter module
RUM = require('./lib/rum'); // Rum

event.on(CONFIG.EVENT_ERROR, logger.methods.push);

module.exports = {
// start sending logs
start: function (options) {
Expand Down
129 changes: 2 additions & 127 deletions lib/api.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
var os = require('os'),
async = require('async'),
sender = require('./sender'),
logger = require('./logger'),
CONFIG = require('../config/config'),
helpers = require('./helpers'),
debug = require('./debug'),
unix_socket = require('./transport/unix-socket'),
http_client = require('../lib/transport/http-client'),
AgentBase = require('../lib/transport/agent-base'),
lastApiError;
debug = require('./debug');

module.exports.initialize = function (settings) {
CONFIG._setupConfig(settings)
CONFIG._validateConfig(settings)
this.methods.transportType(settings)
}
module.exports.lastApiError = lastApiError;
module.exports.methods = {

module.exports.methods = {
identifyApp: function identifyApp(settings) {
var options = {},
appname = settings.appName || helpers.getAppName(),
Expand All @@ -29,11 +23,8 @@ module.exports.methods = {
},
callback = function (data) {
debug.write('[Log] Successfully identified');

CONFIG.APP_DETAILS = data.appData;

logger.methods.start();

},
fail = function () {
debug.write('[Log] Identification failed');
Expand All @@ -54,62 +45,6 @@ module.exports.methods = {
debug.write('[Log] Identifying the app');
sender.send(options, callback, fail);
},

/*
*** posting logs to API ***
*** messages - array of messages ***
*** cb - callback function ***
*** shutdown - optional parameter, indicating if we should retry request attempts when API is down ***
*/
postLogs: function postLogs(messages, cb, shutdown) {
var delay = 0, // scheduled delay when postLogs call failed
options = helpers.getOptions(CONFIG.LOG_SAVE_PATH, helpers.getPostBody(messages), CONFIG.PROXY),

//retry the request if it failed
fail = function (code) {
var sinceFirstError;
debug.write('[Log] Sending logs failed');
if (code === 401) {
delay = CONFIG.DELAY.FIVE_MINUTES_DELAY;
lastApiError = new Date().getTime();
} else {
lastApiError = lastApiError || new Date().getTime();
sinceFirstError = new Date().getTime() - lastApiError;
delay = Math.min(Math.max(sinceFirstError, CONFIG.DELAY.ONE_SECOND_DELAY), CONFIG.DELAY.ONE_MINUTE_DELAY);
}

setTimeout(function () {
sender.send(options, cb, fail);
}, delay);
};
debug.write('[Log] Sending logs: batch size: ' + messages.length + ' messages');
sender.send(options, cb, shutdown ? null : fail);
},
/*
*** posting logs synchronously in case if server is about to close ***
*/
postLogsSync: function postLogsSync(messages) {
var cb = function (response) {
debug.write('postLogsSync response: ' + response)
}
switch(CONFIG.TRANSPORT) {
case 'agent_socket':
module.exports.methods.sendToSocket(messages, cb); // send to unix socket
break;
case 'agent_http':
module.exports.methods.sendToHttpClient(messages, cb); // send to http
break;
case 'log':
var options = {
url: CONFIG.PROTOCOL + '://' + CONFIG.HOST + CONFIG.LOG_SAVE_PATH,
headers : helpers.getHeaders(),
data: helpers.getPostBody(messages)
};
sender.sendSync(options);
break;
}
},

/*
*** Function that will select what transport type to use
*** @settings {Object} contains key-value pairs data such as transport, appName, apiKey, etc.
Expand Down Expand Up @@ -141,65 +76,5 @@ module.exports.methods = {
module.exports.methods.identifyApp(settings);
break;
}
},

/**
*** Send log messages to Linux agent via unix domain socket
*** messages - array of messages
*** cb - callback function
*/
sendToSocket: function sendToSocket(messages, cb) {
try {
if (!messages) {
cb({error: true, message: 'No messages found.'}, null);
return;
}
var log_group = AgentBase.prototype.build_message(messages);
// Serializes to a UInt8Array.
var data = log_group.serializeBinary();
async.retry({
times: CONFIG.MAX_RETRIES,
interval: CONFIG.DELAY.SOCKET_DELAY
}, function (callback) { return unix_socket.send(data, cb) },
function(err, result) {
if (err) {
var err_message = '[Stackify Node Log API] sendToSocket() - Sending failed:' + JSON.stringify(err, null, 2);
debug.writeSync(err_message);
throw new Error(err); // Error still thrown after retrying N times, so rethrow.
}
});
} catch (error) {
debug.writeSync('\n[Stackify Node Log API] sendToSocket() - Sending failed. error stack:' + JSON.stringify(error));
}
},

/**
*** Send log messages(protobuf) via http request
*** messages - array of messages
*** cb - callback function
*/
sendToHttpClient: function sendToHttpClient(messages, cb) {
try {
if (!messages) {
cb({error: true, message: 'No messages found.'}, null);
return;
}
var log_group = AgentBase.prototype.build_message(messages);
// Serializes to a UInt8Array.
var data = log_group.serializeBinary();
async.retry({
times: CONFIG.MAX_RETRIES,
interval: CONFIG.DELAY.SOCKET_DELAY
}, function (callback) { return http_client.post(data, cb) },
function(err, result) {
if (err) {
var err_message = '[Stackify Node Log API] sendToHttpClient() - Sending failed:' + JSON.stringify(err, null, 2);
debug.writeSync(err_message);
throw new Error(err); // Error still thrown after retrying N times, so rethrow.
}
});
} catch (error) {
debug.writeSync('\n[Stackify Node Log API] sendToHttpClient() - Sending failed. error stack:' + JSON.stringify(error));
}
}
}
1 change: 0 additions & 1 deletion lib/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ var url = require('url'),
os = require('os'),

helpers = require('./helpers'),
exc = require('./exception'),
CONFIG = require('../config/config'),

// object that contains all the errors and their numbers logged during the current minute
Expand Down
4 changes: 4 additions & 0 deletions lib/event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var EventEmitter = require('events').EventEmitter
, event = new EventEmitter();

module.exports = event;
3 changes: 1 addition & 2 deletions lib/exception.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var error = require('./error'),
logger = require('./logger'),
var logger = require('./logger'),
CONFIG = require('../config/config');

module.exports = {
Expand Down
24 changes: 12 additions & 12 deletions lib/logger.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var api = require('./api'),
var transport = require('./transport'),
schedule = require('node-schedule'),
CONFIG = require('../config/config'),
helpers = require('./helpers'),
Expand Down Expand Up @@ -30,20 +30,20 @@ var api = require('./api'),
/**
* This function will handle the selection of the transport
*/
transportSelector = function (transport, data, cb, shutdown) {
if (transport === 'agent_socket') {
api.methods.sendToSocket(data, cb); // send to unix domain socket
} else if (transport === 'agent_http') {
api.methods.sendToHttpClient(data, cb); // send to http request
transportSelector = function (transportConfig, data, cb, shutdown) {
if (transportConfig === 'agent_socket') {
transport.methods.sendToSocket(data, cb); // send to unix domain socket
} else if (transportConfig === 'agent_http') {
transport.methods.sendToHttpClient(data, cb); // send to http request
} else {
api.methods.postLogs(data, cb, shutdown); // send directly to stackify-api server
transport.methods.postLogs(data, cb, shutdown); // send directly to stackify-api server
}
},
/* handler for sending logs, accepts callback function and boolean variable
indicating if we should run process.exit() after the callback
*/
sendLogs = function (cb, shutdown) {
var transport = CONFIG && CONFIG.TRANSPORT ? CONFIG.TRANSPORT.trim().toLowerCase() : null
var transportConfig = CONFIG && CONFIG.TRANSPORT ? CONFIG.TRANSPORT.trim().toLowerCase() : null
try {
// If Stackify Application details have not been received, skip logging.
if (!hasAppDetails()) {
Expand All @@ -62,19 +62,19 @@ var api = require('./api'),
if (response && response.success) {
storage = storage.slice(chunk); // remove this chunk from the queue
length -= chunk;
api.lastApiError = 0; // reset the last HTTP error
transport.lastApiError = 0; // reset the last HTTP error
if (length) {
chunk = Math.min(length, CONFIG.MSG.MAX_BATCH_SIZE);
data = storage.slice(0, chunk);
transportSelector(transport, data, success, shutdown)
transportSelector(transportConfig, data, success, shutdown)
}
}
};
debug.write('Checking the queue: ' + data.length + ' messages');

if (data.length && CONFIG.APP_DETAILS) {
// queue has messages and the app is authorized - set the flag, post data
transportSelector(transport, data, success, shutdown)
transportSelector(transportConfig, data, success, shutdown)
}
} catch (error) {
debug.writeSync('\nSending failed. error stack:' + JSON.stringify(error));
Expand Down Expand Up @@ -206,7 +206,7 @@ module.exports = {
// drain the queue and send the messages before server closes
drain: function drain() {
if (storage.length) {
api.methods.postLogsSync(storage);
transport.methods.postLogsSync(storage);
} else {
debug.close();
}
Expand Down
20 changes: 10 additions & 10 deletions lib/sender.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
###### @fail {Function} **Optional** function to be executed if request wasn't succesful
Low level function for sending http/https requests
*/
var http = require('http'),
util = require('util'),

var util = require('util'),
request = require('request'),
requestSync = require('sync-request'),

api = require('./api'),
debug = require('./debug'),
exc = require('./exception'),
logger = require('./logger'),
event = require('./event'),
CONFIG = require('../config/config.js');

var sender = module.exports = {};

module.exports.request = request;
module.exports.requestSync = requestSync;

module.exports.send = function send(options, cb, fail) {

var callback = function (error, response, body) {
Expand All @@ -32,17 +32,17 @@ module.exports.send = function send(options, cb, fail) {
}
} else {
debug.write('Request failed\n', util.inspect(error.stack));
logger.methods.push('error', error.message, [{error: error}]);
event.emit(CONFIG.EVENT_ERROR, 'error', error.message, [{error: error}]);
}
};

request(options, callback);
sender.request(options, callback);
debug.writeRequest(options);
};

module.exports.sendSync = function sendSync(options) {
try {
var res = requestSync('POST', options.url, {
var res = sender.requestSync('POST', options.url, {
json: options.data,
headers: options.headers
});
Expand Down
Loading