diff --git a/plugins/emc/emc_vnx_block_lun_perfdata b/plugins/emc/emc_vnx_block_lun_perfdata new file mode 100755 index 00000000..666469da --- /dev/null +++ b/plugins/emc/emc_vnx_block_lun_perfdata @@ -0,0 +1,351 @@ +#!/bin/bash + + + +# Need bc +# Some parts are rudimental.. +# sudo vim ./share/perl5/Munin/Master/GraphOld.pm +# http://munin-monitoring.org/ticket/1352 +# http://munin-monitoring.org/ticket/1017 + +###################################################################################################################### +# Plugin to monitor basic statistics of EMC VNX 5300 Unified Datamovers # +###################################################################################################################### + +# Author: Evgeny Beysembaev + +##################################### +# Description # +##################################### + +# The plugin monitors basic statistics of EMC Unified Storage system Datamovers. Probably it can also be compatible with +# other Isilon or Celerra systems. It uses SSH to connect to Control Stations, then remotely executes +# /nas/sbin/server_stats and fetches and parses data from it. It supports gathering data both from active/active +# and active/passive Datamover configurations, ignoring offline or standby Datamovers. If all Datamovers are +# offline or absent, the plugin returns error. +# This plugin also automatically chooses Primary Control Station from the list by calling /nasmcd/sbin/getreason and +# /nasmcd/sbin/t2slot. +# +# Data is gathered from basic-std Statistics Group +# +# It's quite easy to comment out unneeded data to make graphs less overloaded or to add new statistics sources. + +##################################### +# Configuration # +##################################### + +# The plugin uses SSH to connect to Control Stations. It's possible to use 'nasadmin' user, but it would be better +# if you create read-only global user by Unisphere Client. The user should have only Operator role. +# I created "operator" user but due to the fact that Control Stations already had one internal "operator" user, +# the new one was called "operator1". So be careful. +# +# On munin-node side choose a user which will be used to connect through SSH. Generally user "munin" is ok. Then, +# execute "sudo su munin -s /bin/bash", "ssh-keygen" and "ssh-copy-id" to both Control Stations with newly created +# user. +# +# Make a link from /usr/share/munin/plugins/emc_vnx_dm_basic_stats to /etc/munin/plugins/emc_vnx_dm_basic_stats_, +# where is any arbitrary name of your storage system. The plugin will return in its answer +# as "host_name" field. +# Assume your storage system is called "VNX5300". +# +# Make a configuration file at /etc/munin/plugin-conf.d/emc_vnx_dm_basic_stats_VNX5300 +# +# [emc_vnx_dm_basic_stats_VNX5300] +# user munin # SSH Client local user +# env.username operator1 # Remote user with Operator role +# env.cs_addr 192.168.1.1 192.168.1.2 # Control Stations addresses +# env.nas_servers server_2 server_3 # This is the default value and can be omitted + +##################################### +# History # +##################################### + +# 09.11.2016 - First Release + +###################################################################################################################### + +export LANG=C +TARGET=$(echo "${0##*/}" | cut -d _ -f 6) +#: ${nas_servers:="server_2 server_3"} +SSH_CHECK='ssh -q $username@$CS "/nasmcd/sbin/getreason | grep -w slot_\`/nasmcd/sbin/t2slot\` | cut -d- -f1"' + +if [ "$1" = "autoconf" ]; then + echo "yes" + exit 0 +fi + +if [ -z "$username" ]; then + echo "No username!" + exit 1 +fi + +if [ -z "$cs_addr" ]; then + echo "No control station addresses!" + exit 1 +fi + +#Choosing Cotrol Station. Code have to be "10" +for CS in $cs_addr; do + if [ "`eval $SSH_CHECK`" -eq "10" ]; then +# echo "$CS is Primary" + PRIMARY_CS=$CS + break + fi +done + +if [ -z "$PRIMARY_CS" ]; then + echo "No alive primary Control Station from list \"$cs_addr\""; + exit 1; +fi + +SP="SPA" #TODO +SPALL="SPA SPB" #TODO +SSH="ssh -q $username@$PRIMARY_CS " +NAVICLI="/nas/sbin/navicli -h $SP" + +# Get Lun List +LUNLIST="$($SSH $NAVICLI lun -list -drivetype | grep Name | sed -ne 's/^Name:\ *//p')" + +echo "host_name ${TARGET} +" + +if [ "$1" = "config" ] ; then + + echo "multigraph emc_vnx_block_blocks +graph_category disk +graph_title EMC VNX 5300 LUN Blocks +graph_vlabel Blocks Read (-) / Written (+) +graph_args --base 1000" + while read -r LUN ; do + echo "${LUN}_read.label none +${LUN}_read.graph no +${LUN}_read.min 0 +${LUN}_read.draw AREA +${LUN}_read.type DERIVE +${LUN}_write.label $LUN Blocks +${LUN}_write.negative ${LUN}_read +${LUN}_write.type DERIVE +${LUN}_write.min 0 +${LUN}_write.draw STACK" + done <<< $LUNLIST + + echo -e "\nmultigraph emc_vnx_block_req +graph_category disk +graph_title EMC VNX 5300 LUN Requests +graph_vlabel Requests: Read (-) / Write (+) +graph_args --base 1000" + while read -r LUN ; do + echo "${LUN}_readreq.label none +${LUN}_readreq.graph no +${LUN}_readreq.min 0 +${LUN}_readreq.type DERIVE +${LUN}_writereq.label $LUN Requests +${LUN}_writereq.negative ${LUN}_readreq +${LUN}_writereq.type DERIVE +${LUN}_writereq.min 0" + done <<< $LUNLIST + + echo -e "\nmultigraph emc_vnx_block_ticks +graph_category disk +graph_title EMC VNX 5300 Counted Load per LUN +graph_vlabel Load, % * Number of LUNs +graph_args --base 1000 -l 0 -r " +echo -n "graph_order " + while read -r LUN ; do + echo -n "${LUN}_busyticks ${LUN}_idleticks ${LUN}_bta=${LUN}_busyticks_spa ${LUN}_idleticks_spa ${LUN}_btb=${LUN}_busyticks_spb ${LUN}_idleticks_spb " + done <<< $LUNLIST + echo "" + while read -r LUN ; do + echo "${LUN}_busyticks_spa.label $LUN Busy Ticks SPA +${LUN}_busyticks_spa.type DERIVE +${LUN}_busyticks_spa.min 0 +${LUN}_busyticks_spa.draw AREA +${LUN}_busyticks_spa.graph no +${LUN}_bta.label $LUN Busy Ticks SPA +${LUN}_bta.graph 0 +${LUN}_idleticks_spa.label $LUN Idle Ticks SPA +${LUN}_idleticks_spa.type DERIVE +${LUN}_idleticks_spa.min 0 +${LUN}_idleticks_spa.draw AREA +${LUN}_idleticks_spa.graph no +${LUN}_busyticks_spb.label $LUN Busy Ticks SPB +${LUN}_busyticks_spb.type DERIVE +${LUN}_busyticks_spb.min 0 +${LUN}_busyticks_spb.draw AREA +${LUN}_busyticks_spb.graph 0 +${LUN}_btb.label $LUN Busy Ticks SPB +${LUN}_btb.graph 0 +${LUN}_idleticks_spb.label $LUN Idle Ticks SPB +${LUN}_idleticks_spb.type DERIVE +${LUN}_idleticks_spb.min 0 +${LUN}_idleticks_spb.draw AREA +${LUN}_idleticks_spb.graph 0" + +echo "${LUN}_load_spa.label $LUN load SPA +${LUN}_load_spa.draw AREASTACK +${LUN}_load_spb.label $LUN load SPB +${LUN}_load_spb.draw AREASTACK +${LUN}_load_spa.cdef 100,${LUN}_bta,${LUN}_busyticks_spa,${LUN}_idleticks_spa,+,/,* +${LUN}_load_spb.cdef 100,${LUN}_btb,${LUN}_busyticks_spa,${LUN}_idleticks_spa,+,/,* +" + done <<< $LUNLIST + + echo -e "\nmultigraph emc_vnx_block_outstanding +graph_category disk +graph_title EMC VNX 5300 Sum of Outstanding Requests +graph_vlabel Requests +graph_args --base 1000" + while read -r LUN ; do + echo "${LUN}_outstandsum.label $LUN +${LUN}_outstandsum.type DERIVE" + done <<< $LUNLIST + + echo -e "\nmultigraph emc_vnx_block_nonzeroreq +graph_category disk +graph_title EMC VNX 5300 Non-Zero Request Count Arrivals +graph_vlabel Count Arrivals +graph_args --base 1000" + while read -r LUN ; do + echo "${LUN}_nonzeroreq.label $LUN +${LUN}_nonzeroreq.type DERIVE" + done <<< $LUNLIST + + echo -e "\nmultigraph emc_vnx_block_trespasses +graph_category disk +graph_title EMC VNX 5300 Trespasses +graph_vlabel Trespasses" + while read -r LUN ; do + echo "${LUN}_implic_tr.label ${LUN} Implicit Trespasses +${LUN}_explic_tr.label ${LUN} Explicit Trespasses" + done <<< $LUNLIST + + + + + echo -e "\nmultigraph emc_vnx_block_queue +graph_category disk +graph_title EMC VNX 5300 Queue Length +graph_vlabel Length" +echo -n "graph_order " +while read -r LUN ; do + echo -n "${LUN}_bta=${LUN}_btspa ${LUN}_btb=${LUN}_btspb " + done <<< $LUNLIST +echo "" + while read -r LUN ; do + echo "${LUN}_btspa.label ${LUN}" + echo "${LUN}_btspa.graph no" + echo "${LUN}_btspa.type DERIVE" +# echo "${LUN}_bta.label ${LUN}" +# echo "${LUN}_bta.graph no" +# echo "${LUN}_bta.type DERIVE" + echo "${LUN}_idspa.label ${LUN}" + echo "${LUN}_idspa.graph no" + echo "${LUN}_idspa.type DERIVE" + echo "${LUN}_btspb.label ${LUN}" + echo "${LUN}_btspb.graph no" + echo "${LUN}_btspb.type DERIVE" +# echo "${LUN}_btb.label ${LUN}" +# echo "${LUN}_btb.graph no" +# echo "${LUN}_btb.type DERIVE" + echo "${LUN}_idspb.label ${LUN}" + echo "${LUN}_idspb.graph no" + echo "${LUN}_idspb.type DERIVE" + echo "${LUN}_oss.label ${LUN}" + echo "${LUN}_oss.graph no" + echo "${LUN}_oss.type DERIVE" + echo "${LUN}_nzr.label ${LUN}" + echo "${LUN}_nzr.graph no" + echo "${LUN}_nzr.type DERIVE" + echo "${LUN}_rr.label ${LUN}" + echo "${LUN}_rr.graph no" + echo "${LUN}_rr.type DERIVE" + echo "${LUN}_wr.label ${LUN}" + echo "${LUN}_wr.graph no" + echo "${LUN}_wr.type DERIVE" +# echo "${LUN}_w_p_r.label ${LUN}" +# echo "${LUN}_w_p_r.graph no" +# echo "${LUN}_w_p_r.cdef ${LUN}_writereq,${LUN}_readreq,+" + echo "${LUN}_ql_l_a.label ${LUN} Queue Length SPA" +# echo "${LUN}_ql_l.cdef ${LUN}_bta,${LUN}_oss,${LUN}_nzr,2,${LUN}_wr,${LUN}_rr,+,/,-,/,*,${LUN}_btspa,${LUN}_idspa,+,/" + echo "${LUN}_ql_l_a.cdef ${LUN}_oss,${LUN}_nzr,2,/,-,${LUN}_rr,${LUN}_wr,+,/,${LUN}_btspa,*,${LUN}_btspa,${LUN}_idspa,+,/" +# echo "${LUN}_ql_l_b.label ${LUN} Queue Length SPB" +# echo "${LUN}_ql_l_b.cdef ${LUN}_oss,${LUN}_nzr,2,/,-,${LUN}_rr,${LUN}_wr,+,/,${LUN}_btspb,*,${LUN}_btspb,${LUN}_idspb,+,/" +# echo "${LUN}_ql_l.cdef ${LUN}_oss,${LUN}_nzr,2,/,-,${LUN}_rr,${LUN}_wr,+,/,5000,*" + done <<< $LUNLIST + + + +exit 0 +fi +# -list -perfData +BIGSSHCMD="$SSH" +while read -r LUN ; do + BIGSSHCMD+="$NAVICLI lun -list -name $LUN -perfData | + sed -ne 's/^Blocks Read\:\ */${LUN}_read.value /p; + s/^Blocks Written\:\ */${LUN}_write.value /p; + s/Read Requests\:\ */${LUN}_readreq.value /p; + s/Write Requests\:\ */${LUN}_writereq.value /p; + s/Busy Ticks SP A\:\ */${LUN}_busyticks_spa.value /p; + s/Idle Ticks SP A\:\ */${LUN}_idleticks_spa.value /p; + s/Busy Ticks SP B\:\ */${LUN}_busyticks_spb.value /p; + s/Idle Ticks SP B\:\ */${LUN}_idleticks_spb.value /p; + s/Sum of Outstanding Requests\:\ */${LUN}_outstandsum.value /p; + s/Non-Zero Request Count Arrivals\:\ */${LUN}_nonzeroreq.value /p; + s/Implicit Trespasses\:\ */${LUN}_implic_tr.value /p; + s/Explicit Trespasses\:\ */${LUN}_explic_tr.value /p; + ' ;" +done <<< $LUNLIST +ANSWER="$($BIGSSHCMD)" +echo "multigraph emc_vnx_block_blocks" +echo "$ANSWER" | grep "read\.\|write\." +echo -e "\nmultigraph emc_vnx_block_req" +echo "$ANSWER" | grep "readreq\.\|writereq\." + +echo -e "\nmultigraph emc_vnx_block_ticks" +while read -r LUN ; do + LBTSPA=$(echo "$ANSWER" | sed -ne "s/^${LUN}_busyticks_spa\.value //p") + LIDSPA=$(echo "$ANSWER" | sed -ne "s/^${LUN}_idleticks_spa\.value //p") + LBTSPB=$(echo "$ANSWER" | sed -ne "s/^${LUN}_busyticks_spb\.value //p") + LIDSPB=$(echo "$ANSWER" | sed -ne "s/^${LUN}_idleticks_spb\.value //p") +# echo "${LUN}_load_spa.value" "$(( $LBTSPA*100 / ($LBTSPA+$LIDSPA) ))" +# echo "${LUN}_load_spb.value" "$(( $LBTSPB*100 / ($LBTSPB+$LIDSPB) ))" + echo "${LUN}_load_spa.value 0" + echo "${LUN}_load_spb.value 0" +done <<< $LUNLIST +echo "$ANSWER" | grep "busyticks_spa\.\|idleticks_spa\." +echo "$ANSWER" | grep "busyticks_spb\.\|idleticks_spb\." + +echo -e "\nmultigraph emc_vnx_block_outstanding" +echo "$ANSWER" | grep "outstandsum\." +echo -e "\nmultigraph emc_vnx_block_nonzeroreq" +echo "$ANSWER" | grep "nonzeroreq\." +echo -e "\nmultigraph emc_vnx_block_trespasses" +echo "$ANSWER" | grep "implic_tr\.\|explic_tr\." + +echo -e "\nmultigraph emc_vnx_block_queue" +# Queue Length +while read -r LUN ; do +# Queue Length SPA = ((Sum of Outstanding Requests SPA - NonZero Request Count Arrivals SPA / 2)/(Host Read Requests SPA + Host Write Requests SPA))* +# (Busy Ticks SPA/(Busy Ticks SPA + Idle Ticks SPA) + +# We count together SPA and SPB, although it is not fully corrext + + SOR=$(echo "$ANSWER" | sed -ne "s/^${LUN}_outstandsum\.value //p") + NZRCA=$(echo "$ANSWER" | sed -ne "s/^${LUN}_nonzeroreq\.value //p") + RR=$(echo "$ANSWER" | sed -ne "s/^${LUN}_readreq\.value //p") + WR=$(echo "$ANSWER" | sed -ne "s/^${LUN}_writereq\.value //p") + echo "$ANSWER" | sed -ne "s/^${LUN}_busyticks_spa\./${LUN}_btspa\./p" + echo "$ANSWER" | sed -ne "s/^${LUN}_idleticks_spa\./${LUN}_idspa\./p" + echo "$ANSWER" | sed -ne "s/^${LUN}_busyticks_spb\./${LUN}_btspb\./p" + echo "$ANSWER" | sed -ne "s/^${LUN}_idleticks_spb\./${LUN}_idspb\./p" + echo "$ANSWER" | grep "${LUN}_busyticks_spa\.\|${LUN}_idleticks_spa\." + echo "$ANSWER" | grep "${LUN}_busyticks_spb\.\|${LUN}_idleticks_spb\." + echo "$ANSWER" | sed -ne "s/^${LUN}_outstandsum\./${LUN}_oss\./p" + echo "$ANSWER" | sed -ne "s/^${LUN}_nonzeroreq\./${LUN}_nzr\./p" + echo "${LUN}_writereq_plus_readreq.value 0" + echo "$ANSWER" | sed -ne "s/^${LUN}_readreq\./${LUN}_rr\./p" + echo "$ANSWER" | sed -ne "s/^${LUN}_writereq\./${LUN}_wr\./p" + echo "${LUN}_ql_l_a.value 0 " + echo "${LUN}_ql_l_b.value 0 " +done <<< $LUNLIST +exit 0