Repository
Munin (contrib)
Last change
2020-12-05
Graph Categories
Family
auto
Capabilities
Keywords
Language
Python (3.x)
License
GPL-2.0-only
Authors

systemd_status

Name

systemd_status - monitor systemd service status, including normal services, mounts, hotplugs and socket activations

Applicable Systems

Linux systems with systemd installed.

Configuration

No configuration is required for this plugin.

Warning level for systemd “failed” state is set to 0:0. If any of the services enters “failed” state, Munin will emit warning.

Author

Kim B. Heino b@bbbs.net

License

GPLv2

Magic Markers

#%# family=auto
#%# capabilities=autoconf
#!/usr/bin/env python3
# pylint: disable=invalid-name
# pylint: enable=invalid-name

"""Munin plugin to monitor systemd service status.

=head1 NAME

systemd_status - monitor systemd service status, including normal services,
mounts, hotplugs and socket activations

=head1 APPLICABLE SYSTEMS

Linux systems with systemd installed.

=head1 CONFIGURATION

No configuration is required for this plugin.

Warning level for systemd "failed" state is set to 0:0. If any of the services
enters "failed" state, Munin will emit warning.

=head1 AUTHOR

Kim B. Heino <b@bbbs.net>

=head1 LICENSE

GPLv2

=head1 MAGIC MARKERS

 #%# family=auto
 #%# capabilities=autoconf

=cut

"""

import os
import re
import subprocess
import sys


STATES = (
    'failed',
    'dead',
    'running',
    'exited',
    'active',
    'listening',
    'waiting',
    'plugged',
    'mounted',
)


def config():
    """Autoconfig values."""
    print('graph_title systemd services')
    print('graph_vlabel Services')
    print('graph_category processes')
    print('graph_args --base 1000 --lower-limit 0')
    print('graph_scale no')
    print('graph_info Number of services in given activation state.')
    for state in STATES:
        print('{state}.label Services in {state} state'.format(state=state))
    print('failed.warning 0:0')
    if os.environ.get('MUNIN_CAP_DIRTYCONFIG') == '1':
        fetch()


def fetch():
    """Print runtime values."""
    # Get data
    try:
        # deb9/py3.5 doesn't have encoding parameter in subprocess
        output = subprocess.check_output(['/bin/systemctl', 'list-units'])
    except (OSError, subprocess.CalledProcessError):
        return
    output = output.decode('utf-8', 'ignore')

    # Parse data
    states = {state: 0 for state in STATES}
    for line in output.splitlines():
        token = line.split()
        if len(token) < 4:
            continue
        if len(token[0]) < 3:  # Skip failed-bullet
            token = token[1:]
        if token[0].endswith('.scope'):
            continue  # Ignore scopes
        if re.match(r'user.*@\d+\.service', token[0]):
            continue  # These fail randomly in older systemd
        if token[3] in states:
            states[token[3]] = states[token[3]] + 1

    # Output
    for state in STATES:
        print('{}.value {}'.format(state, states[state]))


if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'autoconf':
        print('yes' if os.path.exists('/run/systemd/system') else
              'no (systemd is not running)')
    elif len(sys.argv) > 1 and sys.argv[1] == 'config':
        config()
    else:
        fetch()