Plugins hinzugefügt
This commit is contained in:
commit
4a7c3000b2
5 changed files with 1209 additions and 0 deletions
361
zfs_arcstats
Normal file
361
zfs_arcstats
Normal file
|
@ -0,0 +1,361 @@
|
|||
#!/bin/bash
|
||||
|
||||
: << =cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
zfs_arcstats - Munin multi-graph plugin to monitor ZFS ARC statistics
|
||||
|
||||
These functions are implemented:
|
||||
size : to monitor ARC size
|
||||
activity : to monitor ARC activities
|
||||
actlist : to monitor ARC activities by cache list (MFU/MRU)
|
||||
actdata : to monitor ARC activities by data type (Demand/Prefetch)
|
||||
hitratio : to monitor ARC hit ratio
|
||||
|
||||
Tested with Solaris 10 and 11, OpenIndiana Hipster, FreeBSD 11, CentOS 7
|
||||
This plugin is inspired by arcstat.pl [https://github.com/mharsch/arcstat]
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
Make symlink:
|
||||
cd /path/to/munin/etc/plugins
|
||||
ln -s /path/to/munin/lib/plugins/zfs_arcstats .
|
||||
|
||||
For FreeBSD, it should be necessary to change shebang /bin/bash -> /usr/local/bin/bash
|
||||
|
||||
=head1 ENVIRONMENT VARIABLES
|
||||
|
||||
None
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
K.Cima https://github.com/shakemid
|
||||
|
||||
=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
|
||||
|
||||
# Set global variables
|
||||
plugin_name=zfs_arcstats
|
||||
functions='size activity actlist actdata hitratio'
|
||||
|
||||
# Functions
|
||||
|
||||
get_osname() {
|
||||
local osname osver
|
||||
|
||||
osname=$( uname -s )
|
||||
osver=$( uname -v )
|
||||
|
||||
case $osname in
|
||||
SunOS)
|
||||
case $osver in
|
||||
illumos*)
|
||||
osname=illumos
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$osname"
|
||||
}
|
||||
|
||||
preconfig() {
|
||||
local func=$1
|
||||
|
||||
# data_attr format: field type draw label
|
||||
# label can contain white-spaces.
|
||||
|
||||
case $func in
|
||||
size)
|
||||
global_attr="
|
||||
graph_title ZFS ARC - Size
|
||||
graph_category fs
|
||||
graph_args --base 1024 --lower-limit 0
|
||||
graph_vlabel Bytes
|
||||
graph_info ZFS ARC - Size
|
||||
"
|
||||
case $osname in
|
||||
SunOS)
|
||||
# For Solaris 10,11
|
||||
data_attr="
|
||||
data_size GAUGE AREASTACK Data size
|
||||
prefetch_meta_size GAUGE AREASTACK Prefetch meta size
|
||||
buf_size GAUGE AREASTACK Buf size
|
||||
other_size GAUGE AREASTACK Other size
|
||||
"
|
||||
;;
|
||||
*)
|
||||
# For illumos, FreeBSD, Linux (OpenZFS)
|
||||
data_attr="
|
||||
data_size GAUGE AREASTACK Data size
|
||||
metadata_size GAUGE AREASTACK Metadata size
|
||||
hdr_size GAUGE AREASTACK Hdr size
|
||||
other_size GAUGE AREASTACK Other size
|
||||
mru_size GAUGE LINE MRU size
|
||||
mfu_size GAUGE LINE MFU size
|
||||
"
|
||||
;;
|
||||
esac
|
||||
data_attr="
|
||||
$data_attr
|
||||
size GAUGE LINE ARC size
|
||||
c GAUGE LINE Target size
|
||||
p GAUGE LINE Target MRU size
|
||||
"
|
||||
;;
|
||||
activity)
|
||||
global_attr="
|
||||
graph_title ZFS ARC - Activities
|
||||
graph_category fs
|
||||
graph_args --base 1000 --lower-limit 0
|
||||
graph_vlabel misses (-) / hits (+) per second
|
||||
graph_info ZFS ARC - Activities
|
||||
|
||||
hits.negative misses
|
||||
l2_hits.negative l2_misses
|
||||
"
|
||||
data_attr="
|
||||
misses DERIVE LINE dummy
|
||||
hits DERIVE LINE ARC
|
||||
l2_misses DERIVE LINE dummy
|
||||
l2_hits DERIVE LINE L2ARC
|
||||
"
|
||||
;;
|
||||
actlist)
|
||||
global_attr="
|
||||
graph_title ZFS ARC - Activities by cache list
|
||||
graph_category fs
|
||||
graph_args --base 1000 --lower-limit 0
|
||||
graph_vlabel ghost hits (-) / hits (+) per second
|
||||
graph_info ZFS ARC - Activities by cache list
|
||||
|
||||
mfu_hits.negative mfu_ghost_hits
|
||||
mru_hits.negative mru_ghost_hits
|
||||
"
|
||||
data_attr="
|
||||
mfu_ghost_hits DERIVE LINE dummy
|
||||
mfu_hits DERIVE LINE MFU
|
||||
mru_ghost_hits DERIVE LINE dummy
|
||||
mru_hits DERIVE LINE MRU
|
||||
"
|
||||
;;
|
||||
actdata)
|
||||
global_attr="
|
||||
graph_title ZFS ARC - Activities by data type
|
||||
graph_category fs
|
||||
graph_args --base 1000 --lower-limit 0
|
||||
graph_vlabel misses (-) / hits (+) per second
|
||||
graph_info ZFS ARC - Activities by data type
|
||||
|
||||
demand_data_hits.negative demand_data_misses
|
||||
demand_metadata_hits.negative demand_metadata_misses
|
||||
prefetch_data_hits.negative prefetch_data_misses
|
||||
prefetch_metadata_hits.negative prefetch_metadata_misses
|
||||
"
|
||||
data_attr="
|
||||
demand_data_misses DERIVE LINE dummy
|
||||
demand_data_hits DERIVE LINE D data
|
||||
demand_metadata_misses DERIVE LINE dummy
|
||||
demand_metadata_hits DERIVE LINE D meta
|
||||
prefetch_data_misses DERIVE LINE dummy
|
||||
prefetch_data_hits DERIVE LINE P data
|
||||
prefetch_metadata_misses DERIVE LINE dummy
|
||||
prefetch_metadata_hits DERIVE LINE P meta
|
||||
"
|
||||
;;
|
||||
hitratio)
|
||||
global_attr="
|
||||
graph_title ZFS ARC - Hit ratio
|
||||
graph_category fs
|
||||
graph_args --base 1000 --lower-limit 0 --upper-limit 100 --rigid
|
||||
graph_vlabel % hits
|
||||
graph_info ZFS ARC - Hit ratio - The graph shows cache hit ratio between munin-update intervals (usually 5 minutes).
|
||||
|
||||
hitratio.cdef hits,DUP,misses,+,/,100,*
|
||||
l2_hitratio.cdef l2_hits,DUP,l2_misses,+,/,100,*
|
||||
demand_data_hitratio.cdef demand_data_hits,DUP,demand_data_misses,+,/,100,*
|
||||
demand_metadata_hitratio.cdef demand_metadata_hits,DUP,demand_metadata_misses,+,/,100,*
|
||||
prefetch_data_hitratio.cdef prefetch_data_hits,DUP,prefetch_data_misses,+,/,100,*
|
||||
prefetch_metadata_hitratio.cdef prefetch_metadata_hits,DUP,prefetch_metadata_misses,+,/,100,*
|
||||
"
|
||||
data_attr="
|
||||
hits DERIVE LINE dummy
|
||||
misses DERIVE LINE dummy
|
||||
l2_hits DERIVE LINE dummy
|
||||
l2_misses DERIVE LINE dummy
|
||||
demand_data_hits DERIVE LINE dummy
|
||||
demand_data_misses DERIVE LINE dummy
|
||||
demand_metadata_hits DERIVE LINE dummy
|
||||
demand_metadata_misses DERIVE LINE dummy
|
||||
prefetch_data_hits DERIVE LINE dummy
|
||||
prefetch_data_misses DERIVE LINE dummy
|
||||
prefetch_metadata_hits DERIVE LINE dummy
|
||||
prefetch_metadata_misses DERIVE LINE dummy
|
||||
hitratio GAUGE LINE2 ARC hits
|
||||
l2_hitratio GAUGE LINE L2ARC hits
|
||||
demand_data_hitratio GAUGE LINE Demand data hits
|
||||
demand_metadata_hitratio GAUGE LINE Demand metadata hits
|
||||
prefetch_data_hitratio GAUGE LINE Prefetch data hits
|
||||
prefetch_metadata_hitratio GAUGE LINE Prefetch metadata hits
|
||||
"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown function: $func"
|
||||
exit 1
|
||||
;;
|
||||
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
|
||||
|
||||
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 arcstats stat value
|
||||
|
||||
case $osname in
|
||||
SunOS|illumos)
|
||||
arcstats=$( kstat -p 'zfs:0:arcstats' | sed -e 's/:/ /g' | awk '{ print $4,$5 }' )
|
||||
# kstat output example:
|
||||
# $ kstat -p zfs:0:arcstats
|
||||
# zfs:0:arcstats:c 4135233544
|
||||
# ...
|
||||
;;
|
||||
*BSD)
|
||||
arcstats=$( /sbin/sysctl -a | sed -n -e 's/^kstat\.zfs\.misc\.arcstats\.//p' | awk -F: '{ print $1,$2 }' )
|
||||
# sysctl output example:
|
||||
# $ sysctl -a
|
||||
# ...
|
||||
# kstat.zfs.misc.arcstats.c: 632540160
|
||||
# ...
|
||||
;;
|
||||
Linux)
|
||||
arcstats=$( sed '1,2d' /proc/spl/kstat/zfs/arcstats | awk '{ print $1,$3 }' )
|
||||
# proc file output example:
|
||||
# $ cat /proc/spl/kstat/zfs/arcstats
|
||||
# ...
|
||||
# name type data
|
||||
# hits 4 62
|
||||
# ...
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS: $osname"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
while read -r stat value
|
||||
do
|
||||
printf -v "arcstats_${stat}" "%s" "$value"
|
||||
# printf -v means indirect variable assignment (similar to eval)
|
||||
done <<< "$arcstats"
|
||||
}
|
||||
|
||||
do_fetch() {
|
||||
local func=$1
|
||||
local field type draw label value ref
|
||||
|
||||
preconfig "$func"
|
||||
echo "multigraph ${plugin_name}_${func}"
|
||||
|
||||
echo "$data_attr" | while read -r field type draw label
|
||||
do
|
||||
[ -z "$field" ] && continue
|
||||
|
||||
ref="arcstats_${field}"
|
||||
value=${!ref:-0}
|
||||
# ${!varname} means indirect evaluation (similar to eval)
|
||||
|
||||
echo "${field}.value ${value}"
|
||||
done
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
autoconf() {
|
||||
if [ -x /sbin/zfs ]; then
|
||||
echo yes
|
||||
else
|
||||
echo "no (ZFS looks unavailable)"
|
||||
fi
|
||||
}
|
||||
|
||||
config() {
|
||||
local func
|
||||
|
||||
for func in $functions
|
||||
do
|
||||
do_config "$func"
|
||||
done
|
||||
}
|
||||
|
||||
fetch() {
|
||||
local func
|
||||
|
||||
get_stats
|
||||
|
||||
for func in $functions
|
||||
do
|
||||
do_fetch "$func"
|
||||
done
|
||||
}
|
||||
|
||||
# Main
|
||||
|
||||
osname=$( get_osname )
|
||||
|
||||
case ${1:-} in
|
||||
autoconf)
|
||||
autoconf
|
||||
;;
|
||||
config)
|
||||
config
|
||||
if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then fetch; fi
|
||||
;;
|
||||
*)
|
||||
fetch
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
99
zfs_list
Normal file
99
zfs_list
Normal file
|
@ -0,0 +1,99 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Plugin to monitor ZFS Filesystems
|
||||
# Author: Adam Michel (elfurbe@furbism.com)
|
||||
# Description:
|
||||
# This is an extension of the zfs_fs plugin
|
||||
# modified as a multigraph to graph all zfs
|
||||
# filesystems it can find
|
||||
#
|
||||
# Tested on Ubuntu-14.04
|
||||
#
|
||||
# Parameters understood:
|
||||
#
|
||||
# config (required)
|
||||
# autoconf (optional - used by munin-config)
|
||||
#
|
||||
#%# family=auto
|
||||
|
||||
. "$MUNIN_LIBDIR/plugins/plugin.sh"
|
||||
|
||||
need_multigraph()
|
||||
|
||||
if [ "$1" = "autoconf" ]; then
|
||||
# Makes little sense to autoconf if you can't suggest
|
||||
echo no
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "suggest" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "config" ]; then
|
||||
for i in `zfs list -Hp | awk '{print $1}'`; do
|
||||
values=( $(zfs get -p usedbydataset,usedbychildren,usedbysnapshots,usedbyrefreservation,available,quota $i | awk 'BEGIN {total=0;} { if( NR==1 ) next; } !/quota/ {total=total+$3;} {print $3} END{print total;}') )
|
||||
fsname=$(clean_fieldname $(echo "$i" | sed 's/\//__/g'))
|
||||
|
||||
echo <<EOF "multigraph zfs_list_$fsname
|
||||
graph_title $fsname usage
|
||||
graph_order usedbydataset usedbychildren usedbysnapshots usedbyrefreservation available total quota
|
||||
graph_args --base 1024 -r -l 0 --vertical-label Bytes --upper-limit ${values[6]}
|
||||
graph_info This graph shows how is used a zfs filesystems.
|
||||
graph_category fs
|
||||
graph_period second
|
||||
usedbydataset.label UsedByDataset
|
||||
usedbydataset.draw AREA
|
||||
usedbydataset.info Used space by Dataset
|
||||
usedbydataset.colour FF0000
|
||||
usedbychildren.label UsedByChildren
|
||||
usedbychildren.draw STACK
|
||||
usedbychildren.info Used space by children
|
||||
usedbychildren.colour FFCC33
|
||||
usedbysnapshots.label UsedBySnapshots
|
||||
usedbysnapshots.draw STACK
|
||||
usedbysnapshots.info Used space by snapshot
|
||||
usedbysnapshots.colour 0000FF
|
||||
usedbyrefreservation.label Usedbyrefreservation
|
||||
usedbyrefreservation.draw STACK
|
||||
usedbyrefreservation.info Used space by Ref Reservation
|
||||
usedbyrefreservation.colour 33CCFF
|
||||
available.label Available
|
||||
available.draw STACK
|
||||
available.info Free space
|
||||
available.colour 00FF00
|
||||
total.label Total
|
||||
total.draw LINE1
|
||||
total.info Total
|
||||
total.colour 000000
|
||||
quota.label Quota
|
||||
quota.draw LINE1
|
||||
quota.info Quota
|
||||
quota.colour 555555"
|
||||
EOF
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for i in `zfs list -Hp | awk '{print $1}'`; do
|
||||
values=( $(zfs get -p usedbydataset,usedbychildren,usedbysnapshots,usedbyrefreservation,available,quota $i | awk 'BEGIN {total=0;} { if( NR==1 ) next; } !/quota/ {total=total+$3;} {print $3} END{print total;}') )
|
||||
fsname=$(clean_fieldname $(echo "$i" | sed 's/\//__/g'))
|
||||
|
||||
if [ ${values[5]} = "-" ]; then
|
||||
quota=0
|
||||
else
|
||||
quota=${values[5]}
|
||||
fi
|
||||
|
||||
echo <<EOF "multigraph zfs_list_$fsname
|
||||
usedbydataset.value ${values[0]}
|
||||
usedbysnapshots.value ${values[2]}
|
||||
usedbychildren.value ${values[1]}
|
||||
usedbyrefreservation.value ${values[3]}
|
||||
available.value ${values[4]}
|
||||
total.value ${values[6]}
|
||||
quota.value $quota"
|
||||
EOF
|
||||
done
|
||||
|
||||
exit 0
|
355
zfsonlinux_stats_
Normal file
355
zfsonlinux_stats_
Normal file
|
@ -0,0 +1,355 @@
|
|||
#!/usr/bin/env bash
|
||||
# ZFS statistics for ZFSonLinux
|
||||
# Author: Adam Michel (elfurbe@furbism.com)
|
||||
#
|
||||
# Description:
|
||||
# This is a modification of the zfs_stats
|
||||
# plugin by David Bjornsson (which was a
|
||||
# rewrite of zfs-stats-for-freebsd scripts
|
||||
# by patpro) modified to work with ZFSonLinux.
|
||||
#
|
||||
# Tested on Ubuntu-14.04
|
||||
#
|
||||
# Usage: zfs_stats_FUNCTION
|
||||
#
|
||||
# Available functions:
|
||||
# efficiency - ARC efficiency
|
||||
# cachehitlist - Cache hit by cache list
|
||||
# cachehitdtype - Cache hit by data type
|
||||
# dmuprefetch - DMU prefetch
|
||||
# utilization - ARC size breakdown
|
||||
# l2utilization - L2ARC size breakdown
|
||||
# l2efficiency - L2ARC efficiency
|
||||
#
|
||||
#%# family=auto
|
||||
|
||||
FUNCTION=$(basename $0 | cut -d_ -f3)
|
||||
MEMMAX=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'`
|
||||
BC='/usr/bin/bc -q'
|
||||
ARCSTATS="/proc/spl/kstat/zfs/arcstats"
|
||||
ZFETCHSTATS="/proc/spl/kstat/zfs/zfetchstats"
|
||||
|
||||
#
|
||||
# Pull all values from arcstats
|
||||
#
|
||||
|
||||
while read name type data
|
||||
do
|
||||
[[ $name =~ ^[0-9].* ]] && continue
|
||||
[[ $name == "name" ]] && continue
|
||||
[[ $name == "" ]] && continue
|
||||
case $name in
|
||||
"hits" )
|
||||
export ARC_HITS=$data
|
||||
;;
|
||||
"misses" )
|
||||
export ARC_MISSES=$data
|
||||
;;
|
||||
"p" )
|
||||
export MRU_SIZE=$data
|
||||
;;
|
||||
"c_max" )
|
||||
export MAX_SIZE=$data
|
||||
;;
|
||||
"c_min" )
|
||||
export MIN_SIZE=$data
|
||||
;;
|
||||
"c" )
|
||||
export TARGET_SIZE=$data
|
||||
;;
|
||||
* )
|
||||
VARNAME=`echo $name | tr '[:lower:]' '[:upper:]'`
|
||||
#declare $VARNAME=$data
|
||||
export $VARNAME=$data
|
||||
;;
|
||||
esac
|
||||
done < $ARCSTATS
|
||||
|
||||
#
|
||||
# Pull all values from zfetchstats
|
||||
#
|
||||
|
||||
while read name type data
|
||||
do
|
||||
[[ $name =~ ^[0-9].* ]] && continue
|
||||
[[ $name == "name" ]] && continue
|
||||
case $name in
|
||||
"hits" )
|
||||
export DMU_HITS=$data
|
||||
;;
|
||||
"misses" )
|
||||
export DMU_MISSES=$data
|
||||
;;
|
||||
* )
|
||||
VARNAME=`echo $name | tr '[:lower:]' '[:upper:]'`
|
||||
export $VARNAME=$data
|
||||
;;
|
||||
esac
|
||||
done < $ZFETCHSTATS
|
||||
|
||||
#
|
||||
# Calculation macros
|
||||
#
|
||||
|
||||
ANON_HITS=`echo "$ARC_HITS-($MFU_HITS+$MRU_HITS+$MFU_GHOST_HITS+$MRU_GHOST_HITS)" | $BC`
|
||||
ARC_ACCESSES_TOTAL=`echo "$ARC_HITS+$ARC_MISSES" | $BC`
|
||||
DEMAND_DATA_TOTAL=`echo "$DEMAND_DATA_HITS+$DEMAND_DATA_MISSES" | $BC`
|
||||
PREFETCH_DATA_TOTAL=`echo "$PREFETCH_DATA_HITS+$PREFETCH_DATA_MISSES" | $BC`
|
||||
REAL_HITS=`echo "$MFU_HITS+$MRU_HITS" | $BC`
|
||||
|
||||
if [ $ARC_ACCESSES_TOTAL != 0 ]; then
|
||||
CACHE_HIT_RATIO_PERC=`echo "scale=2 ; (100*$ARC_HITS/$ARC_ACCESSES_TOTAL)" | $BC`
|
||||
CACHE_MISS_RATIO_PERC=`echo "scale=2 ; (100*$ARC_MISSES/$ARC_ACCESSES_TOTAL)" | $BC`
|
||||
ACTUAL_HIT_RATIO_PERC=`echo "scale=2 ; (100*$REAL_HITS/$ARC_ACCESSES_TOTAL)" | $BC`
|
||||
else
|
||||
CACHE_HIT_RATIO_PERC=0
|
||||
CACHE_MISS_RATIO_PERC=0
|
||||
ACTUAL_HIT_RATIO_PERC=0
|
||||
fi
|
||||
|
||||
if [ $DEMAND_DATA_TOTAL != 0 ]; then DATA_DEMAND_EFFICIENCY_PERC=`echo "scale=2 ; (100*$DEMAND_DATA_HITS/$DEMAND_DATA_TOTAL)" | $BC`; else DATA_DEMAND_EFFICIENCY_PERC=0; fi
|
||||
if [ $PREFETCH_DATA_TOTAL != 0 ]; then DATA_PREFETCH_EFFICENCY_PERC=`echo "scale=2 ; (100*$PREFETCH_DATA_HITS/$PREFETCH_DATA_TOTAL)" | $BC`; else DATA_PREFETCH_EFFICENCY_PERC=0; fi
|
||||
|
||||
if [ $ARC_HITS != 0 ]; then
|
||||
ANONYMOUSLY_USED_PERC=`echo "scale=2 ; (100*$ANON_HITS/$ARC_HITS)" | $BC`
|
||||
MOST_RECENTLY_USED_PERC=`echo "scale=2 ; (100*$MRU_HITS/$ARC_HITS)" | $BC`
|
||||
MOST_FREQUENTLY_USED_PERC=`echo "scale=2 ; (100*$MFU_HITS/$ARC_HITS)" | $BC`
|
||||
MOST_RECENTLY_USED_GHOST_PERC=`echo "scale=2 ; (100*$MRU_GHOST_HITS/$ARC_HITS)" | $BC`
|
||||
MOST_FREQUENTLY_USED_GHOST_PERC=`echo "scale=2 ; (100*$MFU_GHOST_HITS/$ARC_HITS)" | $BC`
|
||||
|
||||
DEMAND_DATA_HIT_PERC=`echo "scale=2 ; (100*$DEMAND_DATA_HITS/$ARC_HITS)" | $BC`
|
||||
PREFETCH_DATA_HIT_PERC=`echo "scale=2 ; (100*$PREFETCH_DATA_HITS/$ARC_HITS)" | $BC`
|
||||
DEMAND_METADATA_HIT_PERC=`echo "scale=2 ; (100*$DEMAND_METADATA_HITS/$ARC_HITS)" | $BC`
|
||||
PREFETCH_METADATA_HIT_PERC=`echo "scale=2 ; (100*$PREFETCH_METADATA_HITS/$ARC_HITS)" | $BC`
|
||||
else
|
||||
ANONYMOUSLY_USED_PERC=0
|
||||
MOST_RECENTLY_USED_PERC=0
|
||||
MOST_FREQUENTLY_USED_PERC=0
|
||||
MOST_RECENTLY_USED_GHOST_PERC=0
|
||||
MOST_FREQUENTLY_USED_GHOST_PERC=0
|
||||
|
||||
DEMAND_DATA_HIT_PERC=0
|
||||
PREFETCH_DATA_HIT_PERC=0
|
||||
DEMAND_METADATA_HIT_PERC=0
|
||||
PREFETCH_METADATA_HIT_PERC=0
|
||||
fi
|
||||
|
||||
if [ $ARC_MISSES != 0 ]; then
|
||||
PREFETCH_METADATA_MISSES_PERC=`echo "scale=2 ; (100*$PREFETCH_METADATA_MISSES/$ARC_MISSES)" | $BC`
|
||||
DEMAND_DATA_MISS_PERC=`echo "scale=2 ; (100*$DEMAND_DATA_MISSES/$ARC_MISSES)" | $BC`
|
||||
PREFETCH_DATA_MISS_PERC=`echo "scale=2 ; (100*$PREFETCH_DATA_MISSES/$ARC_MISSES)" | $BC`
|
||||
DEMAND_METADATA_MISS_PERC=`echo "scale=2 ; (100*$DEMAND_METADATA_MISSES/$ARC_MISSES)" | $BC`
|
||||
else
|
||||
PREFETCH_METADATA_MISSES_PERC=0
|
||||
DEMAND_DATA_MISS_PERC=0
|
||||
PREFETCH_DATA_MISS_PERC=0
|
||||
DEMAND_METADATA_MISS_PERC=0
|
||||
fi
|
||||
|
||||
DMU_TOTAL=`echo "$DMU_HITS+$DMU_MISSES" | $BC`
|
||||
if [ $DMU_TOTAL != 0 ]; then
|
||||
DMU_HITS_PERC=`echo "scale=2 ; (100*$DMU_HITS/$DMU_TOTAL)" | $BC`
|
||||
DMU_MISSES_PERC=`echo "scale=2 ; (100*$DMU_MISSES/$DMU_TOTAL)" | $BC`
|
||||
else
|
||||
DMU_HITS_PERC=0
|
||||
DMU_MISSES_PERC=0
|
||||
fi
|
||||
|
||||
if [ $SIZE -gt $TARGET_SIZE ]; then
|
||||
MFU_SIZE=`echo "$SIZE-$MRU_SIZE" | $BC`
|
||||
else
|
||||
MFU_SIZE=`echo "$TARGET_SIZE-$MRU_SIZE" | $BC`
|
||||
fi
|
||||
|
||||
L2_ACCESSES_TOTAL=`echo "$L2_HITS+$L2_MISSES" | $BC`
|
||||
if [ $L2_ACCESSES_TOTAL -gt 0 ]; then
|
||||
L2_HIT_RATIO_PERC=`echo "scale=2 ; (100*$L2_HITS/$L2_ACCESSES_TOTAL)" | $BC`
|
||||
L2_MISS_RATIO_PERC=`echo "scale=2 ; (100*$L2_MISSES/$L2_ACCESSES_TOTAL)" | $BC`
|
||||
else
|
||||
L2_HIT_RATIO_PERC=0
|
||||
L2_MISS_RATIO_PERC=0
|
||||
fi
|
||||
|
||||
efficiency() {
|
||||
if [ "$1" = "config" ]; then
|
||||
echo 'graph_title ZFS ARC Efficiency'
|
||||
echo 'graph_args -u 100'
|
||||
echo 'graph_vlabel %'
|
||||
echo 'graph_info This graph shows the ARC Efficiency'
|
||||
|
||||
echo 'hits.label Hit Ratio'
|
||||
echo 'misses.label Miss Ratio'
|
||||
echo 'actual_hits.label Actual Hit Ratio'
|
||||
echo 'data_demand_efficiency.label Data Demand Efficiency'
|
||||
echo 'data_prefetch_efficiency.label Data Prefetch Efficiency'
|
||||
|
||||
exit 0
|
||||
else
|
||||
echo 'hits.value ' $CACHE_HIT_RATIO_PERC
|
||||
echo 'misses.value ' $CACHE_MISS_RATIO_PERC
|
||||
echo 'actual_hits.value ' $ACTUAL_HIT_RATIO_PERC
|
||||
echo 'data_demand_efficiency.value ' $DATA_DEMAND_EFFICIENCY_PERC
|
||||
echo 'data_prefetch_efficiency.value ' $DATA_PREFETCH_EFFICENCY_PERC
|
||||
fi
|
||||
}
|
||||
|
||||
cachehitlist() {
|
||||
if [ "$1" = "config" ]; then
|
||||
echo 'graph_title ZFS ARC Efficiency: Cache hits by cache list'
|
||||
echo 'graph_args -u 100'
|
||||
echo 'graph_vlabel %'
|
||||
echo 'graph_info This graph shows the ARC Efficiency'
|
||||
|
||||
echo 'cache_list_anon.label Anonymously Used'
|
||||
echo 'cache_list_most_rec.label Most Recently Used'
|
||||
echo 'cache_list_most_freq.label Most Frequently Used'
|
||||
echo 'cache_list_most_rec_ghost.label Most Recently Used Ghost'
|
||||
echo 'cache_list_most_freq_ghost.label Most Frequently Used Ghost'
|
||||
|
||||
exit 0
|
||||
else
|
||||
echo 'cache_list_anon.value ' $ANONYMOUSLY_USED_PERC
|
||||
echo 'cache_list_most_rec.value ' $MOST_RECENTLY_USED_PERC
|
||||
echo 'cache_list_most_freq.value ' $MOST_FREQUENTLY_USED_PERC
|
||||
echo 'cache_list_most_rec_ghost.value ' $MOST_RECENTLY_USED_GHOST_PERC
|
||||
echo 'cache_list_most_freq_ghost.value ' $MOST_FREQUENTLY_USED_GHOST_PERC
|
||||
fi
|
||||
}
|
||||
|
||||
cachehitdtype() {
|
||||
if [ "$1" = "config" ]; then
|
||||
echo 'graph_title ZFS ARC Efficiency: Cache hits by data type'
|
||||
echo 'graph_args -u 100'
|
||||
echo 'graph_vlabel %'
|
||||
echo 'graph_info This graph shows the ARC Efficiency'
|
||||
|
||||
echo 'data_type_demand_hits.label Demand Data Hit Ratio'
|
||||
echo 'data_type_demand_misses.label Demand Data Miss Ratio'
|
||||
echo 'data_type_prefetch_hits.label Prefetch Data Hit Ratio'
|
||||
echo 'data_type_prefetch_misses.label Prefetch Data Miss Ratio'
|
||||
echo 'data_type_demand_metadata_hits.label Demand Metadata Hit Ratio'
|
||||
echo 'data_type_demand_metadata_misses.label Demand Metadata Miss Ratio'
|
||||
echo 'data_type_prefetch_metadata_hits.label Prefetch Metadata Hit Ratio'
|
||||
echo 'data_type_prefetch_metadata_misses.label Prefetch Metadata Miss Ratio'
|
||||
|
||||
exit 0
|
||||
else
|
||||
echo 'data_type_demand_hits.value ' $DEMAND_DATA_HIT_PERC
|
||||
echo 'data_type_demand_misses.value ' $DEMAND_DATA_MISS_PERC
|
||||
echo 'data_type_prefetch_hits.value ' $PREFETCH_DATA_HIT_PERC
|
||||
echo 'data_type_prefetch_misses.value ' $PREFETCH_DATA_MISS_PERC
|
||||
echo 'data_type_demand_metadata_hits.value ' $DEMAND_METADATA_HIT_PERC
|
||||
echo 'data_type_demand_metadata_misses.value ' $DEMAND_METADATA_MISS_PERC
|
||||
echo 'data_type_prefetch_metadata_hits.value ' $PREFETCH_METADATA_HIT_PERC
|
||||
echo 'data_type_prefetch_metadata_misses.value ' $PREFETCH_METADATA_MISSES_PERC
|
||||
fi
|
||||
}
|
||||
|
||||
dmuprefetch() {
|
||||
if [ "$1" = "config" ]; then
|
||||
echo 'graph_title ZFS DMU prefetch stats'
|
||||
echo 'graph_args -u 100'
|
||||
echo 'graph_vlabel %'
|
||||
echo 'graph_info This graph shows the DMU prefetch stats'
|
||||
|
||||
echo 'hits.label Hit Ratio'
|
||||
echo 'misses.label Miss Ratio'
|
||||
|
||||
exit 0
|
||||
else
|
||||
echo 'hits.value ' $DMU_HITS_PERC
|
||||
echo 'misses.value ' $DMU_MISSES_PERC
|
||||
fi
|
||||
}
|
||||
|
||||
utilization() {
|
||||
if [ "$1" = "config" ]; then
|
||||
echo 'graph_title ZFS ARC Size'
|
||||
echo 'graph_args --base 1024 -l 0 --vertical-label Bytes --upper-limit '$MEMMAX
|
||||
echo 'graph_vlabel Size in MB'
|
||||
echo 'graph_info This graph shows the ARC Size utilization'
|
||||
|
||||
echo 'max_size.label Maximum Size'
|
||||
echo 'max_size.draw AREA'
|
||||
echo 'size.label Size'
|
||||
echo 'size.draw AREA'
|
||||
echo 'min_size.label Minimum Size'
|
||||
echo 'min_size.draw AREA'
|
||||
echo 'target_size.label Target Size'
|
||||
echo 'target_size.draw LINE1'
|
||||
echo 'recently_size.label Recently Used Cache Size'
|
||||
echo 'recently_size.draw LINE1'
|
||||
echo 'frequently_size.label Frequently Used Cache Size'
|
||||
echo 'frequently_size.draw LINE1'
|
||||
|
||||
exit 0
|
||||
else
|
||||
echo 'max_size.value ' $MAX_SIZE
|
||||
echo 'size.value ' $SIZE
|
||||
echo 'min_size.value ' $MIN_SIZE
|
||||
echo 'target_size.value ' $TARGET_SIZE
|
||||
echo 'recently_size.value ' $MRU_SIZE
|
||||
echo 'frequently_size.value ' $MFU_SIZE
|
||||
fi
|
||||
}
|
||||
|
||||
l2utilization() {
|
||||
if [ "$1" = "config" ]; then
|
||||
echo 'graph_title ZFS L2ARC Size'
|
||||
echo 'graph_args --base 1024 -r -l 0 --vertical-label Bytes'
|
||||
echo 'graph_vlabel Size in MB'
|
||||
echo 'graph_info This graph shows the L2ARC Size utilization'
|
||||
|
||||
echo 'size.label Size'
|
||||
echo 'size.draw AREA'
|
||||
echo 'hdr_size.label Header Size'
|
||||
echo 'hdr_size.draw AREA'
|
||||
|
||||
exit 0
|
||||
else
|
||||
echo 'size.value ' $L2_SIZE
|
||||
echo 'hdr_size.value ' $L2_HDR_SIZE
|
||||
fi
|
||||
}
|
||||
|
||||
l2efficiency() {
|
||||
if [ "$1" = "config" ]; then
|
||||
echo 'graph_title ZFS L2ARC Efficiency'
|
||||
echo 'graph_args -u 100'
|
||||
echo 'graph_vlabel %'
|
||||
echo 'graph_info This graph shows the L2ARC Efficiency'
|
||||
|
||||
echo 'l2_hits.label Hit Ratio'
|
||||
echo 'l2_misses.label Miss Ratio'
|
||||
else
|
||||
echo 'l2_hits.value ' $L2_HIT_RATIO_PERC
|
||||
echo 'l2_misses.value ' $L2_MISS_RATIO_PERC
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
[ "$1" = "config" ] && echo "graph_category fs"
|
||||
|
||||
case "$FUNCTION" in
|
||||
efficiency)
|
||||
efficiency $1
|
||||
;;
|
||||
cachehitlist)
|
||||
cachehitlist $1
|
||||
;;
|
||||
cachehitdtype)
|
||||
cachehitdtype $1
|
||||
;;
|
||||
dmuprefetch)
|
||||
dmuprefetch $1
|
||||
;;
|
||||
utilization)
|
||||
utilization $1
|
||||
;;
|
||||
l2utilization)
|
||||
l2utilization $1
|
||||
;;
|
||||
l2efficiency)
|
||||
l2efficiency $1
|
||||
;;
|
||||
esac
|
267
zpool_capacity
Normal file
267
zpool_capacity
Normal file
|
@ -0,0 +1,267 @@
|
|||
#!/bin/bash
|
||||
|
||||
: << =cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
zpool_capacity - Munin plugin to monitor ZFS capacity
|
||||
|
||||
These functions are implemented:
|
||||
capacity : to monitor zpool capacity %
|
||||
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
|
||||
|
||||
=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 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
|
||||
;;
|
||||
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/%$//'
|
||||
;;
|
||||
allocated)
|
||||
( "$zpool_cmd" list -H -o name,allocated \
|
||||
| awk '{ print $1"_allocated", $2 }'
|
||||
"$zpool_cmd" list -H -o name,size \
|
||||
| awk '{ print $1"_size", $2 }'
|
||||
) \
|
||||
| perl -ane '
|
||||
@unit{ qw/ K M G T P E / } = ( 1 .. 6 );
|
||||
$name = $F[0];
|
||||
$byteu = $F[1];
|
||||
( $n, $u ) = $byteu =~ /^([\d.]+)([KMGTPE]?)$/;
|
||||
$byte = int( $n * 1024 ** ( $u ? $unit{ $u } : 0 ) );
|
||||
print "$name $byte\n";
|
||||
'
|
||||
# Note: ZFS supports up to 16EB.
|
||||
;;
|
||||
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
|
127
zpool_iostat
Normal file
127
zpool_iostat
Normal file
|
@ -0,0 +1,127 @@
|
|||
#!/bin/sh
|
||||
# -*- sh -*-
|
||||
|
||||
set -eu
|
||||
|
||||
: <<=cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
zpool_iostat - Plugin to monitor transfer statistics of ZFS pools
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
All systems with "zpool" installed.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
No configuration is required.
|
||||
|
||||
=head1 INTERPRETATION
|
||||
|
||||
This plugin shows a graph with read (positive) and write (negative) values
|
||||
for the IO transfer of each pool.
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
tsaavik <github@hellspark.com>
|
||||
Peter Doherty <peterd@acranox.org>
|
||||
Lars Kruse <devel@sumpfralle.de>
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# shellcheck source=/usr/share/munin/plugins/plugin.sh
|
||||
. "$MUNIN_LIBDIR/plugins/plugin.sh"
|
||||
|
||||
|
||||
ZPOOL_BIN=/sbin/zpool
|
||||
ACTION="${1:-}"
|
||||
|
||||
|
||||
if [ "$ACTION" = "autoconf" ]; then
|
||||
if [ -x "$ZPOOL_BIN" ]; then
|
||||
echo yes
|
||||
else
|
||||
echo "no (missing executable '$ZPOOL_BIN')"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
zlines=$("$ZPOOL_BIN" iostat -v | wc -l | sed 's/ //g')
|
||||
iostats=$("$ZPOOL_BIN" iostat -v 1 1 | tail "-$zlines")
|
||||
zlist=$(echo "$iostats" \
|
||||
| awk '/alloc/ {next}; /avail/ {next}; /raid/ {next}; /mirror/ {next};
|
||||
{ if ( $4 >=0 ) print $1}' \
|
||||
| tr ' ' '\n')
|
||||
|
||||
# Parse the n'th column of the iostat output for a given pool or disk as a
|
||||
# number (interpreting K and M suffixes).
|
||||
get_device_iostat_column() {
|
||||
local device_label="$1"
|
||||
local stat_column="$2"
|
||||
# convert all numeric values into kB
|
||||
echo "$iostats" \
|
||||
| awk '{ if ($1 == "'"$device_label"'") print $'"$stat_column"'; }' \
|
||||
| awk '/M/ {print int($1)*1000};
|
||||
/K/ {print int($1)};
|
||||
/[0-9]$/ {print int($1)/1000}'
|
||||
}
|
||||
|
||||
|
||||
get_device_fieldname() {
|
||||
local device_id="$1"
|
||||
# Backwards compatibility (until 2016): keep the unprefixed pool name
|
||||
# for the fieldname, except for pool names starting with digits.
|
||||
if echo "$device_id" | grep -q "^[0-9]"; then
|
||||
clean_fieldname "_$device_id"
|
||||
else
|
||||
clean_fieldname "$device_id"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [ "$ACTION" = "config" ]; then
|
||||
echo 'graph_title zpool iostat'
|
||||
echo 'graph_args --base 1000 -l 0'
|
||||
echo 'graph_vlabel write (-) / read (+) KBytes/s'
|
||||
echo 'graph_category disk'
|
||||
echo 'graph_scale no'
|
||||
echo 'graph_info This graph shows zpool iostat'
|
||||
# Assemble the "graph_order" as a sorted list of read/write pairs for
|
||||
# each device.
|
||||
printf "graph_order"
|
||||
echo "$zlist" | while read -r device_id; do
|
||||
fieldname="$(get_device_fieldname "$device_id")"
|
||||
printf " %s_read %s_write" "$fieldname" "$fieldname"
|
||||
done
|
||||
# finalize the 'graph_order' with a newline
|
||||
echo
|
||||
# output all fields: write as negative numbers and read as positive
|
||||
echo "$zlist" | while read -r device_id; do
|
||||
fieldname="$(get_device_fieldname "$device_id")"
|
||||
echo "${fieldname}_read.label $device_id"
|
||||
echo "${fieldname}_read.type GAUGE"
|
||||
echo "${fieldname}_read.graph no"
|
||||
echo "${fieldname}_write.label $device_id"
|
||||
echo "${fieldname}_write.type GAUGE"
|
||||
echo "${fieldname}_write.negative ${fieldname}_read"
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
echo "$zlist" | while read -r device_id; do
|
||||
fieldname="$(get_device_fieldname "$device_id")"
|
||||
echo "${fieldname}_read.value $(get_device_iostat_column "$device_id" 6)"
|
||||
echo "${fieldname}_write.value $(get_device_iostat_column "$device_id" 7)"
|
||||
done
|
Loading…
Reference in a new issue