NET-SNMP Linux disk IO collector, mark II

NET-SNMP Linux disk IO collector, mark II

This is an improvement on a previous post on adding UCD-DISKIO-MIB support to older versions of net-snmp; this one actually works on 2.6 kernels (and thanks to Pete loses about a million forks and pipes).

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/bin/sh

# by Jamie Wilkinson <jamie@anchor.net.au>
# this code is in the public domain
# based on passtest from the net-snmp distribution examples
# WARNING there is shitloads of IO required to get this information :)

debug_flag=0

debug () {
    if [ $debug_flag -eq 1 ]; then
        echo $* >> /tmp/snmp-diskio-collector-debug.log
    fi
}

PLACE=".1.3.6.1.4.1.2021.13.15"
REQ="$2"

debug
debug "new run" 
debug "args $*" 
if [ "$1" = "-s" ]; then
  exit 0
fi

# the 'tail' of the oid, everything after $PLACE
oidtail=`echo $REQ | sed "s/^$PLACE//"`
debug "oidtail=$oidtail" 

# number of devices we can export
devcount=`wc -l /proc/diskstats | cut -f1 -d' '`
debug "devcount=$devcount" 

item=`echo $oidtail | cut -f4 -d.`
index=`echo $oidtail | cut -f5 -d.`
debug "oidtail=$oidtail, item=$item, index=$index" 

if [ "$1" = "-n" ]; then
    if [ -z "$item" ]; then
        item=1
        index=1
    elif [ -z "$index" ]; then
        index=1
    else
        index=`expr $index + 1`
        if [ "$index" -gt "$devcount" ]; then
            index=1
            item=`expr $item + 1`
            if [ "$item" -gt 6 ]; then
                # break out of the loop
                exit 0;
            fi
        fi
    fi
    RET=$PLACE.1.1.$item.$index
else
    case "$REQ" in
        $PLACE) exit 0;;
        *) RET=$REQ ;;
    esac
fi

debug "after -n, item=$item, index=$index" 
debug "RET is now $RET" 

echo "$RET"

debug "oidtail=$oidtail, item=$item, index=$index" 

# awk uses this variable in the environment below
export index
# see linux kernel Documentation/iostats.txt for format
if [ -n "$index" ]; then
    case "$item" in
        1)
            # diskIOIndex
            debug "result: diskIOIndex $index" 
            echo "integer"
            echo $index
            exit 0
            ;;
        2)
            # diskIODevice
            debug "result: diskIODevice $index" 
            echo "string"
            awk 'FNR == ENVIRON["index"] { print $3 }' /proc/diskstats
            exit 0
            ;;
        3)
            # diskIONRead
            debug "result: diskIONRead $index" 
            echo "counter"
            awk 'FNR == ENVIRON["index"] { print $6 }' /proc/diskstats
            exit 0
            ;;
        4)
            # diskIONWritten
            debug "result: diskIONWritten $index" 
            echo "counter"
            awk 'FNR == ENVIRON["index"] { print $10 }' /proc/diskstats
            exit 0
            ;;
        5)
            # diskIOReads
            debug "result: diskIOReads $index" 
            echo "counter"
            awk 'FNR == ENVIRON["index"] { print $4 }' /proc/diskstats
            exit 0
            ;;
        6)
            # diskIOWrites
            debug "result: diskIOWrites $index" 
            echo "counter"
            awk 'FNR == ENVIRON["index"] { print $8 }' /proc/diskstats
            exit 0
            ;;
        *) exit 0; #echo "string"; echo "debug... $RET $REQ"; exit 0 ;;
    esac
else
    exit 0
fi