service-checker
v0.9.3
Published
Checks a variety of common web services for errors.
Downloads
12
Readme
ServiceChecker
Current Version: 0.9.3
A node library to check if various services are up and behaving.
- Install
- Quick Example
- Usage
- Included Plugins
- CLI Utility
- Including a Plugin
- Writing a Plugin
- Contributing
- License
Install
npm install --save service-checker
Quick Example
var ServiceChecker = require("service-checker")();
/* Promise Style */
ServiceChecker
.https({host: 'github.com'})
.then(function (result) {
if (result.success) {
console.log('GitHub.com is up');
}
else {
console.log('GitHub.com is down');
}
})
.catch(function () {
console.log('Other Error, check not attempted');
});
/* Callback Style */
ServiceChecker.https({host: 'github.com'}, function (err, result) {
if (err) {
console.log('Other Error, check not attempted');
return;
}
if (result.success) {
console.log('GitHub.com is up');
}
else {
console.log('GitHub.com is down');
}
});
Usage
service-checker methods take an options argument and optionally a nodeback style callback. The current options are:
- timeout Sets the default timeout in ms for all checks. Default: 5000
- retries Sets the default number of retries for all checks. Default: 0
- ca Sets the ca for all future checks, useful for https and smtpTls plugins. Default: null
Note, the timeout is for each individual check. If you set retries to 1 and timeout to 1000ms and the check fails both attempts, then the total amount of time for the entire call will be 2000ms
Call one of the plugins (below) as a method of service checker. All plugins will return an CheckResult object which contains the following properties:
- type [string] Name of the check performed
- success [bool] Whether or not the check was successful
- time [int] How long in milliseconds the check took
- start_time [int] Millisecond timestamp (Date.now()) when the check started
- end_time [int] Millisecond timestamp (Date.now()) when the check finished
- error [object|undefined] If the test was not successful, the error object from the check
Included Plugins
Ping
Check a given host for an ICMP response. Uses the system ping utility. If your system does not have a ping utility in path, this plugin will fail
.ping(options)
Where options are:
- host (string) The hostname to ping. Can be either a domain or IP address.
- timeout (number) How long to wait until the check is considered timed out.
HTTP
Check a given host for a valid HTTP response
.http(options)
Where options are:
- host (string) The hostname to connect to. Can be either a domain or IP address.
- port (number) The port to connect to. Must be a number. Defaults to 80.
- timeout (number) How long to wait until the check is considered timed out.
HTTPS
Check a given host for a valid HTTP response and for a valid SSL Certificate
.https(options)
Where options are:
- host (string) The hostname to connect to. Can be either a domain or IP address.
- port (number) The port to connect to. Must be a number. Defaults to 443.
- ca (string) A certificate to pass to https.request. Adds the cert to be "trusted" so it will not fail.
- timeout (number) How long to wait until the check is considered timed out.
SMTP
Check a given host for a valid SMTP response. Does not use TLS
.smtp(options)
- host (string) The hostname to connect to. Can be either a domain or IP address.
- port (number) The port to connect to. Must be a number. Defaults to 25.
- timeout (number) How long to wait until the check is considered timed out.
SMTP-TLS
Check a given host for a valid SMTP response and that STARTSSL is enabled with a valid TLS Certificate
.smtpTls(options)
- host (string) The hostname to connect to. Can be either a domain or IP address.
- port (number) The port to connect to. Must be a number. Defaults to 25.
- ca (string) A certificate to pass to https.request. Adds the cert to be "trusted" so it will not fail.
- timeout (number) How long to wait until the check is considered timed out.
Raw-TCP
Check that a TCP connection can be made to a given host on a given port
.rawTcp(options)
- host (string) The hostname to connect to. Can be either a domain or IP address.
- port (number) The port to connect to.
- timeout (number) How long to wait until the check is considered timed out.
DNS
Check that a dns server is resolving
.dns(options)
- host (string) The IP address of the local sever. Defaults to '127.0.0.1'.
- port (number) The port to make the dns request to. Default to 53.
- name (string) The hostname to lookup. Defaults to 'google.com'.
- type (string) The record type to lookup. Defaults to 'A'.
- timeout (number) How long to wait until the request is considered timed out.
CLI Utility
service-checker also comes with a simple CLI utility called scheck. If service-checker is
installed globally, you should have the scheck
utility installed and ready to use.
To use the scheck
CLI utility, make sure to install service-checker globally.
sudo npm install -g service-checker
Then call the scheck
utility.
#See how to use scheck
scheck -h
#Check 8.8.8.8 via ping
scheck 8.8.8.8
#Check google.com via https with a 500ms timeout
scheck https google.com --timeout 500
#Check if gmails mail server is up and properly configured for TLS
scheck smtpTls gmail-smtp-in.l.google.com
The program can be used in a script multiple ways.
Exit Codes
The program will exit with the following codes.
Exit Code | Meaning --------- | ------- 0 | All parameters are sane and the check was successful. 1 | There was an error with the parameters. Check your input. 2 | All parameters are sane, but the check failed. 255 | An unknown error occurred. Please report this as a bug.
Simple Mode
The program can also be invoked with the -s
parameter to enable "simple" mode. In simple mode, the output will always
be in the following format.
(Up/Down)<tab>(Time)
For example, with cut you could run the following command to get how long it takes for a host to respond to a ping.
scheck 127.0.0.1 -s | cut -f2 -d$'\t'
Including a Plugin
Including plugins is very easy. Let's say you installed a plugin from npm named exchange-checker
. All you
would have to do is call the use
function of service-checker
var ServiceChecker = require("service-checker")();
ServiceChecker.use(require("exchange-checker"));
Check the plugins documentation to see which methods are added by the plugin. If the plugins adds the method exchange
,
then all you would have to do is:
ServiceChecker.exchange(args..)
.then(resultHandler)
.catch(errorHandler)
Writing a Plugin
Rules for building a plugin that works correctly with service checker:
- The plugin must be a an object following {method1: handler1, method2: handler2}.
- The handlers must take only one parameter. It will be passed an options object. All options passed by the user will be passed in the options parameter.
- The handlers must return a promise. service-checker uses BlueBird but any Promises/A+ implementation should work.
- The promise must reject if any passed parameters are invalid.
- The promise must resolve with a falsy object (null, undefined) if the check succeeds.
- The promise must resolve with an error object if the check fails.
- The handlers should interpret and adhere to any applicable default options. Current default options are:
- timeout
The following example plugin demonstrates all these rules.
//file-check.js
var Promise = require("bluebird");
var fs = require("fs");
var _ = require("underscore");
function doFileCheck(options)
{
return new Promise(function (resolve, reject)
{
var did_timeout = false;
var timeout_id = setTimeout(function ()
{
did_timeout = true;
var error = new Error("Operation Timed Out");
error.code = "TIMEOUT";
reject(error);
}, options.timeout);
fs.access(options.path, fs.F_OK, function (error)
{
if (!did_timeout)
{
clearTimeout(timeout_id);
if (error) reject(error);
else resolve()
}
});
});
}
function fileCheck(options)
{
return Promise
.try(function ()
{
if (!_.isString(options.path)) throw new Error("path must be a string");
return options;
}).then(function (options){
return doFileCheck(options)
.catch(function (error)
{
return error;
});
});
};
module.exports = { fileCheck: fileCheck };
To use the plugin you just wrote is simple as well:
//checker.js
var ServiceChecker = require("service-checker")();
var fileCheck = require("./file-check");
ServiceChecker.use(fileCheck);
ServiceChecker.fileCheck({path: "path/to/file"})
.then(function (result)
{
if (result.success)
{
console.log("File exists");
}
else
{
console.log("File does not exist");
}
});
Contributing
The project uses CoffeeScript. Please DO NOT edit the js files directly. All js files should be compiled in the following way:
npm run compile
If you would prefer that the coffeescript files be continually compiled as you save use:
npm run compile-watch
A linter is included for the CoffeeScript. To lint any changes you have made run:
npm run lint
Testing and code format is important to make sure the project stays consistent. Please test the code before making a pull request with:
npm test
If your update breaks a test, please update the test. If you add new functionality, please write a test. You can see the current test coverage by running:
npm cover-local
That being said, if you are unsure how to write tests or uncomfortable writing tests, I would be more than happy helping out. Make the pull request and put a comment on it that you need help with the tests.
License
Copyright (c) 2015 Kevin Gravier
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.