diff --git a/plugins/zfs/zfs_stats_ b/plugins/zfs/zfs_stats_ new file mode 100755 index 00000000..d218e46d --- /dev/null +++ b/plugins/zfs/zfs_stats_ @@ -0,0 +1,254 @@ +#!/bin/sh +# ZFS statistics for FreeBSD +# Author: David Bjornsson +# +# Description: +# This is a rewrite of the zfs-stats-for-freebsd +# scripts by patpro. Rather then pulling the +# information from the zfs-stats utility, it +# pulls it straight from sysctl. +# +# Tested on FreeBSD 9.0-RELEASE +# +# 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 +# +#%# family=auto + +FUNCTION=$(basename $0 | cut -d_ -f3) +PAGESIZE=`/sbin/sysctl -n vm.stats.vm.v_page_size` +MEMSIZE=`/sbin/sysctl -n vm.stats.vm.v_page_count` +MEMMAX=`echo 'scale=2;' $PAGESIZE*$MEMSIZE | /usr/bin/bc -q` +BC='/usr/bin/bc -q' +SYS='/sbin/sysctl -n' + +# +# Sysctl macros +# + +ARC_HITS=`$SYS kstat.zfs.misc.arcstats.hits` +ARC_MISSES=`$SYS kstat.zfs.misc.arcstats.misses` + +DEMAND_DATA_HITS=`$SYS kstat.zfs.misc.arcstats.demand_data_hits` +DEMAND_DATA_MISSES=`$SYS kstat.zfs.misc.arcstats.demand_data_misses` +DEMAND_METADATA_HITS=`$SYS kstat.zfs.misc.arcstats.demand_metadata_hits` +DEMAND_METADATA_MISSES=`$SYS kstat.zfs.misc.arcstats.demand_metadata_misses` + +MFU_GHOST_HITS=`$SYS kstat.zfs.misc.arcstats.mfu_ghost_hits` +MFU_HITS=`$SYS kstat.zfs.misc.arcstats.mfu_hits` +MRU_GHOST_HITS=`$SYS kstat.zfs.misc.arcstats.mru_ghost_hits` +MRU_HITS=`$SYS kstat.zfs.misc.arcstats.mru_hits` + +PREFETCH_DATA_HITS=`$SYS kstat.zfs.misc.arcstats.prefetch_data_hits` +PREFETCH_DATA_MISSES=`$SYS kstat.zfs.misc.arcstats.prefetch_data_misses` +PREFETCH_METADATA_HITS=`$SYS kstat.zfs.misc.arcstats.prefetch_metadata_hits` +PREFETCH_METADATA_MISSES=`$SYS kstat.zfs.misc.arcstats.prefetch_metadata_misses` + +DMU_HITS=`$SYS kstat.zfs.misc.zfetchstats.hits` +DMU_MISSES=`$SYS kstat.zfs.misc.zfetchstats.misses` + +SIZE=`$SYS kstat.zfs.misc.arcstats.size` +MRU_SIZE=`$SYS kstat.zfs.misc.arcstats.p` +MAX_SIZE=`$SYS kstat.zfs.misc.arcstats.c_max` +MIN_SIZE=`$SYS kstat.zfs.misc.arcstats.c_min` +TARGET_SIZE=`$SYS kstat.zfs.misc.arcstats.c` + + +# +# 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` + +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` +DATA_DEMAND_EFFICIENCY_PERC=`echo "scale=2 ; (100*$DEMAND_DATA_HITS/$DEMAND_DATA_TOTAL)" | $BC` +DATA_PREFETCH_EFFICENCY_PERC=`echo "scale=2 ; (100*$PREFETCH_DATA_HITS/$PREFETCH_DATA_TOTAL)" | $BC` + +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` +DEMAND_DATA_MISS_PERC=`echo "scale=2 ; (100*$DEMAND_DATA_MISSES/$ARC_HITS)" | $BC` +PREFETCH_DATA_HIT_PERC=`echo "scale=2 ; (100*$PREFETCH_DATA_HITS/$ARC_HITS)" | $BC` +PREFETCH_DATA_MISS_PERC=`echo "scale=2 ; (100*$PREFETCH_DATA_MISSES/$ARC_HITS)" | $BC` +DEMAND_METADATA_HIT_PERC=`echo "scale=2 ; (100*$DEMAND_METADATA_HITS/$ARC_HITS)" | $BC` +DEMAND_METADATA_MISS_PERC=`echo "scale=2 ; (100*$DEMAND_METADATA_MISSES/$ARC_HITS)" | $BC` +PREFETCH_METADATA_HIT_PERC=`echo "scale=2 ; (100*$PREFETCH_METADATA_HITS/$ARC_HITS)" | $BC` +PREFETCH_METADATA_MISSES_PERC=`echo "scale=2 ; (100*$PREFETCH_METADATA_MISSES/$ARC_HITS)" | $BC` + +DMU_TOTAL=`echo "$DMU_HITS+$DMU_MISSES" | $BC` +DMU_HITS_PERC=`echo "scale=2 ; (100*$DMU_HITS/$DMU_TOTAL)" | $BC` +DMU_MISSES_PERC=`echo "scale=2 ; (100*$DMU_MISSES/$DMU_TOTAL)" | $BC` + +if [ $SIZE -gt $TARGET_SIZE ]; then + MFU_SIZE=`echo "$SIZE-$MRU_SIZE" | $BC` +else + MFU_SIZE=`echo "$TARGET_SIZE-$MRU_SIZE" | $BC` +fi + + +efficiency() { + + if [ "$1" = "config" ]; then + echo 'graph_title ZFS ARC Efficiency' + echo 'graph_args -u 100' + echo 'graph_vlabel %' + echo 'graph_category ZFS' + echo 'graph_info This graph shows the ARC Efficiency' + + echo 'hits.label Cache Hit Ratio' + echo 'misses.label Cache 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_category ZFS' + 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_category ZFS' + 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_category ZFS' + echo 'graph_info This graph shows the DMU prefetch stats' + + echo 'hits.label Hit percentage' + echo 'misses.label Miss percentage' + + 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_category ZFS' + echo 'graph_info This graph shows the ARC Size utilization' + + echo 'max_size.label Maximum Size' + echo 'max_size.draw AREA' + echo 'target_size.label Target Size' + echo 'target_size.draw AREA' + echo 'size.label Size' + echo 'size.draw AREA' + echo 'recently_size.label Recently Used Cache Size' + echo 'recently_size.draw AREA' + echo 'frequently_size.label Frequently Used Cache Size' + echo 'frequently_size.draw AREA' + echo 'min_size.label Minimum Size' + echo 'min_size.draw AREA' + + exit 0 + else + echo 'max_size.value ' $MAX_SIZE + echo 'target_size.value ' $TARGET_SIZE + echo 'size.value ' $SIZE + echo 'recently_size.value ' $MRU_SIZE + echo 'frequently_size.value ' $MFU_SIZE + echo 'min_size.value ' $MIN_SIZE + fi +} + +[ "$1" = "config" ] && echo "graph_category zfs" + +case "$FUNCTION" in + efficiency) + efficiency $1 + ;; + cachehitlist) + cachehitlist $1 + ;; + cachehitdtype) + cachehitdtype $1 + ;; + dmuprefetch) + dmuprefetch $1 + ;; + utilization) + utilization $1 + ;; +esac