diff --git a/plugins/chrony/chrony_multigraph b/plugins/chrony/chrony_multigraph new file mode 100755 index 00000000..19e8a45f --- /dev/null +++ b/plugins/chrony/chrony_multigraph @@ -0,0 +1,101 @@ +#!/usr/bin/python3 -tt +# -*- coding: utf-8 -*- + +"""Munin plugin to monitor chrony NTP daemon status. + +Copyright 2014, Kim B. Heino, b@bbbs.net, Foobar Oy +License GPLv2+ + +#%# capabilities=autoconf +#%# family=auto +""" + +import os +import subprocess +import sys + + +FIELDS = { + 'stratum': 'Stratum', + 'systime': 'System time', + 'delay': 'Root delay', + 'frequency': 'Frequency', +} + + +def get_values(): + """Run "chronyc tracking" and parse it's output. + + Return: list of (label, value, description) + """ + try: + output = subprocess.run(['/usr/bin/chronyc', 'tracking'], + stdout=subprocess.PIPE, check=False, + encoding='utf-8', errors='ignore') + except FileNotFoundError: + return {} + lines = output.stdout.splitlines() + ret = {} + for label in FIELDS: + for line in lines: + if line.startswith(FIELDS[label]): + value = float(line.split(':', 1)[1].split()[0]) + if ' slow' in line: + value = -value + ret[label] = value + return ret + + +def config(): + """Print plugin config.""" + print('multigraph chrony_stratum') + print('graph_title Chrony stratum') + print('graph_vlabel stratum') + print('graph_category time') + print('graph_args --base 1000 --lower-limit 0') + print('stratum.label Stratum') + print('stratum.warning 1:9') + + print('multigraph chrony_systime') + print('graph_title Chrony system time offset') + print('graph_vlabel seconds') + print('graph_category time') + print('graph_args --base 1000') + print('systime.label System time offset to NTP time') + + print('multigraph chrony_delay') + print('graph_title Chrony network delay') + print('graph_vlabel seconds') + print('graph_category time') + print('graph_args --base 1000') + print('delay.label Network path delay') + + print('multigraph chrony_frequency') + print('graph_title Chrony clock frequency error') + print('graph_vlabel ppm') + print('graph_category time') + print('graph_args --base 1000') + print('frequency.label Local clock frequency error') + + if os.environ.get('MUNIN_CAP_DIRTYCONFIG') == '1': + fetch() + + +def fetch(): + """Print values.""" + values = get_values() + for key in FIELDS: + print('multigraph chrony_{}'.format(key)) + if key == 'stratum' and values[key] == 0: + print('{}.value U'.format(key)) + else: + print('{}.value {:.8f}'.format(key, values[key])) + + +if __name__ == '__main__': + if len(sys.argv) > 1 and sys.argv[1] == 'autoconf': + print('yes' if get_values() else 'no') + elif len(sys.argv) > 1 and sys.argv[1] == 'config': + config() + else: + fetch()