From 7f928fb5fb828e68ded9995fc2c5eeabb5051243 Mon Sep 17 00:00:00 2001 From: amichel Date: Fri, 15 May 2015 10:16:14 -0700 Subject: [PATCH 1/4] Re-submit zfsonlinux_stats_ --- plugins/zfs/zfsonlinux_stats_ | 330 ++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100755 plugins/zfs/zfsonlinux_stats_ diff --git a/plugins/zfs/zfsonlinux_stats_ b/plugins/zfs/zfsonlinux_stats_ new file mode 100755 index 00000000..5567dd39 --- /dev/null +++ b/plugins/zfs/zfsonlinux_stats_ @@ -0,0 +1,330 @@ +#!/bin/sh +# 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" + +ARC_HITS=`cat $ARCSTATS | grep ^hits | awk '{print $3}'` +ARC_MISSES=`cat $ARCSTATS | grep ^misses | awk '{print $3}'` + +DEMAND_DATA_HITS=`cat $ARCSTATS | grep ^demand_data_hits | awk '{print $3}'` +DEMAND_DATA_MISSES=`cat $ARCSTATS | grep ^demand_data_misses | awk '{print $3}'` +DEMAND_METADATA_HITS=`cat $ARCSTATS | grep ^demand_metadata_hits | awk '{print $3}'` +DEMAND_METADATA_MISSES=`cat $ARCSTATS | grep ^demand_metadata_misses | awk '{print $3}'` + +MFU_GHOST_HITS=`cat $ARCSTATS | grep ^mfu_ghost_hits | awk '{print $3}'` +MFU_HITS=`cat $ARCSTATS | grep ^mfu_hits | awk '{print $3}'` +MRU_GHOST_HITS=`cat $ARCSTATS | grep ^mru_ghost_hits | awk '{print $3}'` +MRU_HITS=`cat $ARCSTATS | grep ^mru_hits | awk '{print $3}'` + +PREFETCH_DATA_HITS=`cat $ARCSTATS | grep ^prefetch_data_hits | awk '{print $3}'` +PREFETCH_DATA_MISSES=`cat $ARCSTATS | grep ^prefetch_data_misses | awk '{print $3}'` +PREFETCH_METADATA_HITS=`cat $ARCSTATS | grep ^prefetch_metadata_hits | awk '{print $3}'` +PREFETCH_METADATA_MISSES=`cat $ARCSTATS | grep ^prefetch_metadata_misses | awk '{print $3}'` + +DMU_HITS=`cat $ZFETCHSTATS | grep ^hits | awk '{print $3}'` +DMU_MISSES=`cat $ZFETCHSTATS | grep ^misses | awk '{print $3}'` + +SIZE=`cat $ARCSTATS | grep ^size | awk '{print $3}'` +MRU_SIZE=`cat $ARCSTATS | grep ^p\ | awk '{print $3}'` +MAX_SIZE=`cat $ARCSTATS | grep ^c_max | awk '{print $3}'` +MIN_SIZE=`cat $ARCSTATS | grep ^c_min | awk '{print $3}'` +TARGET_SIZE=`cat $ARCSTATS | grep ^c\ | awk '{print $3}'` + +L2_SIZE=`cat $ARCSTATS | grep ^l2_size | awk '{print $3}'` +L2_HDR_SIZE=`cat $ARCSTATS | grep ^l2_hdr_size | awk '{print $3}'` + +L2_HITS=`cat $ARCSTATS | grep ^l2_hits | awk '{print $3}'` +L2_MISSES=`cat $ARCSTATS | grep ^l2_misses | awk '{print $3}'` + +# +# 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 filesystem" + +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 From 940fe451454412637e005dcdb70e5c4a3b1df2eb Mon Sep 17 00:00:00 2001 From: Adam Michel Date: Fri, 15 May 2015 17:28:14 -0700 Subject: [PATCH 2/4] Refactor of variable assignment method --- plugins/zfs/zfsonlinux_stats_ | 82 ++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/plugins/zfs/zfsonlinux_stats_ b/plugins/zfs/zfsonlinux_stats_ index 5567dd39..f87f7572 100755 --- a/plugins/zfs/zfsonlinux_stats_ +++ b/plugins/zfs/zfsonlinux_stats_ @@ -29,38 +29,62 @@ BC='/usr/bin/bc -q' ARCSTATS="/proc/spl/kstat/zfs/arcstats" ZFETCHSTATS="/proc/spl/kstat/zfs/zfetchstats" -ARC_HITS=`cat $ARCSTATS | grep ^hits | awk '{print $3}'` -ARC_MISSES=`cat $ARCSTATS | grep ^misses | awk '{print $3}'` +# +# Pull all values from arcstats +# -DEMAND_DATA_HITS=`cat $ARCSTATS | grep ^demand_data_hits | awk '{print $3}'` -DEMAND_DATA_MISSES=`cat $ARCSTATS | grep ^demand_data_misses | awk '{print $3}'` -DEMAND_METADATA_HITS=`cat $ARCSTATS | grep ^demand_metadata_hits | awk '{print $3}'` -DEMAND_METADATA_MISSES=`cat $ARCSTATS | grep ^demand_metadata_misses | awk '{print $3}'` +while read name type data +do + [[ $name =~ ^[0-9].* ]] && continue + [[ $name == "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 < /proc/spl/kstat/zfs/arcstats -MFU_GHOST_HITS=`cat $ARCSTATS | grep ^mfu_ghost_hits | awk '{print $3}'` -MFU_HITS=`cat $ARCSTATS | grep ^mfu_hits | awk '{print $3}'` -MRU_GHOST_HITS=`cat $ARCSTATS | grep ^mru_ghost_hits | awk '{print $3}'` -MRU_HITS=`cat $ARCSTATS | grep ^mru_hits | awk '{print $3}'` +# +# Pull all values from zfetchstats +# -PREFETCH_DATA_HITS=`cat $ARCSTATS | grep ^prefetch_data_hits | awk '{print $3}'` -PREFETCH_DATA_MISSES=`cat $ARCSTATS | grep ^prefetch_data_misses | awk '{print $3}'` -PREFETCH_METADATA_HITS=`cat $ARCSTATS | grep ^prefetch_metadata_hits | awk '{print $3}'` -PREFETCH_METADATA_MISSES=`cat $ARCSTATS | grep ^prefetch_metadata_misses | awk '{print $3}'` - -DMU_HITS=`cat $ZFETCHSTATS | grep ^hits | awk '{print $3}'` -DMU_MISSES=`cat $ZFETCHSTATS | grep ^misses | awk '{print $3}'` - -SIZE=`cat $ARCSTATS | grep ^size | awk '{print $3}'` -MRU_SIZE=`cat $ARCSTATS | grep ^p\ | awk '{print $3}'` -MAX_SIZE=`cat $ARCSTATS | grep ^c_max | awk '{print $3}'` -MIN_SIZE=`cat $ARCSTATS | grep ^c_min | awk '{print $3}'` -TARGET_SIZE=`cat $ARCSTATS | grep ^c\ | awk '{print $3}'` - -L2_SIZE=`cat $ARCSTATS | grep ^l2_size | awk '{print $3}'` -L2_HDR_SIZE=`cat $ARCSTATS | grep ^l2_hdr_size | awk '{print $3}'` - -L2_HITS=`cat $ARCSTATS | grep ^l2_hits | awk '{print $3}'` -L2_MISSES=`cat $ARCSTATS | grep ^l2_misses | awk '{print $3}'` +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 < /proc/spl/kstat/zfs/zfetchstats # # Calculation macros From 26cac8f8564ef9e7d77f85367f12edddc4d60566 Mon Sep 17 00:00:00 2001 From: Adam Michel Date: Fri, 15 May 2015 17:36:57 -0700 Subject: [PATCH 3/4] Forgot to use abstracted variables for stat files --- plugins/zfs/zfsonlinux_stats_ | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/zfs/zfsonlinux_stats_ b/plugins/zfs/zfsonlinux_stats_ index f87f7572..8fe5cd01 100755 --- a/plugins/zfs/zfsonlinux_stats_ +++ b/plugins/zfs/zfsonlinux_stats_ @@ -62,7 +62,7 @@ do export $VARNAME=$data ;; esac -done < /proc/spl/kstat/zfs/arcstats +done < $ARCSTATS # # Pull all values from zfetchstats @@ -84,7 +84,7 @@ do export $VARNAME=$data ;; esac -done < /proc/spl/kstat/zfs/zfetchstats +done < $ZFETCHSTATS # # Calculation macros From c1475343859d6aa50fed87fe954a07afee3e17b7 Mon Sep 17 00:00:00 2001 From: amichel Date: Sat, 16 May 2015 01:59:27 -0700 Subject: [PATCH 4/4] Change interpreter to bash, [[ is just better --- plugins/zfs/zfsonlinux_stats_ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/zfs/zfsonlinux_stats_ b/plugins/zfs/zfsonlinux_stats_ index 8fe5cd01..d96c8fd2 100755 --- a/plugins/zfs/zfsonlinux_stats_ +++ b/plugins/zfs/zfsonlinux_stats_ @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # ZFS statistics for ZFSonLinux # Author: Adam Michel (elfurbe@furbism.com) #