]>
Commit | Line | Data |
---|---|---|
3decc5d1 JR |
1 | #!/bin/bash |
2 | # -*- sh -*- | |
3 | ||
4 | set -e | |
5 | ||
6 | : << =cut | |
7 | ||
8 | =head1 NAME | |
9 | ||
10 | if_ - Wildcard-plugin to monitor traffic and errors on network | |
11 | interfaces. | |
12 | ||
13 | =head1 CONFIGURATION | |
14 | ||
15 | This plugin does not normally require configuration. | |
16 | ||
17 | The plugin may need to run as root to determine the maximum speed of | |
18 | the network interface. This is configured like this: | |
19 | ||
20 | [if_*] | |
21 | user root | |
22 | ||
23 | If the interface speed cannot be determined automatically by this | |
24 | plugin, you may manually configure the speed using the "speed" | |
25 | environment variable, in megabits per second, like this: | |
26 | ||
27 | [if_*] | |
28 | env.speed 1000 | |
29 | ||
30 | To set warning and critical levels do like this: | |
31 | ||
32 | [if_*] | |
33 | env.warning 10000000 | |
34 | ||
35 | or | |
36 | ||
37 | [if_*] | |
38 | env.if_0_warning 10000000 | |
39 | ||
40 | This is a wildcard plugin. To monitor an interface, link | |
41 | if_<interface> to this file. For example, | |
42 | ||
43 | ln -s /usr/share/munin/plugins/if_ \ | |
44 | /etc/munin/plugins/if_eth0 | |
45 | ||
46 | will monitor eth0. | |
47 | ||
48 | Most devices found in /proc/net/dev can be monitored. Examples include | |
49 | ipsec*, eth*, irda*, and lo. Please note that aliases cannot be | |
50 | monitored with this plugin. | |
51 | ||
52 | =head1 AUTHOR | |
53 | ||
54 | Original author unknown | |
55 | ||
56 | Copyright (C) 2011 Diego Elio Pettenò <flameeyes@flameeyes.eu> | |
57 | ||
58 | =head1 LICENSE | |
59 | ||
60 | GPLv2 | |
61 | ||
62 | =head1 MAGIC MARKERS | |
63 | ||
64 | #%# family=auto | |
65 | #%# capabilities=autoconf suggest | |
66 | ||
67 | =cut | |
68 | ||
69 | . "$MUNIN_LIBDIR/plugins/plugin.sh" | |
70 | ||
71 | INTERFACE=${0##*if_} | |
72 | speed=${speed:-} | |
73 | ||
74 | # Who whould have thought it's so much work to determine the | |
75 | # maximum speed of a network interface. Buckle up! | |
76 | findspeed_mbps() { | |
77 | # Do not use interface name to guess technology. Many many | |
78 | # wifi drivers use "eth*" names. | |
79 | IWLIST=$(type -p iwlist) | |
80 | if [[ -x "$IWLIST" ]]; then | |
81 | SPEED=$("$IWLIST" "$INTERFACE" rate 2>&1 | | |
82 | awk 'BEGIN { RATE="U" } | |
83 | { if ($2 == "Mb/s") RATE=$1; } | |
84 | END { print RATE; }') | |
85 | ||
86 | if [[ "$SPEED" != "U" ]]; then | |
87 | echo "$SPEED" | |
88 | return | |
89 | fi | |
90 | fi | |
91 | ||
92 | # sysfs can report the speed if the driver supports it (but it | |
93 | # doesn't work as well for wireless cards, thus why we check for | |
94 | # iwlist first) | |
95 | if [[ -r "/sys/class/net/$INTERFACE/speed" ]]; then | |
96 | SPEED=$(cat "/sys/class/net/$INTERFACE/speed" 2>/dev/null) | |
97 | if [[ "$SPEED" -gt 0 ]]; then | |
98 | echo "$SPEED" | |
99 | return | |
100 | fi | |
101 | fi | |
102 | ||
103 | ETHTOOL=$(type -p ethtool) | |
104 | if [[ -x "$ETHTOOL" ]]; then | |
105 | SPEED=$("$ETHTOOL" "$INTERFACE" 2>&1 | | |
106 | awk '/Speed:/ { gsub(/[^0-9]*/,"",$2); print $2; }') | |
107 | ||
108 | if [[ $SPEED == [0-9]* ]]; then | |
109 | echo "$SPEED" | |
110 | return | |
111 | fi | |
112 | fi | |
113 | ||
114 | MIITOOL=$(type -p mii-tool) | |
115 | if [[ -x "$MIITOOL" ]]; then | |
116 | case $("$MIITOOL" "$INTERFACE" 2>&1) in | |
117 | *1000base*) echo 1000; return ;; | |
118 | *100base*) echo 100; return ;; | |
119 | *10base*) echo 10; return ;; | |
120 | esac | |
121 | fi | |
122 | ||
123 | echo U | |
124 | } | |
125 | ||
126 | findspeed() { | |
127 | if [[ "$speed" ]]; then | |
128 | SPEED=$speed | |
129 | else | |
130 | SPEED=$(findspeed_mbps) | |
131 | fi | |
132 | ||
133 | if [[ -z "$SPEED" ]] || [[ "$SPEED" == "U" ]]; then | |
134 | printf "up.info Traffic of the %s interface. Unable to determine interface speed." "$INTERFACE" | |
135 | if [[ $EUID -ne 0 ]]; then | |
136 | echo " Please run the plugin as root." | |
137 | else | |
138 | echo " Please install ethtool, wireless-tools, mii-tool or whatever is appropriate for the interface." | |
139 | fi | |
140 | ||
141 | return | |
142 | fi | |
143 | ||
144 | BPS=$(( SPEED * 1000 * 1000 )) | |
145 | ||
146 | cat <<EOF | |
147 | up.max $BPS | |
148 | up.info Traffic of the $INTERFACE interface. Maximum speed is $SPEED Mb/s. | |
149 | down.max $BPS | |
150 | EOF | |
151 | ||
152 | return | |
153 | } | |
154 | ||
155 | ||
156 | case $1 in | |
157 | autoconf) | |
158 | if [[ -r /proc/net/dev ]]; then | |
159 | echo yes | |
160 | exit 0 | |
161 | else | |
162 | echo "no (/proc/net/dev not found)" | |
163 | exit 0 | |
164 | fi | |
165 | ;; | |
166 | suggest) | |
167 | if [[ -r /proc/net/dev ]]; then | |
168 | sed -rne '/^[[:space:]]*(lo|gre[[:digit:]]|sit[[:digit:]]+|[a-z0-9]+\.[0-9]+):/d;s,^[[:space:]]*([^:]+):.*,\1,p' /proc/net/dev | |
169 | fi | |
170 | exit 0 | |
171 | ;; | |
172 | config) | |
173 | ||
174 | address="$(ip -j address show dev $INTERFACE | jq -r '.[0].addr_info[].local' | tr '\n' ' ')" | |
175 | echo "graph_order down up" | |
176 | echo "graph_title $INTERFACE (${address% }) traffic" | |
177 | echo 'graph_args --base 1000' | |
178 | # shellcheck disable=SC2016 | |
179 | echo 'graph_vlabel bits in (-) / out (+) per ${graph_period}' | |
180 | echo 'graph_category network' | |
181 | echo "graph_info This graph shows the traffic of the $INTERFACE network interface. Please note that the traffic is shown in bits per second, not bytes. IMPORTANT: On 32-bit systems the data source for this plugin uses 32-bit counters, which makes the plugin unreliable and unsuitable for most 100-Mb/s (or faster) interfaces, where traffic is expected to exceed 50 Mb/s over a 5 minute period. This means that this plugin is unsuitable for most 32-bit production environments. To avoid this problem, use the ip_ plugin instead. There should be no problems on 64-bit systems running 64-bit kernels." | |
182 | echo 'down.label received' | |
183 | echo 'down.type DERIVE' | |
184 | echo 'down.graph no' | |
185 | echo 'down.cdef down,8,*' | |
186 | echo 'down.min 0' | |
187 | echo 'up.label bps' | |
188 | echo 'up.type DERIVE' | |
189 | echo 'up.negative down' | |
190 | echo 'up.cdef up,8,*' | |
191 | echo 'up.min 0' | |
192 | print_warning down | |
193 | print_warning up | |
194 | print_critical down | |
195 | print_critical up | |
196 | ||
197 | findspeed | |
198 | ||
199 | exit 0 | |
200 | ;; | |
201 | esac | |
202 | ||
203 | # Escape dots in the interface name (eg. vlans) before using it as a regex | |
204 | if [[ -r /sys/class/net/$INTERFACE/statistics/rx_bytes ]]; then | |
205 | echo "down.value $(cat "/sys/class/net/$INTERFACE/statistics/rx_bytes")" | |
206 | echo "up.value $(cat "/sys/class/net/$INTERFACE/statistics/tx_bytes")" | |
207 | else | |
208 | awk -v interface="$INTERFACE" \ | |
209 | 'BEGIN { gsub(/\./, "\\.", interface) } | |
210 | $1 ~ "^" interface ":" { | |
211 | split($0, a, /: */); $0 = a[2]; | |
212 | print "down.value " $1 "\nup.value " $9}' \ | |
213 | /proc/net/dev | |
214 | fi |