Projet

Général

Profil

Révision 7d31b4ce

ID7d31b4ce25120c165eec55abced2c4a8e9fdbb48
Parent f90427c3
Enfant a45257a6

Ajouté par Kim B. Heino il y a presque 5 ans

stratis: new plugin to monitor stratis filesystem

Voir les différences:

plugins/disk/stratis
1
#!/usr/bin/python3 -tt
2
# -*- coding: utf-8 -*-
3

  
4
"""Munin plugin to monitor stratis pools and filesystems.
5

  
6
Copyright 2020 Kim B. Heino, Foobar Oy
7
License GPLv2+
8

  
9
#%# capabilities=autoconf
10
#%# family=auto
11
"""
12

  
13
import os
14
import subprocess
15
import sys
16

  
17

  
18
def safename(variable):
19
    """Return safe variable name."""
20
    ret = []
21
    for letter in variable:
22
        if letter.isalnum():
23
            ret.append(letter)
24
        else:
25
            ret.append('_')
26
    return ''.join(ret)
27

  
28

  
29
def run_binary(arg):
30
    """Run binary and return output."""
31
    try:
32
        cmd = subprocess.Popen(
33
            arg, shell=False, close_fds=True, bufsize=-1,
34
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
35
        return cmd.communicate()[0].decode('utf-8', 'ignore')
36
    except OSError:
37
        return ''
38

  
39

  
40
def parse_unit(number, unit):
41
    """Parse "1.60 TiB" to bytes."""
42
    number = float(number)
43
    if unit == 'TiB':
44
        return number * 1024 * 1024 * 1024 * 1024
45
    if unit == 'GiB':
46
        return number * 1024 * 1024 * 1024
47
    if unit == 'MiB':
48
        return number * 1024 * 1024
49
    if unit == 'KiB':
50
        return number * 1024
51
    return number
52

  
53

  
54
def find_pools():
55
    """Return list of found pools and filesystems."""
56
    pool = []
57
    for line in run_binary(['/usr/bin/stratis', 'pool']).splitlines():
58
        if line.startswith('Name  '):
59
            continue
60
        line = line.split()
61
        total = parse_unit(line[1], line[2])
62
        used = parse_unit(line[4], line[5])
63
        free = parse_unit(line[7], line[8])
64
        pool.append((line[0], total, used, free))
65

  
66
    files = []
67
    dflist = run_binary(['/usr/bin/df']).splitlines()
68
    for line in run_binary(['/usr/bin/stratis', 'filesystem']).splitlines():
69
        if line.startswith('Pool Name ') or '-snap-' in line:
70
            continue
71
        line = line.split()
72
        df_used = used = parse_unit(line[2], line[3])
73
        for dfline in dflist:
74
            if line[9] not in dfline:  # match by uuid
75
                continue
76
            df_used = int(dfline.split()[2]) * 1024
77
        files.append((line[0], line[1], used, df_used))
78
    return sorted(pool), sorted(files)
79

  
80

  
81
def config(pools, files):
82
    """Print plugin config."""
83
    print('multigraph stratis_pool')
84
    print('graph_title Stratis pools usage')
85
    print('graph_info Stratis pools usage in percent.')
86
    print('graph_category disk')
87
    print('graph_vlabel %')
88
    print('graph_args --lower-limit 0 --upper-limit 100')
89
    print('graph_scale no')
90
    for item in pools:
91
        name = safename(item[0])
92
        print('{}.label Pool {} usage'.format(name, item[0]))
93
        print('{}.warning 92'.format(name))
94
        print('{}.critical 98'.format(name))
95

  
96
    print('multigraph stratis_fs')
97
    print('graph_title Stratis filesystems usage')
98
    print('graph_info Stratis filesystems pool usage.')
99
    print('graph_category disk')
100
    print('graph_vlabel Pool usage')
101
    print('graph_args --base 1024 --lower-limit 0')
102
    first = True
103
    for item in files:
104
        name = safename(item[0] + '_' + item[1])
105
        print('{}.label Filesystem {}/{}'.format(name, item[0], item[1]))
106
        if first:
107
            print('{}.draw AREA'.format(name))
108
            first = False
109
        else:
110
            print('{}.draw STACK'.format(name))
111

  
112
    print('multigraph stratis_thin')
113
    print('graph_title Stratis thin filesystems usage vs df')
114
    print('graph_info Stratis thin filesystems usage divided by df, in '
115
          'percents.')
116
    print('graph_category disk')
117
    print('graph_vlabel %')
118
    print('graph_args --base 1000')
119
    for item in files:
120
        name = safename(item[0] + '_' + item[1])
121
        print('{}.label {}/{} usage vs df'.format(name, item[0], item[1]))
122
        print('{}.warning 150'.format(name))
123

  
124
    if os.environ.get('MUNIN_CAP_DIRTYCONFIG') == '1':
125
        fetch(pools, files)
126

  
127

  
128
def fetch(pools, files):
129
    """Print values."""
130
    print('multigraph stratis_pool')
131
    for item in pools:
132
        name = safename(item[0])
133
        print('{}.value {}'.format(name, item[2] * 100 / item[1]))
134

  
135
    print('multigraph stratis_fs')
136
    for item in files:
137
        name = safename(item[0] + '_' + item[1])
138
        print('{}.value {}'.format(name, item[2]))
139

  
140
    print('multigraph stratis_thin')
141
    for item in files:
142
        name = safename(item[0] + '_' + item[1])
143
        print('{}.value {}'.format(name, item[2] * 100 / item[3]))
144

  
145

  
146
if __name__ == '__main__':
147
    if len(sys.argv) > 1 and sys.argv[1] == 'autoconf':
148
        print('yes' if find_pools()[0] else 'no')
149
    elif len(sys.argv) > 1 and sys.argv[1] == 'config':
150
        config(*find_pools())
151
    else:
152
        fetch(*find_pools())

Formats disponibles : Unified diff