Comparing version 0.0.5 to 0.1.0
@@ -1,2 +0,9 @@ | ||
### 0.0.5-pre | ||
### 0.1.0-pre | ||
* Add error status to differentiate error from check failures | ||
* Add success, failure, and error messages to improve reporting | ||
* Rename responseTime to duration (check time in milliseconds) | ||
* Change status ok to success | ||
* Add lenient check attribute and warning status | ||
### 0.0.5 | ||
* Add cli formatter | ||
@@ -3,0 +10,0 @@ * Fix CLI exit code to be the number of non-ok status |
{ | ||
"commands": { | ||
"init": { | ||
"desc": "Create sample setup file\nUsage: health init" | ||
"desc": "Create sample setup file" | ||
}, | ||
"check": { | ||
"desc": "Check resources configured in setup file\nUsage: health [-s/--setup-file <setupFile>] [-f/--formatter <formatter>] check", | ||
"desc": "Check resources configured in setup file", | ||
"options": [ | ||
@@ -9,0 +9,0 @@ { "arg": "-s, --setup-file <setupFile>", "desc": "Setup file, default: health.json" }, |
@@ -1,4 +0,4 @@ | ||
var bag = require('bagofholding'), | ||
validator = require('validator'), | ||
check = validator.check; | ||
/*jshint esnext: true */ | ||
var bag = require('bagofrequest'), | ||
validator = require('validator'); | ||
@@ -15,3 +15,6 @@ /** | ||
*/ | ||
function _check(setup, cb) { | ||
function check(setup, cb) { | ||
const CHECKERS = [ _checkStatusCodes, _checkTexts ]; | ||
var method = setup.method || 'get', | ||
@@ -24,28 +27,16 @@ opts = { | ||
function _catchAll(result, cb) { | ||
var _result = {}; | ||
try { | ||
var status, | ||
successes = [], | ||
failures = []; | ||
if (setup.statusCodes) { | ||
// convert to string because check#isIn does not work with number | ||
for (var i = 0, ln = setup.statusCodes.length; i < ln; i += 1) { | ||
setup.statusCodes[i] = setup.statusCodes[i].toString(); | ||
} | ||
check(result.statusCode, 'Status code ' + result.statusCode + ' does not match the expected ' + setup.statusCodes.join(', ')).isIn(setup.statusCodes); | ||
_result.desc = 'Status code ' + result.statusCode + ' as expected'; | ||
} | ||
if (setup.texts) { | ||
setup.texts.forEach(function (text) { | ||
check(result.body, 'Text ' + text + ' does not exist in response body').is(new RegExp(text)); | ||
}); | ||
_result.desc = 'Text ' + setup.texts.join(', ') + ' exists in response body'; | ||
} | ||
_result.status = 'ok'; | ||
CHECKERS.forEach(function (checker) { | ||
var _result = checker(result, setup); | ||
successes = successes.concat(_result.successes); | ||
failures = failures.concat(_result.failures); | ||
}); | ||
} catch (e) { | ||
_result.status = 'fail'; | ||
_result.desc = e.message; | ||
} | ||
cb(null, _result); | ||
cb(null, { | ||
status: (failures.length > 0) ? 'fail' : 'success', | ||
successes: successes, | ||
failures: failures }); | ||
} | ||
@@ -55,5 +46,5 @@ | ||
bag.http.request(method, setup.uri, opts, function (err, result) { | ||
bag.request(method, setup.uri, opts, function (err, result) { | ||
if (err) { | ||
cb(null, { status: 'fail', desc: err.message }); | ||
cb(null, { status: 'error', errors: [err.message] }); | ||
} else { | ||
@@ -65,2 +56,34 @@ cb(null, result); | ||
exports.check = _check; | ||
function _checkStatusCodes(result, setup) { | ||
var successes = [], failures = []; | ||
try { | ||
if (setup.statusCodes) { | ||
// convert to string because check#isIn does not work with number | ||
for (var i = 0, ln = setup.statusCodes.length; i < ln; i += 1) { | ||
setup.statusCodes[i] = setup.statusCodes[i].toString(); | ||
} | ||
validator.check(result.statusCode, 'Status code ' + result.statusCode + ' does not match the expected ' + setup.statusCodes.join(', ')).isIn(setup.statusCodes); | ||
successes.push('Status code ' + result.statusCode + ' as expected'); | ||
} | ||
} catch (e) { | ||
failures.push(e.message); | ||
} | ||
return { successes: successes, failures: failures }; | ||
} | ||
function _checkTexts(result, setup) { | ||
var successes = [], failures = []; | ||
if (setup.texts) { | ||
setup.texts.forEach(function (text) { | ||
try { | ||
validator.check(result.body, 'Text ' + text + ' does not exist in response body').is(new RegExp(text)); | ||
successes.push('Text ' + text + ' exists in response body'); | ||
} catch (e) { | ||
failures.push(e.message); | ||
} | ||
}); | ||
} | ||
return { successes: successes, failures: failures }; | ||
} | ||
exports.check = check; |
@@ -24,7 +24,7 @@ /*jshint esnext: true */ | ||
if (err) { | ||
result.status = 'fail'; | ||
result.desc = err.message; | ||
result.status = 'error'; | ||
result.errors = [err.message]; | ||
} else { | ||
conn.close(); | ||
result.status = 'ok'; | ||
result.status = 'success'; | ||
} | ||
@@ -31,0 +31,0 @@ cb(null, result); |
var _ = require('underscore'), | ||
bag = require('bagofholding'), | ||
bag = require('bagofcli'), | ||
Health = require('./health'), | ||
@@ -7,3 +7,3 @@ util = require('util'); | ||
function _init() { | ||
new Health().init(bag.cli.exit); | ||
new Health().init(bag.exit); | ||
} | ||
@@ -27,9 +27,8 @@ | ||
return (item.status === 'ok') ? 'ok' : 'non-ok'; | ||
})['non-ok']; | ||
})['non-ok'] || 0; | ||
process.exit(numNonOk); | ||
} | ||
var setup = JSON.parse(bag.cli.lookupFile(args.setupFile || 'health.json')); | ||
new Health({ setup: setup }).check(bag.cli.exitCb(null, function (result) { | ||
console.dir(result); | ||
var setup = JSON.parse(bag.lookupFile(args.setupFile || 'health.json')); | ||
new Health({ setup: setup }).check(bag.exitCb(null, function (result) { | ||
log(result); | ||
@@ -52,5 +51,5 @@ exit(result); | ||
bag.cli.command(__dirname, actions); | ||
bag.command(__dirname, actions); | ||
} | ||
exports.exec = exec; | ||
exports.exec = exec; |
@@ -10,6 +10,6 @@ /*jshint esnext: true */ | ||
* - name: resource name | ||
* - status: ok or fail | ||
* - status: success, warning, fail, or error | ||
* - uri: the resource that was checked | ||
* - desc: result description, e.g. failure explanation | ||
* - responseTime: check response time in milliseconds | ||
* - duration: check response time in milliseconds | ||
* @return {Array} an array of result strings | ||
@@ -19,5 +19,13 @@ */ | ||
const COLORS = { | ||
ok: 'green', | ||
fail: 'red' | ||
success: 'green', | ||
warning: 'yellow', | ||
fail: 'red', | ||
error: 'red' | ||
}; | ||
const TYPES = [ | ||
'successes', | ||
'failures', | ||
'errors' | ||
]; | ||
var texts = []; | ||
@@ -27,9 +35,16 @@ | ||
texts.push(util.format( | ||
'%s | %s%s - %dms%s', | ||
'%s - %s%s - %dms', | ||
result.status[COLORS[result.status] || 'grey'], | ||
result.name ? result.name + ' - ' : '', | ||
result.uri.cyan, | ||
result.responseTime, | ||
result.desc ? ' - ' + result.desc : '' | ||
result.duration | ||
)); | ||
TYPES.forEach(function (type) { | ||
if (result[type]) { | ||
result[type].forEach(function (message) { | ||
texts.push(util.format(' * %s', message)); | ||
}); | ||
} | ||
}); | ||
texts.push(''); | ||
}); | ||
@@ -36,0 +51,0 @@ |
@@ -1,3 +0,5 @@ | ||
var bag = require('bagofholding'), | ||
var async = require('async'), | ||
bag = require('jazz'), | ||
fs = require('fs'), | ||
jazz = require('jazz'), | ||
p = require('path'); | ||
@@ -13,10 +15,26 @@ | ||
* - desc: result description, e.g. failure explanation | ||
* - responseTime: check response time in milliseconds | ||
* - duration: check response time in milliseconds | ||
* @return {String} a HTML string | ||
*/ | ||
function format(results) { | ||
var template = fs.readFileSync(p.join(__dirname, '../../views/html.jazz')).toString(); | ||
return bag.text.apply(template, { results: results }); | ||
var text = fs.readFileSync(p.join(__dirname, '../../views/html.jazz')).toString(), | ||
template = jazz.compile(text), | ||
params = { results: results }, | ||
applied; | ||
async.whilst( | ||
function () { return applied === undefined; }, | ||
function (cb) { | ||
template.process(params, function (result) { | ||
applied = result; | ||
}); | ||
setTimeout(cb, 1); | ||
}, | ||
function (err) { | ||
} | ||
); | ||
return applied; | ||
} | ||
exports.format = format; |
@@ -0,1 +1,2 @@ | ||
/*jshint esnext: true */ | ||
var util = require('util'); | ||
@@ -15,2 +16,8 @@ | ||
function format(results) { | ||
const TYPES = [ | ||
'successes', | ||
'failures', | ||
'errors' | ||
]; | ||
var texts = []; | ||
@@ -20,9 +27,15 @@ | ||
texts.push(util.format( | ||
'%s | %s%s - %dms%s', | ||
'%s - %s%s - %dms', | ||
result.status, | ||
result.name ? result.name + ' - ' : '', | ||
result.uri, | ||
result.responseTime, | ||
result.desc ? ' - ' + result.desc : '' | ||
result.duration | ||
)); | ||
TYPES.forEach(function (type) { | ||
if (result[type]) { | ||
result[type].forEach(function (message) { | ||
texts.push(util.format(' * %s', message)); | ||
}); | ||
} | ||
}); | ||
}); | ||
@@ -29,0 +42,0 @@ |
@@ -8,6 +8,6 @@ var Js2Xml = require('js2xml').Js2Xml; | ||
* - name: resource name | ||
* - status: ok or fail | ||
* - status: success, warning, fail, or error | ||
* - uri: the resource that was checked | ||
* - desc: result description, e.g. failure explanation | ||
* - responseTime: check response time in milliseconds | ||
* - duration: check response time in milliseconds | ||
* @return {String} an XML string | ||
@@ -14,0 +14,0 @@ */ |
/*jshint esnext: true */ | ||
var async = require('async'), | ||
bag = require('bagofholding'), | ||
bag = require('bagofcli'), | ||
cache = require('memory-cache'), | ||
fsx = require('fs.extra'), | ||
p = require('path'); | ||
p = require('path'), | ||
url = require('url'); | ||
@@ -50,3 +51,3 @@ /** | ||
if (typeof this.opts.setup === 'string') { | ||
this.opts.setup = JSON.parse(bag.cli.lookupFile(this.opts.setup)); | ||
this.opts.setup = JSON.parse(bag.lookupFile(this.opts.setup)); | ||
} | ||
@@ -71,10 +72,10 @@ | ||
} else { | ||
if (setup.name) { | ||
result.name = setup.name; | ||
} | ||
result.uri = setup.uri; | ||
// check time in milliseconds | ||
var endTime = Date.now(); | ||
result.responseTime = endTime - startTime; | ||
result.duration = endTime - startTime; | ||
// apply global rules | ||
result = self._rules(result, setup); | ||
cache.put(setup.uri, result, setup.ttl || TTL); | ||
@@ -109,2 +110,25 @@ cb(null, result); | ||
Health.prototype._rules = function (result, setup) { | ||
// basic info | ||
if (setup.name) { | ||
result.name = setup.name; | ||
} | ||
result.uri = setup.uri; | ||
// camouflage fail status as warn when lenient is true | ||
if (setup.lenient === true && (result.status === 'fail' || result.status === 'error')) { | ||
result.status = 'warning'; | ||
} | ||
var parsedUri = url.parse(result.uri); | ||
if (parsedUri.auth) { | ||
var userPass = parsedUri.auth.split(':'); | ||
userPass[1] = userPass[1].replace(/./g, '*'); | ||
parsedUri.auth = userPass.join(':'); | ||
result.uri = url.format(parsedUri); | ||
} | ||
return result; | ||
}; | ||
Health.prototype._checker = function (uri) { | ||
@@ -111,0 +135,0 @@ var checker, |
@@ -9,3 +9,3 @@ { | ||
], | ||
"version": "0.0.5", | ||
"version": "0.1.0", | ||
"homepage": "http://github.com/cliffano/health", | ||
@@ -34,3 +34,4 @@ "author": "Cliffano Subagio <blah@cliffano.com> (http://blog.cliffano.com)", | ||
"async": "0.2.6", | ||
"bagofholding": "0.1.6", | ||
"bagofcli": "0.0.1", | ||
"bagofrequest": "0.0.3", | ||
"colors": "0.6.0-1", | ||
@@ -40,2 +41,3 @@ "fs.extra": "1.2.0", | ||
"mongodb": "1.2.14", | ||
"jazz": "0.0.18", | ||
"js2xml": "0.0.6", | ||
@@ -42,0 +44,0 @@ "underscore": "1.4.4", |
Sorry, the diff of this file is not supported yet
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
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
21492
419
11
+ Addedbagofcli@0.0.1
+ Addedbagofrequest@0.0.3
+ Addedjazz@0.0.18
+ Addedbagofcli@0.0.1(transitive)
+ Addedbagofrequest@0.0.3(transitive)
+ Addedlodash@1.2.1(transitive)
- Removedbagofholding@0.1.6
- Removedbagofholding@0.1.6(transitive)
- Removeddateformat@1.0.6-1.2.3(transitive)