invoker.js
A simple node.js script for managing services. invoker.js allows you to start, stop and tail the logs of services.
Installation
npm install -g invoker.js
Getting Started
In your project root, define an invoker.json
file. e.g.:
{
"redis": {
"command": "redis-server"
},
"elasticsearch": {
"command": "./elasticsearch/bin/elasticsearch"
}
}
You can then start a service like so: invoker start redis
Stop a service like so: invoker stop redis
And tail the logs like so: invoker tail redis
You can additionally list the services that are currently running via: invoker list
invoker.json
specification
invoker.json
specifies the services to manage. The JSON object keys are the service names. The values can specify either command-based or module-based services. The above example specifies a couple of command-based services. These are services that are started simply by executing the specified command. On stop, the services are issued a SIGTERM. The normal log and error log are populated via the process' stdout and stderr, respectively.
With command-based services, you can also specify command-line arguments and options to pass to the call to child_process.spawn. Example:
{
"redis": {
"command": "redis-server",
"args": ["./conf/redis.conf"],
"options": {
"cwd": "./data"
}
}
}
For more advanced usage, you can define a module-based service, where invoker calls a node.js module to start and stop the service. This is useful for a number of cases, e.g. when you want to shutdown a service by doing something other than sending a SIGTERM. Here's an example module that would manage elasticsearch using its shutdown API:
var child_process = require("child_process");
var http = require("http");
module.exports = {
// Called on service start
// cmd - The name of the service to start - always `elasticsearch` here
// config - The service config from invoker.json
// options - Command-line options passed in
// cb - The callback to call with the proc object once it's started
start: function(cmd, config, options, cb) {
var proc = child_process.spawn("./etc/elasticsearch/bin/elasticsearch");
cb(proc);
},
// Called on service stop
// cmd - The name of the service to stop - always `elasticsearch` here
// config - The service config from invoker.json
// options - Command-line options passed in
// pid - The PID of the managing invoker.js instance to stop
// cb - The callback to call when the service is stopped. Optionally
// pass in an error object. If there is an error, invoker.js will
// still try to cleanup before throwing the error.
stop: function(cmd, config, options, pid, cb) {
var opts = {
port: 9200,
method: "POST",
path: "/_shutdown"
};
var req = http.request(opts, function(res) {
if(res.statusCode != 200) {
cb(new Error("Unexpected status code: " + res.statusCode));
} else {
cb();
}
});
req.on("error", function(e) {
cb(e);
});
req.end();
}
};
Assuming you saved this to ./elasticsearch-invoker.js
, your invoker.json
would then have this specification:
{
"elasticsearch": {
"module": "./elasticsearch-invoker"
}
}