UNPKG

the-shepherd

Version:
211 lines (204 loc) 7.39 kB
// Generated by CoffeeScript 2.5.1 (function() { var $, Groups, Health, Http, echo, quoted, verbose; $ = require('bling'); Http = require('http'); ({echo, verbose, quoted} = require('../common')); ({Groups} = require('../daemon/groups')); $.extend(module.exports, Health = { defaultInterval: 10000, defaultTimeout: 3000, monitor: function(group, path, exec, interval, status, text, timeout) { var monitorKey; if (exec != null) { if (!(exec.length > 0)) { return new Error(`Invalid exec command: ${exec}`); } } else if (path != null) { if (!(path.length > 0)) { return new Error(`Invalid path: ${path}`); } } else { return new Error("Either path or exec is required."); } verbose("Health.monitor", path, exec, interval, status, text, timeout); interval = parseInt(interval != null ? interval : Health.defaultInterval, 10); if (!(isFinite(interval) && !isNaN(interval) && ((0 < interval && interval < 4294967295)))) { return new Error(`Invalid interval: ${interval}.`); } if (status != null) { status = parseInt(status, 10); if (!(isFinite(status) && !isNaN(status) && ((0 < status && status < 1000)))) { return new Error(`Invalid status: ${status}.`); } } text = String(text != null ? text : ''); timeout = parseInt(timeout != null ? timeout : Health.defaultTimeout, 10); if (!(isFinite(timeout) && !isNaN(timeout) && ((0 < timeout && timeout < 4294967295)))) { return new Error(`Invalid timeout: ${timeout}.`); } monitorKey = path != null ? path : exec; group.monitors || (group.monitors = Object.create(null)); if (monitorKey in group.monitors) { return new Error("Group is already monitored."); } verbose("Adding health monitor", {path, interval, status, text, timeout}); group.monitors[monitorKey] = $.interval(interval, function() { var i, len, proc, results; results = []; for (i = 0, len = group.length; i < len; i++) { proc = group[i]; if (proc.expected) { results.push((function(group, path, exec, interval, status, text, timeout, proc) { var countdown, fail, req, res; countdown = null; if (proc.enabled && !proc.started) { proc.healthy = false; return; } proc.healthy = void 0; fail = function(msg) { var ref, ref1; clearTimeout(countdown); echo(`Health check failed (${msg}), pid: ${(ref = proc.proc) != null ? ref.pid : void 0} port: ${proc.port}`); proc.healthy = false; return (ref1 = proc.proc) != null ? ref1.kill() : void 0; }; if (timeout > 0) { countdown = setTimeout((() => { return fail('timeout'); }), timeout); } if (exec != null) { res = Shell.exec(exec, { silent: true, async: false }); if ((status != null) && res.code !== status) { return fail("bad status: " + res.code); } else if ((text != null) && !(res.stdout.indexOf(text) > -1)) { return fail("bad text: " + res.stdout); } else { return proc.healthy = true; } } else if (path != null) { req = Http.get({ host: "127.0.0.1", port: proc.port, path: path }, function(res) { var buffer; clearTimeout(countdown); if (status !== 0 && res.statusCode !== status) { return fail("bad status: " + res.statusCode); } if (text.length > 0) { buffer = ""; res.setEncoding('utf8'); res.on('data', function(data) { return buffer += data; }); res.on('end', function() { if (!(buffer.indexOf(text) > -1)) { return fail("text not found: " + text); } }); } res.on('error', function(err) { return fail("response error: " + String(err)); }); return proc.healthy = true; }); return req.on('error', function(err) { return fail("request error: " + String(err)); }); } })(group, path, exec, interval, status, text, timeout, proc)); } } return results; }); Object.assign(group.monitors[monitorKey], {interval, status, text, timeout}); return true; }, unmonitor: function(group, path) { var check, ref; if (!('monitors' in group)) { return false; } if ((path != null) && !(path in group.monitors)) { return false; } if (path != null) { group.monitors[path].cancel(); } else { ref = group.monitors; for (path in ref) { check = ref[path]; check.cancel(); delete group.monitors[path]; } } return true; }, pause: function(group, path) { var check, ref; if (!('monitors' in group)) { return false; } if ((path != null) && !(path in group.monitors)) { return false; } if (path != null) { group.monitors[path].pause(); group.monitors[path].paused = true; } else { ref = group.monitors; for (path in ref) { check = ref[path]; check.pause(); } } return true; }, resume: function(group, path) { var check, ref; if (!('monitors' in group)) { return false; } if ((path != null) && !(path in group.monitors)) { return false; } if (path != null) { group.monitors[path].resume(); group.monitors[path].paused = false; } else { ref = group.monitors; for (path in ref) { check = ref[path]; check.resume(); } } return true; }, toConfig: function() { var items; items = []; Groups.forEach(function(group) { var interval, mon, path, paused, ref, results, status, text, timeout; if (group.monitors == null) { return; } ref = group.monitors; results = []; for (path in ref) { mon = ref[path]; ({interval, status, text, timeout, paused} = mon); results.push(items.push(`health --group ${group.name} --path \"${path}\"` + (status > 0 ? ` --status ${status}` : "") + (interval > 0 ? ` --interval ${Math.floor(interval / 1000)}` : "") + (text.length > 0 ? ` --contains ${quoted(text)}` : "") + (timeout > 0 ? ` --timeout ${timeout}` : "") + (paused ? " --pause" : ""))); } return results; }); return items.join("\n"); } }); }).call(this);