banshee is under active development: collectors will keep changing, and a version you publish will likely need adjustments. For stable use, wait for version 1.0.0.

Linux

banshee/linux-collection/linux/ssh/

services

State of the services of a Linux by SSH, under systemd or OpenRC.

  • linux
  • ssh
  • systemd
  • openrc
  • service
  • alpine
  • debian
  • fedora

by banshee1 installation2 versions

Keen 1.0.0 · 55 lines
// The state of the services of a Linux, by SSH, under systemd (Debian, Fedora) as under OpenRC (Alpine):
// the collector tries systemd, then OpenRC, and says in "Service manager" which one answered; if neither
// answers, it stops and says so. By default only the SSH server and cron are watched, under their names on
// the three systems; others are chosen on the probe.
// Runs systemctl list-units --type=service --all --no-legend --plain (systemd, on Debian and Fedora),
// otherwise rc-status -a (OpenRC, on Alpine); both only read. OpenRC states are given in systemd's words,
// so that one watch holds on all three: started becomes active, stopped inactive, crashed failed; the
// others stay as written.
need('protocol:ssh');

per('service', 'Services', array('only' => array('ssh', 'sshd', 'cron', 'crond')));
output('manager', 'text', array('label' => 'Service manager'));
output('state', 'text', array('label' => 'State', 'per' => 'service'));

watch.expect('stopped', 'Service stopped', 'state', array('critical' => array('active')));
watch.missing('missing', 'Service missing', 'state');

// The name of a service is the key: a service listed twice is given once.
$states = array();
$manager = 'systemd';

// systemd: one line per service, "nginx.service loaded active running A high performance web server",
// preceded by a "●" when it failed: the name, then the load state, then the active state.
$units = ssh.run('systemctl list-units --type=service --all --no-legend --plain');
if ($units['exit'] == 0) {
    foreach (text.lines($units['output']) as $line) {
        $m = text.match($line, '([^ ]+)\.service +[^ ]+ +([^ ]+)');
        if (list.count($m) > 0) {
            $states[$m[1]] = $m[2];
        }
    }
} else {
    // OpenRC: lines "Runlevel: default", then one per service, "sshd  [  started  ]".
    $rc = ssh.run('rc-status -a');
    if ($rc['exit'] != 0) {
        fail('misconfigured', 'Neither systemd nor OpenRC answers on this machine',
            'systemctl: ' . text.trim($units['errors']) . '; rc-status: ' . text.trim($rc['errors']));
    }
    $manager = 'openrc';
    $words = array('started' => 'active', 'stopped' => 'inactive', 'crashed' => 'failed');
    foreach (text.lines($rc['output']) as $line) {
        $m = text.match($line, '^([^ ]+) +\[ *([a-z]+)');
        if (list.count($m) > 0) {
            $states[$m[1]] = list.get($words, $m[2], $m[2]);
        }
    }
}
if (list.count($states) == 0) {
    fail('misconfigured', 'No service found in the answer of ' . $manager);
}

value('manager', $manager);
foreach ($states as $name => $state) {
    value('state', $state, $name);
}