root / plugins / zfs / zpool_capacity @ 17f78427
Historique | Voir | Annoter | Télécharger (5,99 ko)
| 1 |
#!/bin/bash |
|---|---|
| 2 |
|
| 3 |
: << =cut |
| 4 |
|
| 5 |
=head1 NAME |
| 6 |
|
| 7 |
zpool_capacity - Munin plugin to monitor ZFS capacity |
| 8 |
|
| 9 |
These functions are implemented: |
| 10 |
capacity : to monitor zpool capacity % |
| 11 |
allocated : to monitor zpool allocated bytes |
| 12 |
dedup : to monitor zpool dedup and compress ratio |
| 13 |
|
| 14 |
Tested with Solaris 10 and 11, OpenIndiana Hipster, FreeBSD 11, CentOS 7 |
| 15 |
|
| 16 |
=head1 CONFIGURATION |
| 17 |
|
| 18 |
Make symlink: |
| 19 |
cd /path/to/munin/etc/plugins |
| 20 |
ln -s /path/to/munin/lib/plugins/zpool_capacity . |
| 21 |
|
| 22 |
For FreeBSD, it should be necessary to change shebang /bin/bash -> /usr/local/bin/bash |
| 23 |
|
| 24 |
For Linux, root privilege is necessary to run zpool command. |
| 25 |
[zpool_capacity] |
| 26 |
user root |
| 27 |
|
| 28 |
=head1 ENVIRONMENT VARIABLES |
| 29 |
|
| 30 |
critical : default 90 |
| 31 |
warning : default 80 |
| 32 |
|
| 33 |
=head1 AUTHOR |
| 34 |
|
| 35 |
K.Cima https://github.com/shakemid |
| 36 |
|
| 37 |
=head1 LICENSE |
| 38 |
|
| 39 |
GPLv2 |
| 40 |
|
| 41 |
=head1 Magic markers |
| 42 |
|
| 43 |
#%# family=contrib |
| 44 |
#%# capabilities=autoconf |
| 45 |
|
| 46 |
=cut |
| 47 |
|
| 48 |
# Include plugin.sh |
| 49 |
. "${MUNIN_LIBDIR:-}/plugins/plugin.sh"
|
| 50 |
is_multigraph "$@" |
| 51 |
|
| 52 |
# Shell options |
| 53 |
set -o nounset |
| 54 |
|
| 55 |
# Global variables |
| 56 |
plugin_name=zpool_capacity |
| 57 |
functions='capacity allocated dedup' |
| 58 |
zpool_cmd=/sbin/zpool |
| 59 |
zfs_cmd=/sbin/zfs |
| 60 |
|
| 61 |
# Environment variables |
| 62 |
: "${warning:=80}"
|
| 63 |
: "${critical:=90}"
|
| 64 |
|
| 65 |
# Note: The performance of ZFS may significantly degrade when zpool capacity > 90% |
| 66 |
# See also: https://docs.oracle.com/cd/E53394_01/html/E54801/zfspools-4.html |
| 67 |
|
| 68 |
# Functions |
| 69 |
|
| 70 |
preconfig() {
|
| 71 |
local func="$1" |
| 72 |
local p c |
| 73 |
|
| 74 |
# data_attr format: field type draw label |
| 75 |
# label can contain white-spaces. |
| 76 |
data_attr= |
| 77 |
|
| 78 |
case $func in |
| 79 |
capacity) |
| 80 |
global_attr=" |
| 81 |
graph_title ZFS storage pool - Capacity |
| 82 |
graph_category fs |
| 83 |
graph_args --base 1000 --lower-limit 0 --upper-limit 100 |
| 84 |
graph_vlabel % allocated |
| 85 |
graph_info ZFS storage pool - Capacity |
| 86 |
warning ${warning}
|
| 87 |
critical ${critical}
|
| 88 |
" |
| 89 |
for p in $pool_list |
| 90 |
do |
| 91 |
data_attr="${data_attr}
|
| 92 |
${p} GAUGE LINE2 ${p}"
|
| 93 |
done |
| 94 |
;; |
| 95 |
allocated) |
| 96 |
global_attr=" |
| 97 |
graph_title ZFS storage pool - Allocated bytes |
| 98 |
graph_category fs |
| 99 |
graph_args --base 1024 --lower-limit 0 |
| 100 |
graph_vlabel Bytes |
| 101 |
graph_info ZFS storage pool - Allocated bytes |
| 102 |
" |
| 103 |
c=0 |
| 104 |
for p in $pool_list |
| 105 |
do |
| 106 |
data_attr="${data_attr}
|
| 107 |
${p}_size GAUGE LINE ${p} size
|
| 108 |
${p}_allocated GAUGE LINE2 ${p} allocated"
|
| 109 |
global_attr="${global_attr}
|
| 110 |
${p}_size.colour COLOUR${c}
|
| 111 |
${p}_allocated.colour COLOUR${c}"
|
| 112 |
c=$(( c + 1 )) |
| 113 |
done |
| 114 |
;; |
| 115 |
dedup) |
| 116 |
global_attr=" |
| 117 |
graph_title ZFS storage pool - Dedup and compress ratio |
| 118 |
graph_category fs |
| 119 |
graph_args --base 1000 --lower-limit 1 |
| 120 |
graph_vlabel Ratio |
| 121 |
graph_info ZFS storage pool - Dedup and compress ratio |
| 122 |
" |
| 123 |
for p in $pool_list |
| 124 |
do |
| 125 |
data_attr="${data_attr}
|
| 126 |
${p}_dedup GAUGE LINE ${p} dedup
|
| 127 |
${p}_compress GAUGE LINE ${p} compress"
|
| 128 |
done |
| 129 |
;; |
| 130 |
esac |
| 131 |
} |
| 132 |
|
| 133 |
do_config() {
|
| 134 |
local func="$1" |
| 135 |
local label_max_length=45 |
| 136 |
local field type draw label |
| 137 |
|
| 138 |
preconfig "$func" |
| 139 |
echo "multigraph ${plugin_name}_${func}"
|
| 140 |
|
| 141 |
# print global attributes |
| 142 |
echo "$global_attr" | sed -e 's/^ *//' -e '/^$/d' |
| 143 |
|
| 144 |
# print data source attributes |
| 145 |
echo "$data_attr" | while read -r field type draw label |
| 146 |
do |
| 147 |
[ -z "$field" ] && continue |
| 148 |
|
| 149 |
field=$( clean_fieldname "$field" ) |
| 150 |
echo "${field}.type ${type}"
|
| 151 |
echo "${field}.draw ${draw}"
|
| 152 |
echo "${field}.label ${label:0:${label_max_length}}"
|
| 153 |
if [ "$type" = 'DERIVE' ]; then |
| 154 |
echo "${field}.min 0"
|
| 155 |
fi |
| 156 |
if [ "$label" = 'dummy' ]; then |
| 157 |
echo "${field}.graph no"
|
| 158 |
fi |
| 159 |
done |
| 160 |
|
| 161 |
echo |
| 162 |
} |
| 163 |
|
| 164 |
get_stats() {
|
| 165 |
local func="$1" |
| 166 |
|
| 167 |
case $func in |
| 168 |
capacity) |
| 169 |
"$zpool_cmd" list -H -o name,capacity | sed 's/%$//' |
| 170 |
;; |
| 171 |
allocated) |
| 172 |
( "$zpool_cmd" list -H -o name,allocated \ |
| 173 |
| awk '{ print $1"_allocated", $2 }'
|
| 174 |
"$zpool_cmd" list -H -o name,size \ |
| 175 |
| awk '{ print $1"_size", $2 }'
|
| 176 |
) \ |
| 177 |
| perl -ane ' |
| 178 |
@unit{ qw/ K M G T P E / } = ( 1 .. 6 );
|
| 179 |
$name = $F[0]; |
| 180 |
$byteu = $F[1]; |
| 181 |
( $n, $u ) = $byteu =~ /^([\d.]+)([KMGTPE]?)$/; |
| 182 |
$byte = int( $n * 1024 ** ( $u ? $unit{ $u } : 0 ) );
|
| 183 |
print "$name $byte\n"; |
| 184 |
' |
| 185 |
# Note: ZFS supports up to 16EB. |
| 186 |
;; |
| 187 |
dedup) |
| 188 |
"$zpool_cmd" list -H -o name,dedup \ |
| 189 |
| sed 's/x$//' \ |
| 190 |
| awk '{ print $1"_dedup", $2 }'
|
| 191 |
# example output: |
| 192 |
# $ zpool list -H -o name,dedup |
| 193 |
# rpool 1.00x |
| 194 |
# ... |
| 195 |
|
| 196 |
"$zpool_cmd" list -H -o name \ |
| 197 |
| xargs "$zfs_cmd" get -H -o name,value compressratio \ |
| 198 |
| sed 's/x$//' \ |
| 199 |
| awk '{ print $1"_compress", $2 }'
|
| 200 |
# example output: |
| 201 |
# $ zfs get -H -o name,value compressratio rpool |
| 202 |
# rpool 1.00x |
| 203 |
;; |
| 204 |
esac |
| 205 |
} |
| 206 |
|
| 207 |
do_fetch() {
|
| 208 |
local func="$1" |
| 209 |
local zpool_stats field value |
| 210 |
|
| 211 |
# zpool_stats contains 'key value\n' |
| 212 |
zpool_stats=$( get_stats "$func" ) |
| 213 |
|
| 214 |
echo "multigraph ${plugin_name}_${func}"
|
| 215 |
|
| 216 |
echo "$zpool_stats" | while read -r field value |
| 217 |
do |
| 218 |
field=$( clean_fieldname "$field" ) |
| 219 |
echo "${field}.value ${value}"
|
| 220 |
done |
| 221 |
|
| 222 |
echo |
| 223 |
} |
| 224 |
|
| 225 |
autoconf() {
|
| 226 |
if [ -x "$zpool_cmd" ]; then |
| 227 |
echo yes |
| 228 |
else |
| 229 |
echo "no (failed to find executable 'zpool')" |
| 230 |
fi |
| 231 |
} |
| 232 |
|
| 233 |
config() {
|
| 234 |
local func |
| 235 |
|
| 236 |
pool_list=$( "$zpool_cmd" list -H -o name ) |
| 237 |
|
| 238 |
for func in $functions |
| 239 |
do |
| 240 |
do_config "$func" |
| 241 |
done |
| 242 |
} |
| 243 |
|
| 244 |
fetch() {
|
| 245 |
local func |
| 246 |
|
| 247 |
for func in $functions |
| 248 |
do |
| 249 |
do_fetch "$func" |
| 250 |
done |
| 251 |
} |
| 252 |
|
| 253 |
# Main |
| 254 |
case ${1:-} in
|
| 255 |
autoconf) |
| 256 |
autoconf |
| 257 |
;; |
| 258 |
config) |
| 259 |
config |
| 260 |
if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then fetch; fi
|
| 261 |
;; |
| 262 |
*) |
| 263 |
fetch |
| 264 |
;; |
| 265 |
esac |
| 266 |
|
| 267 |
exit 0 |
