Projet

Général

Profil

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

root / plugins / solaris / io_disk @ 544b2cfb

Historique | Voir | Annoter | Télécharger (7,73 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

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

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

    
21
=head1 CONFIGURATION
22

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

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

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

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

    
37
=head1 ENVIRONMENT VARIABLES
38

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

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

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

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

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

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

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

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

    
70
=head1 AUTHOR
71

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

    
75
=head1 LICENSE
76

    
77
  GPLv2
78

    
79
=head1 MAGIC MARKERS
80

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

    
84
=cut
85

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

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

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

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

    
114
# Functions
115

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

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

    
168
is_excluded() {
169
    local dev i
170
    dev=$1
171

    
172
    for i in ${exclude}
173
    do
174
        if [ "$dev" = "$i" ]; then
175
            return 0
176
        fi
177
    done
178

    
179
    return 1
180
}
181

    
182
do_config() {
183
    local func dev ref devname stat
184

    
185
    func=$1
186
    preconfig "$func"
187

    
188
    echo "multigraph ${plugin_name}_${func}_${module}"
189

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

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

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

    
208
        # reads and writes are necessary to calculate latency
209
        if [ "$func" = 'latency' ]; then
210
            for stat in reads writes
211
            do
212
                echo "${dev}_$stat.label dummy" 
213
                echo "${dev}_$stat.graph no"
214
                echo "${dev}_$stat.type DERIVE"
215
                echo "${dev}_$stat.min 0"
216
            done
217
            # rlentime / ( reads + writes )
218
            conf_cdef=,${dev}_reads,${dev}_writes,+,/
219
        fi
220

    
221
        echo "${dev}_${conf_out}.label dummy" 
222
        echo "${dev}_${conf_out}.graph no"
223
        echo "${dev}_${conf_out}.type DERIVE"
224
        echo "${dev}_${conf_out}.min 0"
225

    
226
        echo "${dev}_${conf_in}.label ${devname:-${dev}}"
227
        echo "${dev}_${conf_in}.negative ${dev}_${conf_out}"
228
        echo "${dev}_${conf_in}.type DERIVE"
229
        echo "${dev}_${conf_in}.min 0"
230

    
231
        if [ -n "$conf_cdef" ]; then
232
            echo "${dev}_${conf_out}.cdef ${dev}_${conf_out}${conf_cdef}"
233
            echo "${dev}_${conf_in}.cdef ${dev}_${conf_in}${conf_cdef}"
234
        fi
235
    done
236

    
237
    echo
238
}
239

    
240
do_getvalue() {
241
    local func stat_regex dev stat value
242

    
243
    func=$1
244
    preconfig "$func"
245

    
246
    if [ "$func" = 'latency' ]; then
247
        stat_regex="/^($conf_in|$conf_out|reads|writes)\$/"
248
    else
249
        stat_regex="/^($conf_in|$conf_out)\$/"
250
    fi
251

    
252
    echo "multigraph ${plugin_name}_${func}_${module}"
253

    
254
    # Get device instance names, stat names and values by kstat
255

    
256
    # kstat output example:
257
    #   $ kstat -p -c disk -m '/^sd$/' -s '/^reads$/'
258
    #   sd:0:sd0:reads  51432610
259
    #   sd:1:sd1:reads  52671435
260
    #   ...
261

    
262
    kstat -p -c "$class" -m "$module_regex" -s "$stat_regex" | sed 's/:/ /g' | awk '{ print $3,$4,$5 }' | \
263
    while read -r dev stat value
264
    do
265
        is_excluded "$dev" && continue
266

    
267
        echo "${dev}_${stat}.value ${value%.*}"
268
    done
269

    
270
    echo
271
}
272

    
273
autoconf() {
274
    if [ -x /usr/bin/kstat ]; then
275
        echo yes
276
        exit 0
277
    else
278
        echo "no (/usr/bin/kstat not found)"
279
        exit 0
280
    fi
281
}
282

    
283
config() {
284
    local func
285

    
286
    for func in $functions
287
    do
288
        do_config "$func"
289
    done
290
}
291

    
292
getvalue() {
293
    local func
294

    
295
    for func in $functions
296
    do
297
        do_getvalue "$func"
298
    done
299
}
300

    
301
# Main
302
case ${1:-} in
303
autoconf)
304
    autoconf
305
    ;;
306
config)
307
    config
308
    ;;
309
*)
310
    getvalue
311
    ;;
312
esac
313

    
314
exit 0