From 726abac4619fa9ccaf3d73811e55fd77c8b2dd53 Mon Sep 17 00:00:00 2001 From: "K.Cima" Date: Sun, 16 Apr 2017 21:58:21 +0900 Subject: [PATCH] Add interrupts, forks, fsstat_bytes, fsstat_act_ plugins for Solaris --- plugins/solaris/forks | 112 ++++++++++++++++++++++ plugins/solaris/fsstat_act_ | 175 +++++++++++++++++++++++++++++++++++ plugins/solaris/fsstat_bytes | 172 ++++++++++++++++++++++++++++++++++ plugins/solaris/interrupts | 132 ++++++++++++++++++++++++++ 4 files changed, 591 insertions(+) create mode 100755 plugins/solaris/forks create mode 100755 plugins/solaris/fsstat_act_ create mode 100755 plugins/solaris/fsstat_bytes create mode 100755 plugins/solaris/interrupts diff --git a/plugins/solaris/forks b/plugins/solaris/forks new file mode 100755 index 00000000..fd79393c --- /dev/null +++ b/plugins/solaris/forks @@ -0,0 +1,112 @@ +#!/bin/bash + +: << =cut + +=head1 NAME + + forks - Munin plugin to monitor Solaris fork and exec rate + +=head1 CONFIGURATION + + Make symlink: + cd /path/to/munin/etc/plugins + ln -s /path/to/munin/lib/plugins/forks . + +=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" + +# Shell options +set -o nounset # Like perl use strict; + +# Graph settings +global_attr=" + graph_title Fork and exec rate + graph_category processes + graph_args --base 1000 --lower-limit 0 --rigid + graph_vlabel count per second + graph_info Fork and exec rate +" +# data_attr format: field type draw label +# label can contain white-spaces. +data_attr=" + sysfork DERIVE LINE fork + sysvfork DERIVE LINE vfork + sysexec DERIVE LINE exec +" + +# Functions + +autoconf() { + if [ -x "$( which kstat )" ]; then + echo yes + else + echo "no (failed to find executable 'kstat')" + fi +} + +config() { + local label_max_length=45 + + # print global attributes + sed -e 's/^ *//' -e '/^$/d' <<< "${global_attr}" + + # print data source attributes + # split line into field,type,draw,label + local fields field type draw label + fields= + while read -r field type draw label + do + [ -z "$field" ] && continue + fields="${fields} ${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 + done <<< "${data_attr}" + + echo graph_order "$fields" +} + +getvalue() { + local field type draw label + while read -r field type draw label + do + [ -z "$field" ] && continue + value=$( kstat -p "cpu::sys:${field}" | awk '{ sum += $2 } END { print sum }' ) + echo "${field}.value ${value}" + done <<< "${data_attr}" +} + +# Main +case ${1:-} in +autoconf) + autoconf + ;; +config) + config + [ "${MUNIN_CAP_DIRTYCONFIG:-}" = "1" ] && getvalue + ;; +*) + getvalue + ;; +esac + +exit 0 diff --git a/plugins/solaris/fsstat_act_ b/plugins/solaris/fsstat_act_ new file mode 100755 index 00000000..07af4e58 --- /dev/null +++ b/plugins/solaris/fsstat_act_ @@ -0,0 +1,175 @@ +#!/bin/bash + +: << =cut + +=head1 NAME + + fsstat_act_ - Munin wildcard plugin to monitor Solaris file system statistics + + This plugin monitors full activity of file system like fsstat -f . + See man fsstat for more details. + + Tested with Solaris 10 and 11. And should work with Solaris 10 11/06 or above. + + Note: + In Solaris 11, fsstat command can get stats for each non-global zones in + global zone. (see man fsstat) + In global zone, this plugin gets stats of only global zone. + In non-global zones, this plugin reports stats of the non-global zones. + +=head1 CONFIGURATION + + This plugin monitors statistics per file system type. Available file system + can be shown by fsstat command. + + Make symlink: + cd /path/to/munin/etc/plugins + ln -s /path/to/munin/lib/plugins/fsstat_act_ fsstat_act_zfs + ln -s /path/to/munin/lib/plugins/fsstat_act_ fsstat_act_nfs3 + ln -s /path/to/munin/lib/plugins/fsstat_act_ fsstat_act_nfs4 + ... + +=head1 ENVIRONMET VARIABLES + + None + +=head1 AUTHOR + + K.Cima https://github.com/shakemid + +=head1 LICENSE + + GPLv2 + +=head1 Magic markers + + #%# family=contrib + #%# capabilities=autoconf suggest + +=cut + +# Include plugin.sh +. "${MUNIN_LIBDIR:-}/plugins/plugin.sh" + +# Shell options +set -o nounset # Like perl use strict; + +# Set environment variables +plugin_name=${0##*/} +fs_type=${plugin_name##*_} +name_regexp='/^vopstats_(?![0-9a-f]{7})[a-z]/' # data source of fsstat +stat_regexp='/^(?!(class|crtime|snaptime|.*_bytes))/' + +# Graph settings +global_attr=" + graph_title File system statictics - Activities of ${fs_type^^} + graph_category disk + graph_args --base 1000 + graph_vlabel Counts per second + graph_info File system statictics - Activities of ${fs_type^^} +" + +# Functions + +get_zone_id() { + local osver zonename zoneid + + zoneid=0 + osver=$( uname -r | cut -d. -f2 ) + + if [ "$osver" -ge 11 ]; then + zonename=$( zonename ) + zoneid=$( /usr/sbin/zoneadm list -p | awk -F: '$2 == "'"$zonename"'" { print $1 }' ) + fi + + echo "$zoneid" +} + +autoconf() { + if [ -x "$( which kstat )" ]; then + echo yes + else + echo "no (failed to find executable 'kstat')" + fi +} + +suggest() { + # Print file systems which look active + + kstat -p "unix:${zone_id}:${name_regexp}:/^(read_bytes|write_bytes)\$/" | \ + sed -e 's/vopstats_//' -e 's/:/ /g' | \ + awk '{ + sum[ $3 ] += $5 + } + END { + for ( i in sum ) { + if ( sum[i] != 0 ) { + print i + } + } + }' | sort +} + +config() { + local stat + + # Print global attributes + echo "${global_attr}" | sed -e 's/^ *//' -e '/^$/d' + + # Get stat names by kstat + kstat -p "unix:${zone_id}:vopstats_${fs_type}:${stat_regexp}" | \ + sed -e 's/vopstats_//' -e 's/:/ /g' | awk '{ print $4 }' | sort -u | \ + while read -r stat + do + # Print data attributes + echo "${stat}.label ${stat#n}" + echo "${stat}.graph line" + echo "${stat}.type DERIVE" + echo "${stat}.min 0" + done + + echo +} + +getvalue() { + local stat value + + # Get fs names, stat names and values by kstat + + # kstat output example: + # $ kstat -p 'unix::/^vopstats_[a-z]/:nread' + # unix:0:vopstats_autofs:nread 2 + # unix:0:vopstats_hsfs:nread 407790 + # ... + + kstat -p "unix:${zone_id}:vopstats_${fs_type}:${stat_regexp}" | \ + sed -e 's/vopstats_//' -e 's/:/ /g' | awk '{ print $4,$5 }' | \ + while read -r stat value + do + echo "${stat}.value ${value}" + done + + echo +} + +# Main + +zone_id=$( get_zone_id ) + +case ${1:-} in +autoconf) + autoconf + ;; +suggest) + suggest + ;; +config) + config + [ "${MUNIN_CAP_DIRTYCONFIG:-}" = "1" ] && getvalue + ;; +*) + getvalue + ;; +esac + +exit 0 diff --git a/plugins/solaris/fsstat_bytes b/plugins/solaris/fsstat_bytes new file mode 100755 index 00000000..f2078d4a --- /dev/null +++ b/plugins/solaris/fsstat_bytes @@ -0,0 +1,172 @@ +#!/bin/bash + +: << =cut + +=head1 NAME + + fsstat_bytes - Munin plugin to monitor Solaris file system statistics + + Tested with Solaris 10 and 11. + + Note: + In Solaris 11, fsstat command can get stats for each non-global zones in + global zone. (see man fsstat) + In global zone, this plugin gets stats of only global zone. + In non-global zones, this plugin reports stats of the non-global zones. + +=head1 CONFIGURATION + + Make symlink: + cd /path/to/munin/etc/plugins + ln -s /path/to/munin/lib/plugins/fsstat_bytes . + +=head1 ENVIRONMET VARIABLES + + env.exclude - file system(s) to exclude seperated by white-space. + example: env.exclude autofs + default: 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" + +# Shell options +set -o nounset # Like perl use strict; + +# Set environment variables +name_regexp='/^vopstats_(?![0-9a-f]{7})[a-z]/' # data source of fsstat +: "${exclude:=}" + +# Set graph settings +global_attr=" + graph_title File system statictics - I/O throughput + graph_category disk + graph_args --base 1024 + graph_vlabel Bytes per second write (-) / read (+) + graph_info File system statictics - I/O throughput +" +data_in=read_bytes +data_out=write_bytes + + +# Functions + +is_excluded() { + local arg i + arg=$1 + + for i in ${exclude} + do + if [ "$arg" = "$i" ]; then + return 0 + fi + done + + return 1 +} + +get_zone_id() { + local osver zonename zoneid + + zoneid=0 + osver=$( uname -r | cut -d. -f2 ) + + if [ "$osver" -ge 11 ]; then + zonename=$( zonename ) + zoneid=$( /usr/sbin/zoneadm list -p | awk -F: '$2 == "'"$zonename"'" { print $1 }' ) + fi + + echo "$zoneid" +} + +autoconf() { + if [ -x "$( which kstat )" ]; then + echo yes + else + echo "no (failed to find executable 'kstat')" + fi +} + +config() { + local fs + + # Print global attributes + echo "${global_attr}" | sed -e 's/^ *//' -e '/^$/d' + + # Get fs names by kstat + kstat -p "unix:${zone_id}:${name_regexp}:${data_in}" | \ + sed -e 's/vopstats_//' -e 's/:/ /g' | awk '{ print $3 }' | sort -u | \ + while read -r fs + do + is_excluded "$fs" && continue + + # Print data attributes + echo "${fs}_${data_out}.label dummy" + echo "${fs}_${data_out}.graph no" + echo "${fs}_${data_out}.type DERIVE" + echo "${fs}_${data_out}.min 0" + + echo "${fs}_${data_in}.label ${fs}" + echo "${fs}_${data_in}.negative ${fs}_${data_out}" + echo "${fs}_${data_in}.type DERIVE" + echo "${fs}_${data_in}.min 0" + done + + echo +} + +getvalue() { + local fs stat value + + # Get fs names, stat names and values by kstat + + # kstat output example: + # $ kstat -p 'unix::/^vopstats_[a-z]/:nread' + # unix:0:vopstats_autofs:nread 2 + # unix:0:vopstats_hsfs:nread 407790 + # ... + + kstat -p "unix:${zone_id}:${name_regexp}:/^(${data_in}|${data_out})\$/" | \ + sed -e 's/vopstats_//' -e 's/:/ /g' | awk '{ print $3,$4,$5 }' | \ + while read -r fs stat value + do + is_excluded "$fs" && continue + + echo "${fs}_${stat}.value ${value}" + done + + echo +} + +# Main + +zone_id=$( get_zone_id ) + +case ${1:-} in +autoconf) + autoconf + ;; +config) + config + [ "${MUNIN_CAP_DIRTYCONFIG:-}" = "1" ] && getvalue + ;; +*) + getvalue + ;; +esac + +exit 0 diff --git a/plugins/solaris/interrupts b/plugins/solaris/interrupts new file mode 100755 index 00000000..bb34b5ef --- /dev/null +++ b/plugins/solaris/interrupts @@ -0,0 +1,132 @@ +#!/bin/bash + +: << =cut + +=head1 NAME + + interrupts - Munin plugin to monitor Solaris cpu interrupts and context switches + +=head1 CONFIGURATION + + Make symlink: + cd /path/to/munin/etc/plugins + ln -s /path/to/munin/lib/plugins/interrupts . + +=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" + +# Shell options +set -o nounset # Like perl use strict; + +# Graph settings +global_attr=" + graph_title Interrupts and context switches + graph_category system + graph_args --base 1000 --lower-limit 0 --rigid + graph_vlabel count per second + graph_info Interrupts and context switches + + rw_wrfails.graph no + rw_rdfails.cdef rw_rdfails,rw_wrfails,+ +" +# data_attr format: field type draw label +# label can contain white-spaces. +data_attr=" + intr DERIVE LINE interrupts + intrthread DERIVE LINE interrupts as threads + pswitch DERIVE LINE context switches + inv_swtch DERIVE LINE involuntary context switches + cpumigrate DERIVE LINE thread migrations + xcalls DERIVE LINE inter-processor cross-calls + mutex_adenters DERIVE LINE spins on mutexes + rw_rdfails DERIVE LINE spins on r/w locks + rw_wrfails DERIVE LINE dummy + syscall DERIVE LINE system calls + trap DERIVE LINE traps +" +# They can be shown by vmstat -s or mpstat + +# Functions + +autoconf() { + if [ -x "$( which kstat )" ]; then + echo yes + else + echo "no (failed to find executable 'kstat')" + fi +} + +config() { + local label_max_length=45 + + # print global attributes + sed -e 's/^ *//' -e '/^$/d' <<< "${global_attr}" + + # print data source attributes + # split line into field,type,draw,label + local fields field type draw label + fields= + while read -r field type draw label + do + [ -z "$field" ] && continue + fields="${fields} ${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 + done <<< "${data_attr}" + + echo graph_order "$fields" +} + +getvalue() { + local field type draw label + while read -r field type draw label + do + [ -z "$field" ] && continue + + # kstat output example: + # $ kstat -p cpu::sys:intr + # cpu:0:sys:intr 5728473528 + # cpu:1:sys:intr 1060016014 + # cpu:2:sys:intr 1297441213 + # ... + value=$( kstat -p "cpu::sys:${field}" | awk '{ sum += $2 } END { print sum }' ) + + echo "${field}.value ${value}" + done <<< "${data_attr}" +} + +# Main +case ${1:-} in +autoconf) + autoconf + ;; +config) + config + [ "${MUNIN_CAP_DIRTYCONFIG:-}" = "1" ] && getvalue + ;; +*) + getvalue + ;; +esac + +exit 0