Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / solaris / io_disk @ c57fd566

Historique | Voir | Annoter | Télécharger (8,55 ko)

1
#!/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 (%w usually indicates 0 in Sol10,11)
13
     queue   : similar to iostat actv, wait
14
     latency : similar to iostat asvc_t, wsvc_t
15
     size    : average io size
16

    
17
  This plugin is improved from Solaris io_busy_, io_ops_, io_bytes_ plugins.
18
  Any device found in /usr/bin/kstat can be monitored.
19

    
20
  Tested with Solaris 10 and 11, and it should work with Solaris 8, 9.
21

    
22
=head1 CONFIGURATION
23

    
24
  Make symlink:
25
    cd /path/to/munin/etc/plugins
26
    ln -s /path/to/munin/lib/plugins/io_disk .
27

    
28
  The RRD files generated by io_busy_, io_ops_, io_bytes_ can be taken over 
29
  by this plugin.
30
  Thus, please remove symlinks of those plugins before using this plugin.
31

    
32
  By default, this plugin monitors disk devices. And also it can monitor 
33
  NFS and Tape devices as much as io_* plugins with setting environments.
34

    
35
  Note that instance names of nfs (e.g. nfs1) can be changed after reboot or
36
  remount, this plugin may not monitor nfs properly. (same as original ones)
37

    
38
=head1 ENVIRONMENT VARIABLES
39

    
40
  env.class - kstat class. See man kstat -c option.
41
    example:  env.class  /disk|nfs|tape/
42
    default:  disk
43

    
44
  env.module - Module name. Only used in internal graph name.  
45
    example:  env.module  something
46
    default:  sd
47

    
48
    If you would not like to take over RRDs generated by io_*_sd plugins,
49
    please change it to another name.
50

    
51
    And also, if you would like to take over RRDs of nfs, tape devices,
52
    please set it 'nfs' or 'tape' (and set env.class, env.module_regex).
53
    It may be good to link like ln -s /path/to/io_disk io_nfs if necessary.
54

    
55
  env.module_regex - kstat module. See man kstat -m option.
56
    example:  env.module_regex  /^(s?sd|vdc|zvblk|dad|md|nfs|st)$/
57
    default:  /^(s?sd|vdc|zvblk|dad|md)$/
58

    
59
  env.title_type - Device type shown in graph title.
60
    example:  env.title_type  Disk Device, NFS, Tape
61
    default:  Disk Device
62

    
63
  env.exclude - Device instance name(s) to exclude seperated by white-space.
64
    example:  env.exclude  sd0 ssd1
65
    default:  none
66

    
67
  env.graph_width - Graph width in pixel
68
    example:  env.graph_width  450
69
    default:  none (usually 400)
70

    
71
=head1 AUTHOR
72

    
73
  Unknown Author
74
  Improved by K.Cima https://github.com/shakemid
75

    
76
=head1 LICENSE
77

    
78
  GPLv2
79

    
80
=head1 MAGIC MARKERS
81

    
82
  #%# family=auto
83
  #%# capabilities=autoconf
84

    
85
=cut
86

    
87
# Include plugin.sh
88
. "${MUNIN_LIBDIR:-}/plugins/plugin.sh"
89
is_multigraph "$@"
90

    
91
# Shell options
92
set -o nounset  # Like perl use strict;
93

    
94
# Set environment variables
95
plugin_name=io
96
functions='ops bytes busy queue latency size'
97
: "${class:=disk}"
98
: "${module:=sd}"
99
: "${module_regex:=/^(s?sd|vdc|zvblk|dad|md)\$/}"
100
: "${title_type:=Disk Device}"
101
: "${exclude:=}"
102
: "${graph_width:=}"
103

    
104
# Create map of instance name (e.g. sd0) and logical device name (e.g. c0t0d0)
105
#   Example: 
106
#     name_sd1=c0t0d0
107
#     name_ssd2=c0tAB_1234d0  (shorten long target)
108
#     ...
109
instance_names=$( iostat -x | sed -e '1,2d' | awk '{print $1}' \
110
    | sed -e 's/^/name_/' )
