Projet

Général

Profil

Révision 44b604cd

ID44b604cdb855305cb4624b69689bab0843b9a024
Parent e48f0a3b
Enfant 7698d7fe

Ajouté par Bert Peters il y a presque 7 ans

Create plugin timesync_status to monitor systemd ntp.

Voir les différences:

plugins/systemd/timesync_status
1
#!/usr/bin/env python3
2
import re
3
import subprocess
4
import sys
5
import textwrap
6

  
7

  
8
'''
9
=head1 NAME
10

  
11
timesync_status - monitor ntp status with systemd-timesyncd
12

  
13
=head1 APPLICABLE SYSTEMS
14

  
15
All systems using systemd-timesyncd as its NTP-client. However, this
16
plugin itself also needs Python 3.5+ to call subprocess.run.
17

  
18
=head1 CONFIGURATION
19

  
20
This plugin should work out-of-the-box with autoconf. It does expect
21
timedatectl to be on $PATH, but that should always be the case in a
22
normal system.
23

  
24
=head1 INTERPRETATION
25

  
26
This plugin shows a graph with one line for every NTP metric it measure.
27
Metrics are shown with their usual name, and are explained in their
28
respective info fields.
29

  
30
This plugin issues no warnings or critical states.
31

  
32
=head1 MAGIC MARKERS
33

  
34
 #%# family=auto
35
 #%# capabilities=autoconf
36

  
37
=head1 VERSION
38

  
39
1.0
40

  
41
=head1 AUTHOR
42

  
43
Bert Peters <bert@bertptrs.nl>
44

  
45
=head1 LICENSE
46

  
47
GPLv2
48
'''
49

  
50

  
51
def parse_time(value):
52
    value = value.strip()
53
    if ' ' in value:
54
        return sum(parse_time(x) for x in value.split(' '))
55

  
56
    match = re.match(r'^([+-]?[0-9.]+)([a-z]+)$', value)
57
    if not match:
58
        raise ValueError('Invalid time ' + value)
59

  
60
    value = float(match.group(1))
61
    suffix = match.group(2)
62

  
63
    if suffix == 'min':
64
        value *= 60
65
    elif suffix == 'ms':
66
        value /= 1000
67
    elif suffix == 'us':
68
        value /= 1e6
69

  
70
    return value
71

  
72

  
73
def parse_response(data):
74
    values = {}
75
    for line in data.splitlines():
76
        k, v = line.split(': ', 1)
77
        values[k.strip()] = v.strip()
78

  
79
    return values
80

  
81

  
82
def retrieve():
83
    result = subprocess.run(['timedatectl', 'timesync-status'], capture_output=True)
84
    if result.returncode != 0:
85
        sys.exit('timedatectl failed')
86

  
87
    output = result.stdout.decode('utf-8')
88
    values = parse_response(output)
89

  
90
    print('offset.value', parse_time(values['Offset']))
91
    print('delay.value', parse_time(values['Delay']))
92
    print('delay.extinfo', 'Server', values['Server'])
93
    print('jitter.value', parse_time(values['Jitter']))
94
    print('poll.value', parse_time(values['Poll interval'].split('(')[0]))
95

  
96

  
97
def autoconf():
98
    result = subprocess.run(['timedatectl', 'status'], capture_output=True)
99
    if result.returncode != 0:
100
        print('no (failed to run timedatectl)')
101
        return
102

  
103
    values = parse_response(result.stdout.decode('utf-8'))
104
    if values['NTP service'] == 'active':
105
        print('yes')
106
    else:
107
        print('no (ntp service not running)')
108

  
109

  
110
def config():
111
    print(textwrap.dedent('''\
112
            graph_title Timesync status
113
            graph_vlabel s
114
            graph_category time
115

  
116
            offset.label Offset
117
            offset.info Time difference between source and local
118

  
119
            delay.label Delay
120
            delay.info Roundtrip time to the NTP-server
121

  
122
            jitter.label Jitter
123
            jitter.info Difference in offset between two subsequent samples
124

  
125
            poll.label Polling time
126
            poll.info Time between two subsequent NTP-polls
127
    '''))
128

  
129

  
130
if __name__ == '__main__':
131
    if len(sys.argv) == 1:
132
        retrieve()
133
    elif sys.argv[1] == 'config':
134
        config()
135
    elif sys.argv[1] == 'autoconf':
136
        autoconf()

Formats disponibles : Unified diff