mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-21 18:41:03 +00:00
stratis: new plugin to monitor stratis filesystem
This commit is contained in:
parent
f90427c32a
commit
7d31b4ce25
1 changed files with 152 additions and 0 deletions
152
plugins/disk/stratis
Executable file
152
plugins/disk/stratis
Executable file
|
@ -0,0 +1,152 @@
|
|||
#!/usr/bin/python3 -tt
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Munin plugin to monitor stratis pools and filesystems.
|
||||
|
||||
Copyright 2020 Kim B. Heino, Foobar Oy
|
||||
License GPLv2+
|
||||
|
||||
#%# capabilities=autoconf
|
||||
#%# family=auto
|
||||
"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def safename(variable):
|
||||
"""Return safe variable name."""
|
||||
ret = []
|
||||
for letter in variable:
|
||||
if letter.isalnum():
|
||||
ret.append(letter)
|
||||
else:
|
||||
ret.append('_')
|
||||
return ''.join(ret)
|
||||
|
||||
|
||||
def run_binary(arg):
|
||||
"""Run binary and return output."""
|
||||
try:
|
||||
cmd = subprocess.Popen(
|
||||
arg, shell=False, close_fds=True, bufsize=-1,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
return cmd.communicate()[0].decode('utf-8', 'ignore')
|
||||
except OSError:
|
||||
return ''
|
||||
|
||||
|
||||
def parse_unit(number, unit):
|
||||
"""Parse "1.60 TiB" to bytes."""
|
||||
number = float(number)
|
||||
if unit == 'TiB':
|
||||
return number * 1024 * 1024 * 1024 * 1024
|
||||
if unit == 'GiB':
|
||||
return number * 1024 * 1024 * 1024
|
||||
if unit == 'MiB':
|
||||
return number * 1024 * 1024
|
||||
if unit == 'KiB':
|
||||
return number * 1024
|
||||
return number
|
||||
|
||||
|
||||
def find_pools():
|
||||
"""Return list of found pools and filesystems."""
|
||||
pool = []
|
||||
for line in run_binary(['/usr/bin/stratis', 'pool']).splitlines():
|
||||
if line.startswith('Name '):
|
||||
continue
|
||||
line = line.split()
|
||||
total = parse_unit(line[1], line[2])
|
||||
used = parse_unit(line[4], line[5])
|
||||
free = parse_unit(line[7], line[8])
|
||||
pool.append((line[0], total, used, free))
|
||||
|
||||
files = []
|
||||
dflist = run_binary(['/usr/bin/df']).splitlines()
|
||||
for line in run_binary(['/usr/bin/stratis', 'filesystem']).splitlines():
|
||||
if line.startswith('Pool Name ') or '-snap-' in line:
|
||||
continue
|
||||
line = line.split()
|
||||
df_used = used = parse_unit(line[2], line[3])
|
||||
for dfline in dflist:
|
||||
if line[9] not in dfline: # match by uuid
|
||||
continue
|
||||
df_used = int(dfline.split()[2]) * 1024
|
||||
files.append((line[0], line[1], used, df_used))
|
||||
return sorted(pool), sorted(files)
|
||||
|
||||
|
||||
def config(pools, files):
|
||||
"""Print plugin config."""
|
||||
print('multigraph stratis_pool')
|
||||
print('graph_title Stratis pools usage')
|
||||
print('graph_info Stratis pools usage in percent.')
|
||||
print('graph_category disk')
|
||||
print('graph_vlabel %')
|
||||
print('graph_args --lower-limit 0 --upper-limit 100')
|
||||
print('graph_scale no')
|
||||
for item in pools:
|
||||
name = safename(item[0])
|
||||
print('{}.label Pool {} usage'.format(name, item[0]))
|
||||
print('{}.warning 92'.format(name))
|
||||
print('{}.critical 98'.format(name))
|
||||
|
||||
print('multigraph stratis_fs')
|
||||
print('graph_title Stratis filesystems usage')
|
||||
print('graph_info Stratis filesystems pool usage.')
|
||||
print('graph_category disk')
|
||||
print('graph_vlabel Pool usage')
|
||||
print('graph_args --base 1024 --lower-limit 0')
|
||||
first = True
|
||||
for item in files:
|
||||
name = safename(item[0] + '_' + item[1])
|
||||
print('{}.label Filesystem {}/{}'.format(name, item[0], item[1]))
|
||||
if first:
|
||||
print('{}.draw AREA'.format(name))
|
||||
first = False
|
||||
else:
|
||||
print('{}.draw STACK'.format(name))
|
||||
|
||||
print('multigraph stratis_thin')
|
||||
print('graph_title Stratis thin filesystems usage vs df')
|
||||
print('graph_info Stratis thin filesystems usage divided by df, in '
|
||||
'percents.')
|
||||
print('graph_category disk')
|
||||
print('graph_vlabel %')
|
||||
print('graph_args --base 1000')
|
||||
for item in files:
|
||||
name = safename(item[0] + '_' + item[1])
|
||||
print('{}.label {}/{} usage vs df'.format(name, item[0], item[1]))
|
||||
print('{}.warning 150'.format(name))
|
||||
|
||||
if os.environ.get('MUNIN_CAP_DIRTYCONFIG') == '1':
|
||||
fetch(pools, files)
|
||||
|
||||
|
||||
def fetch(pools, files):
|
||||
"""Print values."""
|
||||
print('multigraph stratis_pool')
|
||||
for item in pools:
|
||||
name = safename(item[0])
|
||||
print('{}.value {}'.format(name, item[2] * 100 / item[1]))
|
||||
|
||||
print('multigraph stratis_fs')
|
||||
for item in files:
|
||||
name = safename(item[0] + '_' + item[1])
|
||||
print('{}.value {}'.format(name, item[2]))
|
||||
|
||||
print('multigraph stratis_thin')
|
||||
for item in files:
|
||||
name = safename(item[0] + '_' + item[1])
|
||||
print('{}.value {}'.format(name, item[2] * 100 / item[3]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'autoconf':
|
||||
print('yes' if find_pools()[0] else 'no')
|
||||
elif len(sys.argv) > 1 and sys.argv[1] == 'config':
|
||||
config(*find_pools())
|
||||
else:
|
||||
fetch(*find_pools())
|
Loading…
Add table
Add a link
Reference in a new issue