111
logical_device_names=$( iostat -xn | sed -e '1,2d' | awk '{print $NF}' \
112
    | sed -e 's/^\(c[0-9]*\)\(t.\{2\}\).*\(.\{4\}\)\(d[0-9]*\)$/\1\2_\3\4/' )
113
declare $( paste -d= <( echo "$instance_names" ) <( echo "$logical_device_names" ) )
114

    
115
# Functions
116

    
117
preconfig() {
118
    local func
119
    func=$1
120

    
121
    case "$func" in
122
    ops)
123
        conf_title='I/O Operations'
124
        conf_gargs='--base 1000'
125
        conf_vlabel='Ops per second write (-) / read (+)'
126
        conf_in=reads
127
        conf_out=writes
128
        ;;
129
    bytes)
130
        conf_title='I/O Throughput'
131
        conf_gargs='--base 1024'
132
        conf_vlabel='Bytes per second write (-) / read (+)'
133
        conf_in=nread
134
        conf_out=nwritten
135
        ;;
136
    busy)
137
        conf_title='Busy & Wait'
138
        conf_gargs='--base 1000 --lower-limit 0 --upper-limit 100'
139
        conf_vlabel='% wait (-) / busy (+)'
140
        conf_in=rtime
141
        conf_out=wtime
142
        ;;
143
    queue)
144
        conf_title='Queue Length'
145
        conf_gargs='--base 1000'
146
        conf_vlabel='Queue length wait (-) / actv (+)'
147
        conf_in=rlentime
148
        conf_out=wlentime
149
        ;;
150
    latency)
151
        conf_title='Latency'
152
        conf_gargs='--base 1000'
153
        conf_vlabel='Seconds wsvc_t (-) / asvc_t (+)'
154
        conf_in=rlentime
155
        conf_out=wlentime
156
        ;;
157
    size)
158
        conf_title='I/O Size'
159
        conf_gargs='--base 1024'
160
        conf_vlabel='Average size write (-) / read (+)'
161
        conf_in=nread
162
        conf_out=nwritten
163
        ;;
164
    *)
165
        echo "Unknown function: $func"
166
        exit 1
167
        ;;
168
    esac
169
}
170

    
171
is_excluded() {
172
    local arg i
173
    arg=$1
174

    
175
    for i in ${exclude}
176
    do
177
        if [ "$arg" = "$i" ]; then
178
            return 0
179
        fi
180
    done
181

    
182
    return 1
183
}
184

    
185
do_config() {
186
    local func dev ref devname stat
187

    
188
    func=$1
189
    preconfig "$func"
190
    echo "multigraph ${plugin_name}_${func}_${module}"
191

    
192
    echo "graph_title $title_type $conf_title"
193
    echo 'graph_category disk'
194
    echo "graph_args $conf_gargs"
195
    echo "graph_vlabel $conf_vlabel"
196
    if [ -n "$graph_width" ]; then
197
        echo "graph_width $graph_width"
198
    fi
199

    
200
    # Get device instance names by kstat
201
    kstat -p -c "$class" -m "$module_regex" -s "/^${conf_in}\$/" \
202
    | sed 's/:/ /g' | awk '{ print $3 }' \
203
    | while read -r dev
204
    do
205
        is_excluded "$dev" && continue
206

    
207
        # Replace instance name to logical device name if exists
208
        ref="name_$dev"
209
        devname=${!ref:-}  # ${!varname} means indirect evaluation (similar to eval)
210

    
211
        # reads and writes are necessary to calculate latency, size
212
        case "$func" in
213
        latency|size)
214
            for stat in reads writes
215
            do
216
                echo "${dev}_${stat}.label dummy" 
217
                echo "${dev}_${stat}.graph no"
218
                echo "${dev}_${stat}.type DERIVE"
219
                echo "${dev}_${stat}.min 0"
