root / plugins / solaris / io_disk @ 25901320
Historique | Voir | Annoter | Télécharger (6,88 ko)
| 1 | 25901320 | K.Cima | #!/bin/bash |
|---|---|---|---|
| 2 | |||
| 3 | : << =cut |
||
| 4 | |||
| 5 | =head1 NAME |
||
| 6 | |||
| 7 | io_disk - Multigraph plugin to monitor disks for Solaris. |
||
| 8 | |||
| 9 | These functions are implemented: |
||
| 10 | ops : similar to iostat r/s, w/s |
||
| 11 | bytes : similar to iostat kr/s, kw/s |
||
| 12 | busy : similar to iostat %b, %w |
||
| 13 | queue : similar to iostat actv, wait |
||
| 14 | latency : similar to iostat asvc_t, wsvc_t |
||
| 15 | |||
| 16 | Any device found in /usr/bin/kstat can be monitored. |
||
| 17 | |||
| 18 | Tested with Solaris 10 and 11, and it should work with Solaris 8, 9. |
||
| 19 | |||
| 20 | =head1 CONFIGURATION |
||
| 21 | |||
| 22 | Make symlink: |
||
| 23 | cd /path/to/munin/etc/plugins |
||
| 24 | ln -s /path/to/munin/lib/plugins/io_disk . |
||
| 25 | |||
| 26 | The RRD files generated by io_busy_, io_ops_, io_bytes_ can be taken over |
||
| 27 | by this plugin. |
||
| 28 | Thus, please remove symlinks of those plugins before using this plugin. |
||
| 29 | |||
| 30 | By default, this plugin monitors disk devices. And also it can monitor |
||
| 31 | NFS and Tape devices as much as io_* plugins with setting environments. |
||
| 32 | |||
| 33 | =head1 ENVIRONMENT VARIABLES |
||
| 34 | |||
| 35 | env.class - kstat class. See man kstat -c option. |
||
| 36 | example: env.class /disk|nfs|tape/ |
||
| 37 | default: disk |
||
| 38 | |||
| 39 | env.module - Module name. Only used in internal graph name. If you would not |
||
| 40 | to like to take over RRDs generated by io_*_sd plugins, please change it |
||
| 41 | to another name. |
||
| 42 | |||
| 43 | example: env.module something |
||
| 44 | default: sd |
||
| 45 | |||
| 46 | env.module_regex - kstat module. See man kstat -m option. |
||
| 47 | example: env.module_regex /^(s?sd|vdc|zvblk|dad|md|nfs|tape)$/ |
||
| 48 | default: /^(s?sd|vdc|zvblk|dad|md)$/ |
||
| 49 | |||
| 50 | env.title_type - Device type shown in graph title. |
||
| 51 | example: env.title_type Disk Device, NFS, Tape |
||
| 52 | default: Disk Device |
||
| 53 | |||
| 54 | env.exclude - Device instance name(s) to exclude seperated by white-space. |
||
| 55 | example: env.exclude sd0 ssd1 |
||
| 56 | default: none |
||
| 57 | |||
| 58 | env.graph_width - Graph width in pixel |
||
| 59 | example: env.graph_width 450 |
||
| 60 | default: none (usually 400) |
||
| 61 | |||
| 62 | =head1 AUTHOR |
||
| 63 | |||
| 64 | Unknown Author |
||
| 65 | Improved by K.Cima https://github.com/shakemid |
||
| 66 | |||
| 67 | =head1 LICENSE |
||
| 68 | |||
| 69 | GPLv2 |
||
| 70 | |||
| 71 | =head1 MAGIC MARKERS |
||
| 72 | |||
| 73 | #%# family=auto |
||
| 74 | #%# capabilities=autoconf |
||
| 75 | |||
| 76 | =cut |
||
| 77 | |||
| 78 | # Include plugin.sh |
||
| 79 | . "${MUNIN_LIBDIR:-}/plugins/plugin.sh"
|
||
| 80 | is_multigraph "$@" |
||
| 81 | |||
| 82 | # Shell options |
||
| 83 | set -o nounset |
||
| 84 | set -o pipefail |
||
| 85 | |||
| 86 | # Set environment variables |
||
| 87 | plugin_name=io |
||
| 88 | functions='ops bytes busy queue latency' |
||
| 89 | : "${class:=disk}"
|
||
| 90 | : "${module:=sd}"
|
||
| 91 | : "${module_regex:=/^(s?sd|vdc|zvblk|dad|md)\$/}"
|
||
| 92 | : "${title_type:=Disk Device}"
|
||
| 93 | : "${exclude:=}"
|
||
| 94 | : "${graph_width:=}"
|
||
| 95 | |||
| 96 | # Create map of instance name (e.g. sd0) and logical device name (e.g. c0t0d0) |
||
| 97 | # Example: |
||
| 98 | # name_sd1=c0t0d0 |
||
| 99 | # name_ssd2=c0tAB_1234d0 (shorten long target) |
||
| 100 | # ... |
||
| 101 | declare $( paste -d= \ |
||
| 102 | <( iostat -x | awk '{print $1}' | sed -e '1,2d' -e 's/^/name_/' ) \
|
||
| 103 | <( iostat -xn | awk '{print $NF}' | sed -e '1,2d' -e 's/^\(c[0-9]*\)\(t.\{2\}\).*\(.\{4\}\)\(d[0-9]*\)$/\1\2_\3\4/' ) \
|
||
| 104 | ) |
||
| 105 | |||
| 106 | # Functions |
||
| 107 | |||
| 108 | preconfig() {
|
||
| 109 | local func |
||
| 110 | func=$1 |
||
| 111 | |||
| 112 | case "$func" in |
||
| 113 | ops) |
||
| 114 | conf_title='I/O Operations' |
||
| 115 | conf_in=reads |
||
| 116 | conf_out=writes |
||
| 117 | conf_cdef= |
||
| 118 | conf_gargs='--base 1000' |
||
| 119 | conf_vlabel='Ops per second write (-) / read (+)' |
||
| 120 | ;; |
||
| 121 | bytes) |
||
| 122 | conf_title='I/O Throughput' |
||
| 123 | conf_in=nread |
||
| 124 | conf_out=nwritten |
||
| 125 | conf_cdef= |
||
| 126 | conf_gargs='--base 1024' |
||
| 127 | conf_vlabel='Bytes per second write (-) / read (+)' |
||
| 128 | ;; |
||
| 129 | busy) |
||
| 130 | conf_title='Busy & Wait' |
||
| 131 | conf_in=rtime |
||
| 132 | conf_out=wtime |
||
| 133 | conf_cdef=',100,*' |
||
| 134 | conf_gargs='--base 1000 --lower-limit 0 --upper-limit 100' |
||
| 135 | conf_vlabel='% wait (-) / busy (+)' |
||
| 136 | ;; |
||
| 137 | queue) |
||
| 138 | conf_title='Queue Length' |
||
| 139 | conf_in=rlentime |
||
| 140 | conf_out=wlentime |
||
| 141 | conf_cdef= |
||
| 142 | conf_gargs='--base 1000' |
||
| 143 | conf_vlabel='Queue length wait (-) / actv (+)' |
||
| 144 | ;; |
||
| 145 | latency) |
||
| 146 | conf_title='Latency' |
||
| 147 | conf_in=rlentime |
||
| 148 | conf_out=wlentime |
||
| 149 | conf_cdef= |
||
| 150 | conf_gargs='--base 1000' |
||
| 151 | conf_vlabel='Seconds wsvc_t (-) / asvc_t (+)' |
||
| 152 | ;; |
||
| 153 | *) |
||
| 154 | echo "Unknown function: $func" |
||
| 155 | exit 1 |
||
| 156 | ;; |
||
| 157 | esac |
||
| 158 | } |
||
| 159 | |||
| 160 | is_excluded() {
|
||
| 161 | local dev i |
||
| 162 | dev=$1 |
||
| 163 | |||
| 164 | for i in ${exclude}
|
||
| 165 | do |
||
| 166 | if [ "$dev" = "$i" ]; then |
||
| 167 | return 0 |
||
| 168 | fi |
||
| 169 | done |
||
| 170 | |||
| 171 | return 1 |
||
| 172 | } |
||
| 173 | |||
| 174 | do_config() {
|
||
| 175 | local func dev ref devname stat |
||
| 176 | |||
| 177 | func=$1 |
||
| 178 | preconfig "$func" |
||
| 179 | |||
| 180 | echo "multigraph ${plugin_name}_${func}_${module}"
|
||
| 181 | |||
| 182 | echo "graph_title $title_type $conf_title" |
||
| 183 | echo 'graph_category disk' |
||
| 184 | echo "graph_args $conf_gargs" |
||
| 185 | echo "graph_vlabel $conf_vlabel" |
||
| 186 | if [ -n "$graph_width" ]; then |
||
| 187 | echo "graph_width $graph_width" |
||
| 188 | fi |
||
| 189 | |||
| 190 | kstat -p -c "$class" -m "$module_regex" -s "/^${conf_in}\$/" | sed 's/:/ /g' | awk '{ print $3 }' | \
|
||
| 191 | while read -r dev |
||
| 192 | do |
||
| 193 | if is_excluded "$dev" ; then |
||
| 194 | continue |
||
| 195 | fi |
||
| 196 | |||
| 197 | # replace instance name to logical device name if exists |
||
| 198 | ref="name_$dev" |
||
| 199 | devname=${!ref:-}
|
||
| 200 | |||
| 201 | # reads and writes are necessary to calculate latency |
||
| 202 | if [ "$func" = 'latency' ]; then |
||
| 203 | for stat in reads writes |
||
| 204 | do |
||
| 205 | echo "${dev}_$stat.label dummy"
|
||
| 206 | echo "${dev}_$stat.graph no"
|
||
| 207 | echo "${dev}_$stat.type DERIVE"
|
||
| 208 | echo "${dev}_$stat.min 0"
|
||
| 209 | done |
||
| 210 | # rlentime / ( reads + writes ) |
||
| 211 | conf_cdef=,${dev}_reads,${dev}_writes,+,/
|
||
| 212 | fi |
||
| 213 | |||
| 214 | echo "${dev}_${conf_out}.label dummy"
|
||
| 215 | echo "${dev}_${conf_out}.graph no"
|
||
| 216 | echo "${dev}_${conf_out}.type DERIVE"
|
||
| 217 | echo "${dev}_${conf_out}.min 0"
|
||
| 218 | |||
| 219 | echo "${dev}_${conf_in}.label ${devname:-${dev}}"
|
||
| 220 | echo "${dev}_${conf_in}.negative ${dev}_${conf_out}"
|
||
| 221 | echo "${dev}_${conf_in}.type DERIVE"
|
||
| 222 | echo "${dev}_${conf_in}.min 0"
|
||
| 223 | |||
| 224 | if [ -n "$conf_cdef" ]; then |
||
| 225 | echo "${dev}_${conf_out}.cdef ${dev}_${conf_out}${conf_cdef}"
|
||
| 226 | echo "${dev}_${conf_in}.cdef ${dev}_${conf_in}${conf_cdef}"
|
||
| 227 | fi |
||
| 228 | done |
||
| 229 | |||
| 230 | echo |
||
| 231 | } |
||
| 232 | |||
| 233 | do_getvalue() {
|
||
| 234 | local func stat_regex dev stat value |
||
| 235 | |||
| 236 | func=$1 |
||
| 237 | preconfig "$func" |
||
| 238 | |||
| 239 | if [ "$func" = 'latency' ]; then |
||
| 240 | stat_regex="/^($conf_in|$conf_out|reads|writes)\$/" |
||
| 241 | else |
||
| 242 | stat_regex="/^($conf_in|$conf_out)\$/" |
||
| 243 | fi |
||
| 244 | |||
| 245 | echo "multigraph ${plugin_name}_${func}_${module}"
|
||
| 246 | |||
| 247 | kstat -p -c "$class" -m "$module_regex" -s "$stat_regex" | sed 's/:/ /g' | awk '{ print $3,$4,$5 }' | \
|
||
| 248 | while read -r dev stat value |
||
| 249 | do |
||
| 250 | if is_excluded "$dev" ; then |
||
| 251 | continue |
||
| 252 | fi |
||
| 253 | |||
| 254 | echo "${dev}_${stat}.value ${value%.*}"
|
||
| 255 | done |
||
| 256 | |||
| 257 | echo |
||
| 258 | } |
||
| 259 | |||
| 260 | autoconf() {
|
||
| 261 | if [ -x /usr/bin/kstat ]; then |
||
| 262 | echo yes |
||
| 263 | exit 0 |
||
| 264 | else |
||
| 265 | echo "no (/usr/bin/kstat not found)" |
||
| 266 | exit 0 |
||
| 267 | fi |
||
| 268 | } |
||
| 269 | |||
| 270 | config() {
|
||
| 271 | local func |
||
| 272 | |||
| 273 | for func in $functions |
||
| 274 | do |
||
| 275 | do_config "$func" |
||
| 276 | done |
||
| 277 | } |
||
| 278 | |||
| 279 | getvalue() {
|
||
| 280 | local func |
||
| 281 | |||
| 282 | for func in $functions |
||
| 283 | do |
||
| 284 | do_getvalue "$func" |
||
| 285 | done |
||
| 286 | } |
||
| 287 | |||
| 288 | # main |
||
| 289 | case ${1:-} in
|
||
| 290 | autoconf) |
||
| 291 | autoconf |
||
| 292 | ;; |
||
| 293 | config) |
||
| 294 | config |
||
| 295 | ;; |
||
| 296 | *) |
||
| 297 | getvalue |
||
| 298 | ;; |
||
| 299 | esac |
||
| 300 | |||
| 301 | exit 0 |
