✨: munin zfs capability
This commit is contained in:
278
roles/munin_client/files/zpool_capacity
Normal file
278
roles/munin_client/files/zpool_capacity
Normal file
@@ -0,0 +1,278 @@
|
||||
#!/bin/bash
|
||||
|
||||
: << =cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
zpool_capacity - Munin plugin to monitor ZFS capacity
|
||||
|
||||
These functions are implemented:
|
||||
capacity : to monitor zpool capacity %
|
||||
fragmentation : to monitor zpool fragmentation %
|
||||
allocated : to monitor zpool allocated bytes
|
||||
dedup : to monitor zpool dedup and compress ratio
|
||||
|
||||
Tested with Solaris 10 and 11, OpenIndiana Hipster, FreeBSD 11, CentOS 7
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
Make symlink:
|
||||
cd /path/to/munin/etc/plugins
|
||||
ln -s /path/to/munin/lib/plugins/zpool_capacity .
|
||||
|
||||
For FreeBSD, it should be necessary to change shebang /bin/bash -> /usr/local/bin/bash
|
||||
|
||||
For Linux, root privilege is necessary to run zpool command.
|
||||
[zpool_capacity]
|
||||
user root
|
||||
|
||||
=head1 ENVIRONMENT VARIABLES
|
||||
|
||||
critical : default 90
|
||||
warning : default 80
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
K.Cima https://github.com/shakemid
|
||||
|
||||
Fragmentation graph by https://github.com/rantal
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2
|
||||
|
||||
=head1 Magic markers
|
||||
|
||||
#%# family=contrib
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=cut
|
||||
|
||||
# Include plugin.sh
|
||||
. "${MUNIN_LIBDIR:-}/plugins/plugin.sh"
|
||||
is_multigraph "$@"
|
||||
|
||||
# Shell options
|
||||
set -o nounset
|
||||
|
||||
# Global variables
|
||||
plugin_name=zpool_capacity
|
||||
functions='capacity fragmentation allocated dedup'
|
||||
zpool_cmd=/sbin/zpool
|
||||
zfs_cmd=/sbin/zfs
|
||||
|
||||
# Environment variables
|
||||
: "${warning:=80}"
|
||||
: "${critical:=90}"
|
||||
|
||||
# Note: The performance of ZFS may significantly degrade when zpool capacity > 90%
|
||||
# See also: https://docs.oracle.com/cd/E53394_01/html/E54801/zfspools-4.html
|
||||
|
||||
# Functions
|
||||
|
||||
preconfig() {
|
||||
local func="$1"
|
||||
local p c
|
||||
|
||||
# data_attr format: field type draw label
|
||||
# label can contain white-spaces.
|
||||
data_attr=
|
||||
|
||||
case $func in
|
||||
capacity)
|
||||
global_attr="
|
||||
graph_title ZFS storage pool - Capacity
|
||||
graph_category fs
|
||||
graph_args --base 1000 --lower-limit 0 --upper-limit 100
|
||||
graph_vlabel % allocated
|
||||
graph_info ZFS storage pool - Capacity
|
||||
warning ${warning}
|
||||
critical ${critical}
|
||||
"
|
||||
for p in $pool_list
|
||||
do
|
||||
data_attr="${data_attr}
|
||||
${p} GAUGE LINE2 ${p}"
|
||||
done
|
||||
;;
|
||||
fragmentation)
|
||||
global_attr="
|
||||
graph_title ZFS storage pool - Fragmentation
|
||||
graph_category fs
|
||||
graph_args --base 1000 --lower-limit 0 --upper-limit 100
|
||||
graph_vlabel % fragmentation
|
||||
graph_info ZFS storage pool - Fragmentation
|
||||
"
|
||||
for p in $pool_list
|
||||
do
|
||||
data_attr="${data_attr}
|
||||
${p} GAUGE LINE2 ${p}"
|
||||
done
|
||||
;;
|
||||
allocated)
|
||||
global_attr="
|
||||
graph_title ZFS storage pool - Allocated bytes
|
||||
graph_category fs
|
||||
graph_args --base 1024 --lower-limit 0
|
||||
graph_vlabel Bytes
|
||||
graph_info ZFS storage pool - Allocated bytes
|
||||
"
|
||||
c=0
|
||||
for p in $pool_list
|
||||
do
|
||||
data_attr="${data_attr}
|
||||
${p}_size GAUGE LINE ${p} size
|
||||
${p}_allocated GAUGE LINE2 ${p} allocated"
|
||||
global_attr="${global_attr}
|
||||
${p}_size.colour COLOUR${c}
|
||||
${p}_allocated.colour COLOUR${c}"
|
||||
c=$(( c + 1 ))
|
||||
done
|
||||
;;
|
||||
dedup)
|
||||
global_attr="
|
||||
graph_title ZFS storage pool - Dedup and compress ratio
|
||||
graph_category fs
|
||||
graph_args --base 1000 --lower-limit 1
|
||||
graph_vlabel Ratio
|
||||
graph_info ZFS storage pool - Dedup and compress ratio
|
||||
"
|
||||
for p in $pool_list
|
||||
do
|
||||
data_attr="${data_attr}
|
||||
${p}_dedup GAUGE LINE ${p} dedup
|
||||
${p}_compress GAUGE LINE ${p} compress"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
do_config() {
|
||||
local func="$1"
|
||||
local label_max_length=45
|
||||
local field type draw label
|
||||
|
||||
preconfig "$func"
|
||||
echo "multigraph ${plugin_name}_${func}"
|
||||
|
||||
# print global attributes
|
||||
echo "$global_attr" | sed -e 's/^ *//' -e '/^$/d'
|
||||
|
||||
# print data source attributes
|
||||
echo "$data_attr" | while read -r field type draw label
|
||||
do
|
||||
[ -z "$field" ] && continue
|
||||
|
||||
field=$( clean_fieldname "$field" )
|
||||
echo "${field}.type ${type}"
|
||||
echo "${field}.draw ${draw}"
|
||||
echo "${field}.label ${label:0:${label_max_length}}"
|
||||
if [ "$type" = 'DERIVE' ]; then
|
||||
echo "${field}.min 0"
|
||||
fi
|
||||
if [ "$label" = 'dummy' ]; then
|
||||
echo "${field}.graph no"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
get_stats() {
|
||||
local func="$1"
|
||||
|
||||
case $func in
|
||||
capacity)
|
||||
"$zpool_cmd" list -H -o name,capacity | sed 's/%$//'
|
||||
;;
|
||||
fragmentation)
|
||||
"$zpool_cmd" list -H -o name,fragmentation | sed 's/%$//'
|
||||
;;
|
||||
allocated)
|
||||
( "$zpool_cmd" list -H -p -o name,allocated \
|
||||
| awk '{ print $1"_allocated", $2 }'
|
||||
"$zpool_cmd" list -H -p -o name,size \
|
||||
| awk '{ print $1"_size", $2 }'
|
||||
)
|
||||
;;
|
||||
dedup)
|
||||
"$zpool_cmd" list -H -o name,dedup \
|
||||
| sed 's/x$//' \
|
||||
| awk '{ print $1"_dedup", $2 }'
|
||||
# example output:
|
||||
# $ zpool list -H -o name,dedup
|
||||
# rpool 1.00x
|
||||
# ...
|
||||
|
||||
"$zpool_cmd" list -H -o name \
|
||||
| xargs "$zfs_cmd" get -H -o name,value compressratio \
|
||||
| sed 's/x$//' \
|
||||
| awk '{ print $1"_compress", $2 }'
|
||||
# example output:
|
||||
# $ zfs get -H -o name,value compressratio rpool
|
||||
# rpool 1.00x
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
do_fetch() {
|
||||
local func="$1"
|
||||
local zpool_stats field value
|
||||
|
||||
# zpool_stats contains 'key value\n'
|
||||
zpool_stats=$( get_stats "$func" )
|
||||
|
||||
echo "multigraph ${plugin_name}_${func}"
|
||||
|
||||
echo "$zpool_stats" | while read -r field value
|
||||
do
|
||||
field=$( clean_fieldname "$field" )
|
||||
echo "${field}.value ${value}"
|
||||
done
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
autoconf() {
|
||||
if [ -x "$zpool_cmd" ]; then
|
||||
echo yes
|
||||
else
|
||||
echo "no (failed to find executable 'zpool')"
|
||||
fi
|
||||
}
|
||||
|
||||
config() {
|
||||
local func
|
||||
|
||||
pool_list=$( "$zpool_cmd" list -H -o name )
|
||||
|
||||
for func in $functions
|
||||
do
|
||||
do_config "$func"
|
||||
done
|
||||
}
|
||||
|
||||
fetch() {
|
||||
local func
|
||||
|
||||
for func in $functions
|
||||
do
|
||||
do_fetch "$func"
|
||||
done
|
||||
}
|
||||
|
||||
# Main
|
||||
case ${1:-} in
|
||||
autoconf)
|
||||
autoconf
|
||||
;;
|
||||
config)
|
||||
config
|
||||
if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then fetch; fi
|
||||
;;
|
||||
*)
|
||||
fetch
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@@ -111,9 +111,9 @@
|
||||
ansible.builtin.include_tasks: hypervisors.yml
|
||||
when: "'hypervisors' in group_names"
|
||||
|
||||
# - name: Execute specific ZFS commands
|
||||
# ansible.builtin.include_tasks: zfs.yml
|
||||
# when: "'zfsservers' in group_names"
|
||||
- name: Execute specific ZFS commands
|
||||
ansible.builtin.include_tasks: zfs.yml
|
||||
when: "'zfsservers' in group_names"
|
||||
|
||||
# Specific LXC commands
|
||||
- name: Execute specific LXC commands
|
||||
|
10
roles/munin_client/tasks/zfs.yml
Normal file
10
roles/munin_client/tasks/zfs.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Put zpool_capacity script
|
||||
ansible.builtin.copy:
|
||||
src: files/zpool_capacity
|
||||
dest: /etc/munin/plugins/zpool_capacity
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0o755"
|
||||
notify:
|
||||
- Restart munin-node
|
Reference in New Issue
Block a user