220
            done
221
            ;;
222
        esac
223

    
224
        # Set CDEF
225
        case "$func" in
226
        busy)
227
            conf_in_cdef="${dev}_${conf_in},100,*"
228
            conf_out_cdef="${dev}_${conf_out},100,*"
229
            ;;
230
        latency)
231
            # rlentime / ( reads + writes )
232
            conf_in_cdef="${dev}_${conf_in},${dev}_reads,${dev}_writes,+,/"
233
            conf_out_cdef="${dev}_${conf_out},${dev}_reads,${dev}_writes,+,/"
234
            ;;
235
        size)
236
            conf_in_cdef="${dev}_${conf_in},${dev}_reads,/"
237
            conf_out_cdef="${dev}_${conf_out},${dev}_writes,/"
238
            ;;
239
        *)
240
            conf_in_cdef=
241
            conf_out_cdef=
242
            ;;
243
        esac
244

    
245
        # Print data attributes
246
        echo "${dev}_${conf_out}.label dummy" 
247
        echo "${dev}_${conf_out}.graph no"
248
        echo "${dev}_${conf_out}.type DERIVE"
249
        echo "${dev}_${conf_out}.min 0"
250
        if [ -n "$conf_out_cdef" ]; then
251
            echo "${dev}_${conf_out}.cdef ${conf_out_cdef}"
252
        fi
253

    
254
        echo "${dev}_${conf_in}.label ${devname:-${dev}}"
255
        echo "${dev}_${conf_in}.negative ${dev}_${conf_out}"
256
        echo "${dev}_${conf_in}.type DERIVE"
257
        echo "${dev}_${conf_in}.min 0"
258
        if [ -n "$conf_in_cdef" ]; then
259
            echo "${dev}_${conf_in}.cdef ${conf_in_cdef}"
260
        fi
261
    done
262

    
263
    echo
264
}
265

    
266
do_fetch() {
267
    local func stat_regex dev stat value
268

    
269
    func=$1
270
    preconfig "$func"
271
    echo "multigraph ${plugin_name}_${func}_${module}"
272

    
273
    case "$func" in
274
    latency|size)
275
        stat_regex="/^($conf_in|$conf_out|reads|writes)\$/"
276
        ;;
277
    *)
278
        stat_regex="/^($conf_in|$conf_out)\$/"
279
        ;;
280
    esac
281

    
282
    # Get device instance names, stat names and values by kstat
283

    
284
    # kstat output example:
285
    #   $ kstat -p -c disk -m '/^sd$/' -s '/^reads$/'
286
    #   sd:0:sd0:reads  51432610
287
    #   sd:1:sd1:reads  52671435
288
    #   ...
289

    
290
    kstat -p -c "$class" -m "$module_regex" -s "$stat_regex" \
291
    | sed 's/:/ /g' | awk '{ print $3,$4,$5 }' \
292
    | while read -r dev stat value
293
    do
294
        is_excluded "$dev" && continue
295

    
296
        echo "${dev}_${stat}.value ${value%.*}"
297
    done
298

    
299
    echo
300
}
301

    
302
autoconf() {
303
    if [ -x /usr/bin/kstat ]; then
304
        echo yes
305
        exit 0
306
    else
307
        echo "no (/usr/bin/kstat not found)"
308
        exit 0
309
    fi
310
}
311

    
312
config() {
313
    local func
314

    
315
    for func in $functions
316
    do
317
        do_config "$func"
318
    done
319
}
320

    
321
fetch() {
322
    local func
323

    
324
    for func in $functions
325
    do
326
        do_fetch "$func"
327
    done
328
}
329

    
330
# Main
331
case ${1:-} in
332
autoconf)
333
    autoconf
334
    ;;
335
config)
336
    config
337
    [ "${MUNIN_CAP_DIRTYCONFIG:-}" = "1" ] && fetch
338
    ;;
339
*)
340
    fetch
341
    ;;
342
esac
343

    
344
exit 0