Skip to content

Commit 339a76b

Browse files
Debugging mode + Env option minor fix
1 parent d0b7a4a commit 339a76b

File tree

9 files changed

+124
-18
lines changed

9 files changed

+124
-18
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ The following options could be passed. 'apiKey' is the only one that required:
2828
* __env:__ environment name
2929
* __exitOnError:__ boolean flag indicating whether to shutdown the server after logging an uncaught exception, defaults to false
3030
* __proxy:__ proxy server if you want to send requests via proxy.
31+
* __debug:__ boolean flag, turning on the debug mode. When set to true the log file (`stackify-debug.log`) is created in the working directory and all of the library actions is being written to it, defaults to false.
32+
3133

3234
*Notice:* stackify-logger sends synchronous requests if you call `process.exit()`. Sending via proxy wouldn't be possible in this case.
3335

index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var api = require('./lib/api'), // wrappers for API calls
2+
debug = require('./lib/debug'), // debug mode module
23
exception = require('./lib/exception'), // exception handler module
34
logger = require('./lib/logger'), // logging methods module
45
CONFIG = require('./config/config');
@@ -7,6 +8,7 @@ module.exports = {
78
// start sending logs
89
start: function (options) {
910
CONFIG.SELECTED_LOGGER = CONFIG.LOGGER_VERSION;
11+
debug.set(options.debug);
1012
api.methods.identifyApp(options);
1113
exception.catchException(options.exitOnError || false);
1214
exception.gracefulExitHandler();
@@ -18,13 +20,14 @@ module.exports = {
1820
info: logger.methods.info,
1921
warn: logger.methods.warn,
2022
error: logger.methods.error,
21-
23+
2224
//common method for handling logged messages
2325
push: logger.methods.push,
2426
// setting logger name to Winston logger if it's used
2527
setLoggerName: function (name) {
2628
if (name === 'Winston') {
2729
CONFIG.SELECTED_LOGGER = CONFIG.WINSTON_LOGGER_VERSION;
30+
debug.write('Winston Stackify Transport added');
2831
}
2932
},
3033

lib/api.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var os = require('os'),
55
CONFIG = require('../config/config'),
66
exc = require('./exception'),
77
helpers = require('./helpers'),
8+
debug = require('./debug'),
89

910
lastApiError;
1011

@@ -18,11 +19,11 @@ module.exports.methods = {
1819
AppName: appname,
1920
ConfiguredAppName: appname,
2021
AppLocaton: process.env.PWD,
21-
ConfiguredEnvName: settings ? settings.env : (process.env.NODE_ENV || null)
22+
ConfiguredEnvName: settings && settings.env ? settings.env : (process.env.NODE_ENV || null)
2223
},
2324
opt = helpers.getOptions(CONFIG.IDENTIFY_PATH, body, settings ? settings.proxy : undefined),
2425
callback = function (data) {
25-
console.log('successfully identified');
26+
debug.write('Successfully identified');
2627

2728
CONFIG.APP_DETAILS = data;
2829

@@ -34,6 +35,7 @@ module.exports.methods = {
3435

3536
},
3637
fail = function () {
38+
debug.write('Identification failed');
3739
setTimeout(function () {
3840
sender.send(opt, callback, fail);
3941
}, CONFIG.IDENTIFY_DELAY);
@@ -42,16 +44,18 @@ module.exports.methods = {
4244
// check that settings object is correct
4345

4446
if (!settings) {
47+
debug.write('Settings are not provided');
4548
throw new TypeError('Settings are not provided');
4649
}
4750

4851
if (settings.apiKey && typeof (settings.apiKey) === 'string') {
4952
CONFIG.APIKEY = settings.apiKey;
5053
opt.headers['X-Stackify-Key'] = settings.apiKey;
5154
CONFIG.APPNAME = appname;
52-
CONFIG.ENV = settings.env || process.env.NODE_ENV || null;
55+
debug.write('Identifying the app');
5356
sender.send(opt, callback, fail);
5457
} else {
58+
debug.write('You have to pass API key to initialize Stackify Logger');
5559
throw new TypeError('You have to pass API key');
5660
}
5761

@@ -70,7 +74,7 @@ module.exports.methods = {
7074
//retry the request if it failed
7175
fail = function (code) {
7276
var sinceFirstError;
73-
77+
debug.write('Sending logs failed');
7478
if (code === 401) {
7579
delay = CONFIG.DELAY.FIVE_MINUTES;
7680
lastApiError = new Date().getTime();
@@ -84,7 +88,7 @@ module.exports.methods = {
8488
sender.send(opt, cb, fail);
8589
}, delay);
8690
};
87-
91+
debug.write('Sending logs: batch size: ' + messages.length + ' messages');
8892
sender.send(opt, cb, shutdown ? null : fail);
8993
},
9094
/*

lib/debug.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
var fs = require('fs'),
2+
path = require('path'),
3+
util = require('util'),
4+
log_path = path.join(process.cwd(), 'stackify-debug.log'),
5+
debug = false,
6+
stream = false,
7+
makeMsg = function (msg) {
8+
return new Date().toString() + ' ' + msg + '\n';
9+
},
10+
// create writable stream if debug mode is turned on
11+
init = function () {
12+
stream = fs.createWriteStream(log_path, {flags: 'a'});
13+
stream.write(makeMsg('Debugging started'));
14+
stream.on('error', function (err) {
15+
console.error('Error occured during writing to the log file ', util.inspect(err));
16+
});
17+
};
18+
19+
module.exports = {
20+
21+
set: function (option) {
22+
debug = (option === true) ? true : false;
23+
if (debug) {
24+
init();
25+
}
26+
},
27+
28+
write: function (msg) {
29+
if (debug) {
30+
stream.write(makeMsg(msg));
31+
}
32+
},
33+
34+
writeResponse: function (response, close) {
35+
var body = (typeof response.body === 'object') ? JSON.stringify(response.body, null, 4) : response.body,
36+
msg = 'url: ' + response.request.uri.href + ':' + response.request.uri.port + ', method: '
37+
+ response.req.method + ', status: ' + response.statusCode + '\nresponse: ' + body;
38+
if (close) {
39+
this.close('Response received\n' + msg);
40+
} else {
41+
this.write('Response received\n' + msg);
42+
}
43+
},
44+
45+
writeRequest: function (request, close) {
46+
if (request.body.Msgs) {
47+
request.body.Msgs = request.body.Msgs.length + ' messages';
48+
}
49+
if (close) {
50+
this.close('Request sent\n' + JSON.stringify(request, null, 4));
51+
} else {
52+
this.write('Request sent\n' + JSON.stringify(request, null, 4));
53+
}
54+
},
55+
56+
// special case - write synchronously to file if synchronous request before exit failed
57+
writeSync: function (msg) {
58+
try {
59+
fs.appendFileSync(log_path, msg);
60+
} catch (err) {
61+
console.error('Error occured during writing to the log file ', util.inspect(err));
62+
}
63+
},
64+
65+
close: function (msg) {
66+
var exit_msg = 'Exiting the app',
67+
message = msg || exit_msg;
68+
69+
if (stream) {
70+
stream.end(makeMsg(message) + (msg ? makeMsg(exit_msg) : ''));
71+
}
72+
}
73+
};

lib/error.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ module.exports = {
7272
AppName: CONFIG.APPNAME,
7373
AppLocation: process.env.PWD,
7474
ConfiguredAppName: CONFIG.APPNAME,
75-
ConfiguredEnvironmentName: CONFIG.ENV
75+
ConfiguredEnvironmentName: CONFIG.APP_DETAILS ? CONFIG.APP_DETAILS.ENV : null
7676
},
7777
OccurredEpochMillis: Date.now(),
7878
Error: {

lib/helpers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ module.exports.getPostBody = function getPostBody(messages) {
142142
AppNameID: CONFIG.APP_DETAILS ? CONFIG.APP_DETAILS.AppNameID : null,
143143
AppEnvID: CONFIG.APP_DETAILS ? CONFIG.APP_DETAILS.AppEnvID : null,
144144
EnvID: CONFIG.APP_DETAILS ? CONFIG.APP_DETAILS.EnvID : null,
145-
Env: CONFIG.ENV,
145+
Env: CONFIG.APP_DETAILS ? CONFIG.APP_DETAILS.ENV : null,
146146
ServerName: os.hostname(),
147147
AppName: CONFIG.APPNAME,
148148
AppLoc: process.env.PWD,

lib/logger.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var api = require('./api'),
22
CONFIG = require('../config/config'),
33
helpers = require('./helpers'),
44
error = require('./error'),
5+
debug = require('./debug'),
56

67
storage = [],
78

@@ -29,7 +30,7 @@ var api = require('./api'),
2930
send another batch (if there are enough messages in the queue)
3031
*/
3132
success = function (response) {
32-
if (response.success) {
33+
if (response && response.success) {
3334
storage = storage.slice(chunk); // remove this chunk from the queue
3435
length -= chunk;
3536
api.lastApiError = 0; // reset the last HTTP error
@@ -50,6 +51,7 @@ var api = require('./api'),
5051
}
5152
}
5253
};
54+
debug.write('Checking the queue: ' + data.length + ' messages');
5355
// re-count the delay
5456
if (length >= CONFIG.MSG.MAX_BATCH_SIZE) {
5557
delay = Math.max(Math.round(delay / 2.0), CONFIG.DELAY.ONE_SECOND_DELAY);
@@ -138,6 +140,8 @@ module.exports.methods = {
138140
}
139141
};
140142

143+
debug.write('Exception caught');
144+
141145
clearTimeout(timeout);
142146
this.push('error', err.message, [err], req, err);
143147
check();
@@ -146,6 +150,8 @@ module.exports.methods = {
146150
drain : function drain() {
147151
if (storage.length) {
148152
api.methods.postLogsSync(storage);
153+
} else {
154+
debug.close();
149155
}
150156
},
151157

@@ -156,10 +162,12 @@ module.exports.methods = {
156162

157163
// check the message level
158164
if (levels.indexOf(level.toLowerCase()) < 0) {
165+
debug.write(level + ' level doesn\'t exist');
159166
throw new TypeError(level + ' level doesn\'t exist');
160167
}
161168
// check the message itself
162169
if (typeof msg !== 'string') {
170+
debug.write('Message must be a string');
163171
throw new TypeError('Message must be a string');
164172
}
165173
this.push(level, msg, meta);

lib/sender.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@
55
Low level function for sending http/https requests
66
*/
77
var http = require('http'),
8+
util = require('util'),
89

910
request = require('request'),
1011
requestSync = require('sync-request'),
1112

13+
debug = require('./debug'),
14+
exc = require('./exception'),
1215
logger = require('./logger'),
1316
CONFIG = require('../config/config.js');
1417

1518
module.exports.send = function send(options, cb, fail) {
16-
1719
var callback = function (error, response, body) {
20+
debug.writeResponse(response, exc.excCaught);
1821
if (!error) {
1922
if (response.statusCode === 200) {
2023
if (cb) {
@@ -26,23 +29,25 @@ module.exports.send = function send(options, cb, fail) {
2629
}
2730
}
2831
} else {
29-
console.error(error.stack);
32+
debug.write('Request failed\n', util.inspect(error.stack));
3033
logger.methods.push('error', error.message, [{error: error}]);
3134
}
3235
};
36+
3337
request(options, callback);
38+
debug.writeRequest(options);
3439
};
3540

3641
module.exports.sendSync = function sendSync(options) {
37-
3842
try {
3943
var res = requestSync('POST', options.url, {
4044
json: options.data,
4145
headers: options.headers
4246
});
47+
options.data.Msgs = options.data.Msgs.length + ' messages';
48+
debug.close('Sending logs synchronously before exiting the app\n' + JSON.stringify(options, null, 4));
4349
} catch (err) {
44-
console.error(err.stack);
50+
debug.writeSync('Sending failed. Error stack: \n' + JSON.stringify(err.stack, null, 4));
4551
process.exit(1);
4652
}
47-
4853
};

package.json

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "stackify-logger",
3-
"version": "1.0.0",
3+
"version": "1.0.2",
44
"description": "Stackify logs and errors for Node.Js",
55
"main": "index.js",
66
"scripts": {
@@ -11,16 +11,27 @@
1111
"logger",
1212
"log"
1313
],
14-
"author": "Stackify",
14+
"author": {
15+
"name": "Stackify"
16+
},
1517
"license": "Apache-2.0",
1618
"repository": {
1719
"type": "git",
18-
"url": "https://github.com/stackify/stackify-log-nodejs.git"
20+
"url": "http://github.com/stackify/stackify-log-nodejs.git"
1921
},
2022
"homepage": "https://github.com/stackify/stackify-log-nodejs",
2123
"dependencies": {
2224
"request": "~2.48.x",
2325
"stack-trace": "0.0.9",
2426
"sync-request": "^1.0.1"
25-
}
27+
},
28+
"readme": "#Stackify Log API for Node.js\n\nErrors and Logs Overview:\n\nhttp://docs.stackify.com/m/7787/l/189767\n\nSign Up for a Trial:\n\nhttp://www.stackify.com/sign-up/\n\n## Installation\n```bash\n$ npm install stackify-logger\n```\n\n## Usage\n\n```js\nvar stackify = require(‘stackify-logger’);\n```\nStart sending logs:\n```js\n// this should be executed only once in the app\nstackify.start(options);\n```\nThe following options could be passed. 'apiKey' is the only one that required:\n* __apiKey:__ client license key\n* __env:__ environment name\n* __exitOnError:__ boolean flag indicating whether to shutdown the server after logging an uncaught exception, defaults to false\n* __proxy:__ proxy server if you want to send requests via proxy.\n\n*Notice:* stackify-logger sends synchronous requests if you call `process.exit()`. Sending via proxy wouldn't be possible in this case.\n\n#### Using direct logger\n\nIf you are not using Winston logger you can use default Stackify logger. It has 5 levels of messages: `trace`, `debug`, `info`, `warn` and `error`. To send the message to Stackify API you should run one of the following methods in any place of your code where you want to track some information:\n```js\nstackify.log(level, message [, meta])\nstackify.trace(message [, meta])\nstackify.debug(message [, meta])\nstackify.info(message [, meta])\nstackify.warn(message [, meta])\nstackify.error(message [, meta])\n```\n\n**Message** must be a string.\n\n**meta** - an additional parameter of any type.\n\nExamples of usage:\n```js\n// Add the module to all the script files where you want to log any messages.\nvar stackify = require('stackify-logger');\n\nstackify.log('info', 'hey!');\nstackify.debug('any message');\nstackify.info('any message', {anything: 'this is metadata'});\nstackify.warn('attention');\nstackify.log('error', {error : new Error()});\n```\nWhen logging an error message you can pass an Error object in metadata like in the last example, so the exception details would be available.\n\n#### Exception handling\nBy executing `stackify.start()` you set a handler for uncaught exceptions.\nMake sure you run it before any methods that set exception handlers.\n\n##### Using with Express\nGlobal handler doesn't work inside Express route methods.\nYou should use error-handling middleware function `stackify.expressExceptionHandler`. Since middleware is executed serially, it's order of inclusion is important. Make sure you add it before any other error-handling middleware.\n\n```js\nvar express = require('express');\nvar app = express();\n\n/* \n*** block of route handlers ***\n*** *** **** **** **** **** ***\n*/\n\napp.use(stackify.expressExceptionHandler);\n```\n\nTo handle exceptions correctly put this right after all route handlers.\n\n## Troubleshooting\nWhen request to Stackify fails for some reason, an error message is being printed to your `process.stderr` stream \n\n## License\n\nCopyright 2014 Stackify, LLC.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
29+
"readmeFilename": "README.md",
30+
"gitHead": "d0b7a4ade02acf6dc17d5c1e96d67a78edc9ed7f",
31+
"bugs": {
32+
"url": "https://github.com/stackify/stackify-log-nodejs/issues"
33+
},
34+
35+
"_shasum": "33730db585d53b43988b359145d76629e7ec35f1",
36+
"_from": "stackify-logger@"
2637
}

0 commit comments

Comments
 (0)