]> jfr.im git - munin-plugins.git/blob - processes
support for a 2nd unbound plugin
[munin-plugins.git] / processes
1 #!/bin/sh
2 # -*- sh -*-
3
4 set -e
5
6 : << =cut
7
8 =head1 NAME
9
10 processes - Plugin to monitor processes and process states.
11
12 =head1 ABOUT
13
14 This plugin requires munin-server version 1.2.5 or 1.3.3 (or higher).
15
16 This plugin is backwards compatible with the old processes-plugins found on
17 SunOS, Linux and *BSD (i.e. the history is preserved).
18
19 All fields have colours associated with them which reflect the type of process
20 (sleeping/idle = blue, running = green, stopped/zombie/dead = red, etc.)
21
22 =head1 CONFIGURATION
23
24 No configuration for this plugin.
25
26 =head1 AUTHOR
27
28 Copyright (C) 2006 Lars Strand
29
30 =head1 LICENSE
31
32 GNU General Public License, version 2
33
34 =begin comment
35
36 This file is part of Munin.
37
38 This program is free software; you can redistribute it and/or modify it under
39 the terms of the GNU General Public License as published by the Free Software
40 Foundation; version 2 dated June, 1991.
41
42 This program is distributed in the hope that it will be useful, but WITHOUT ANY
43 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
44 PARTICULAR PURPOSE. See the GNU General Public License for more details.
45
46 You should have received a copy of the GNU General Public License along with
47 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
48 Street, Fifth Floor, Boston, MA 02110-1301 USA.
49
50 =end comment
51
52 =head1 MAGIC MARKERS
53
54 =begin comment
55
56 These magic markers are used by munin-node-configure when installing
57 munin-node.
58
59 =end comment
60
61 #%# family=auto
62 #%# capabilities=autoconf
63
64 =cut
65
66 # Search for program in $PATH unless predefined.
67 awk=${awk:-awk}
68 ps=${ps:-ps}
69
70 # Find operating system
71 OPERSYS=${OPERSYS:-$(uname | cut -f 1 -d _)}
72 [ -z "$OPERSYS" ] && echo >&2 "Failed to detect environment via uname" && exit 1
73
74 if [ "$1" = "autoconf" ]; then
75 case "$OPERSYS" in
76 Linux|SunOS|FreeBSD|OpenBSD|NetBSD|Darwin|CYGWIN)
77 if ! "$ps" >/dev/null 2>/dev/null; then
78 echo "no (ps=$ps failed)"
79 elif ! echo | "$awk" '{ print "Hei" }' >/dev/null 2>/dev/null; then
80 echo "no (awk=$awk failed)"
81 else
82 echo yes
83 fi
84 exit 0
85 ;;
86 *)
87 echo "no (unknown OS)"
88 exit 0
89 ;;
90 esac
91 fi
92
93 . "$MUNIN_LIBDIR/plugins/plugin.sh"
94
95 # Define colours
96 RUNNABLE='22ff22' # Green
97 SLEEPING='0022ff' # Blue
98 STOPPED='cc0000' # Darker red
99 DEBUGGED='ffff00' # Yellow
100 ZOMBIE='990000' # Darkest red
101 UNINTERRUPTIBLE='ffa500' # Orange
102 IDLE='4169e1' # Royal blue
103 PAGING='00aaaa' # Darker turquoise
104 INTERRUPT='ff00ff' # Fuchsia
105 LOCK='ff3333' # Lighter red
106 RUNNING='00ff7f' # Spring green
107 DEAD='ff0000' # Red
108 SUSPENDED='ff1493' # Deep pink
109 TOTAL='c0c0c0' # Silver
110
111 # Taken from ps(1)
112 # R - Linux, SunOS, FreeBSD, OpenBSD, NetBSD, OSX, HP-UX (runable)
113 # S - Linux, SunOS, FreeBSD*, OpenBSD*, NetBSD*, OSX*, HP-UX (sleeping)
114 # T - Linux, SunOS, FreeBSD, OpenBSD, NetBSD, OSX, HP-UX (stopped)
115 # Z - Linux, SunOS, FreeBSD, OpenBSD, NetBSD, OSX, HP-UX (zombie/terminated)
116 # D - Linux, FreeBSD, OpenBSD, NetBSD (uninterruptible)
117 # I - FreeBSD, OpenBSD, NetBSD, OSX, HP-UX (idle/intermediate)
118 # W - Linux*, FreeBSD*, HP-UX (paging/interrupt/waiting)
119 # L - FreeBSD (lock)
120 # O - SunOS (running)
121 # X - Linux, HP-UX* (dead)
122 # U - OSX, NetBSD* (uninterruptible/suspended)
123 # 0 - HP-UX (nonexistent)
124 # *) Differ meaning
125
126 if [ "$1" = "config" ]; then
127 echo "graph_title Processes"
128 echo "graph_info This graph shows the number of processes"
129 echo "graph_category processes"
130 echo "graph_args --base 1000 -l 0"
131 echo "graph_vlabel Number of processes"
132
133 # OS specific flags
134 if [ "$OPERSYS" = "Linux" ]; then
135 echo "graph_order sleeping idle stopped debugged zombie dead paging uninterruptible runnable processes"
136 echo "dead.label dead"
137 echo "dead.draw STACK"
138 echo "dead.colour $DEAD"
139 echo "dead.info The number of dead processes."
140 print_warning dead
141 print_critical dead
142 echo "paging.label paging"
143 echo "paging.draw STACK"
144 echo "paging.colour $PAGING"
145 echo "paging.info The number of paging processes (<2.6 kernels only)."
146 print_warning paging
147 print_critical paging
148 echo "debugged.label debug"
149 echo "debugged.draw STACK"
150 echo "debugged.colour $DEBUGGED"
151 echo "debugged.info The number of processes stopped for debugging"
152 print_warning debugged
153 print_critical debugged
154
155 elif [ "$OPERSYS" = "SunOS" ]; then
156 echo "graph_order sleeping stopped zombie runnable running total"
157 echo "running.label running"
158 echo "running.draw STACK"
159 echo "running.colour $RUNNING"
160 echo "running.info The number of processes that are running on a processor."
161 print_warning running
162 print_critical running
163 # Be backwards compatible.
164 echo "total.label total"
165 echo "total.draw LINE1"
166 echo "total.colour $TOTAL"
167 echo "total.info The total number of processes."
168 print_warning total
169 print_critical total
170
171 elif [ "$OPERSYS" = "FreeBSD" ]; then
172 echo "graph_order sleeping idle stopped zombie lock uninterruptible interrupt runnable processes"
173 echo "lock.label lock"
174 echo "lock.draw STACK"
175 echo "lock.colour $LOCK"
176 echo "lock.info The number of processes that are waiting to acquire a lock."
177 print_warning lock
178 print_critical lock
179 echo "interrupt.label interrupt"
180 echo "interrupt.draw STACK"
181 echo "interrupt.colour $INTERRUPT"
182 echo "interrupt.info The number of idle interrupt threads."
183 print_warning interrupt
184 print_critical interrupt
185
186 elif [ "$OPERSYS" = "OpenBSD" ]; then
187 echo "graph_order sleeping idle stopped zombie uninterruptible runnable processes"
188
189 elif [ "$OPERSYS" = "NetBSD" ]; then
190 echo "graph_order sleeping idle stopped zombie uninterruptible suspended runnable processes"
191 echo "suspended.label suspended"
192 echo "suspended.draw STACK"
193 echo "suspended.colour $SUSPENDED"
194 echo "suspended.info The number of processes that are suspended."
195 print_warning suspended
196 print_critical suspended
197
198 elif [ "$OPERSYS" = "Darwin" ]; then
199 echo "graph_order sleeping idle stopped zombie uninterruptible running processes"
200 echo "uninterruptible.label uninterruptible"
201 echo "uninterruptible.draw STACK"
202 echo "uninterruptible.colour $UNINTERRUPTIBLE"
203 echo "uninterruptible.info The number of uninterruptible processes (usually IO)."
204 print_warning uninterruptible
205 print_critical uninterruptible
206 elif [ "$OPERSYS" = "HP-UX" ]; then
207 echo "graph_order sleeping intermediate stopped terminated waiting growing nonexistent runnable processes"
208 echo "waiting.label waiting"
209 echo "waiting.draw STACK"
210 echo "waiting.colour $INTERRUPT"
211 echo "waiting.info The number of waiting processes."
212 print_warning waiting
213 print_critical waiting
214 echo "terminated.label terminated"
215 echo "terminated.draw STACK"
216 echo "terminated.colour $ZOMBIE"
217 echo "terminated.info The number of processes that are terminated."
218 print_warning terminated
219 print_critical terminated
220 echo "growing.label growing"
221 echo "growing.draw STACK"
222 echo "growing.colour $RUNNING"
223 echo "growing.info The number of growing processes."
224 print_warning growing
225 print_critical growing
226 echo "intermediate.label intermediate"
227 echo "intermediate.draw STACK"
228 echo "intermediate.colour $IDLE"
229 echo "intermediate.info The number of intermediate processes."
230 print_warning intermediate
231 print_critical intermediate
232 echo "nonexistent.label nonexistent"
233 echo "nonexistent.draw STACK"
234 echo "nonexistent.colour $LOCK"
235 echo "nonexistent.info The number of nonexistent processes."
236 print_warning nonexistent
237 print_critical nonexistent
238 fi
239
240 # Common flags for some OS
241 if [ "$OPERSYS" = "FreeBSD" ] || [ "$OPERSYS" = "OpenBSD" ] ||
242 [ "$OPERSYS" = "NetBSD" ] || [ "$OPERSYS" = "Darwin" ]; then
243 echo "idle.label idle"
244 echo "idle.draw STACK"
245 echo "idle.colour $IDLE"
246 echo "idle.info The number of processes that are idle (sleeping for longer than about 20 seconds)."
247 print_warning idle
248 print_critical idle
249 echo "sleeping.label sleeping"
250 echo "sleeping.draw AREA"
251 echo "sleeping.colour $SLEEPING"
252 echo "sleeping.info The number of processes that are sleeping for less than about 20 seconds."
253 print_warning sleeping
254 print_critical sleeping
255 elif [ "$OPERSYS" = "Linux" ]; then
256 echo "idle.label idle"
257 echo "idle.draw STACK"
258 echo "idle.colour $IDLE"
259 echo "idle.info The number of idle kernel threads (>= 4.2 kernels only)."
260 print_warning idle
261 print_critical idle
262 echo "sleeping.label sleeping"
263 echo "sleeping.draw AREA"
264 echo "sleeping.colour $SLEEPING"
265 echo "sleeping.info The number of sleeping processes."
266 print_warning sleeping
267 print_critical sleeping
268 elif [ "$OPERSYS" = "SunOS" ] || [ "$OPERSYS" = "HP-UX" ]; then
269 echo "sleeping.label sleeping"
270 echo "sleeping.draw AREA"
271 echo "sleeping.colour $SLEEPING"
272 echo "sleeping.info The number of sleeping processes."
273 print_warning sleeping
274 print_critical sleeping
275 fi
276
277 if [ "$OPERSYS" = "Linux" ] || [ "$OPERSYS" = "FreeBSD" ] ||
278 [ "$OPERSYS" = "OpenBSD" ] || [ "$OPERSYS" = "NetBSD" ]; then
279 echo "uninterruptible.label uninterruptible"
280 echo "uninterruptible.draw STACK"
281 echo "uninterruptible.colour $UNINTERRUPTIBLE"
282 echo "uninterruptible.info The number of uninterruptible processes (usually IO)."
283 print_warning uninterruptible
284 print_critical uninterruptible
285 fi
286
287 # Common (non-cygwin) flags
288 if [ "$OPERSYS" != "CYGWIN" ]; then
289 echo "stopped.label stopped"
290 echo "stopped.draw STACK"
291 echo "stopped.colour $STOPPED"
292 echo "stopped.info The number of stopped or traced processes."
293 print_warning stopped
294 print_critical stopped
295
296 echo "runnable.label runnable"
297 echo "runnable.draw STACK"
298 echo "runnable.colour $RUNNABLE"
299 echo "runnable.info The number of runnable processes (on the run queue)."
300 print_warning runnable
301 print_critical runnable
302 fi
303
304 if [ "$OPERSYS" != "CYGWIN" ] && [ "$OPERSYS" != "HP-UX" ]; then
305 echo "zombie.label zombie"
306 echo "zombie.draw STACK"
307 echo "zombie.colour $ZOMBIE"
308 echo "zombie.info The number of defunct ('zombie') processes (process terminated and parent not waiting)."
309 print_warning zombie
310 print_critical zombie
311 fi
312
313 if [ "$OPERSYS" != "SunOS" ]; then
314 # Not using 'graph_total' due to backwards compability. SunOS uses 'total'.
315 #echo 'graph_total total'
316 echo "processes.label total"
317 echo "processes.draw LINE1"
318 echo "processes.colour $TOTAL"
319 echo "processes.info The total number of processes."
320 print_warning processes
321 print_critical processes
322 fi
323
324 exit 0
325 fi
326
327 if [ "$OPERSYS" = "Linux" ]; then
328 # shellcheck disable=SC2016
329 "$ps" --no-header -eo s | "$awk" '
330 { processes++; stat[$1]++ }
331 END {
332 print "processes.value " 0+processes;
333 print "uninterruptible.value " 0+stat["D"];
334 print "runnable.value " 0+stat["R"];
335 print "sleeping.value " 0+stat["S"];
336 print "idle.value " 0+stat["I"];
337 print "debugged.value " 0+stat["t"];
338 print "stopped.value " 0+stat["T"];
339 print "paging.value " 0+stat["W"];
340 print "dead.value " 0+stat["X"];
341 print "zombie.value " 0+stat["Z"];
342 }'
343
344 elif [ "$OPERSYS" = "SunOS" ]; then
345 # shellcheck disable=SC2016
346 "$ps" -e -o s | "$awk" '
347 { total++; stat[$1]++ }
348 END {
349 print "total.value " 0+total;
350 print "running.value " 0+stat["O"];
351 print "sleeping.value " 0+stat["S"];
352 print "runnable.value " 0+stat["R"];
353 print "stopped.value " 0+stat["T"];
354 print "zombie.value " 0+stat["Z"];
355 }'
356 elif [ "$OPERSYS" = "FreeBSD" ]; then
357 # shellcheck disable=SC2016
358 "$ps" -axo state= | sed -e 's/^\(.\).*/\1/' | "$awk" '
359 { processes++; stat[$1]++ }
360 END {
361 print "processes.value " 0+processes;
362 print "uninterruptible.value " 0+stat["D"];
363 print "idle.value " 0+stat["I"];
364 print "lock.value " 0+stat["G"];
365 print "runnable.value " 0+stat["R"];
366 print "sleeping.value " 0+stat["S"];
367 print "stopped.value " 0+stat["T"];
368 print "interrupt.value " 0+stat["W"];
369 print "zombie.value " 0+stat["Z"];
370 }'
371 elif [ "$OPERSYS" = "OpenBSD" ]; then
372 # First line is header. Remove it.
373 # shellcheck disable=SC2016
374 "$ps" -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | "$awk" '
375 { processes++; stat[$1]++ }
376 END {
377 print "processes.value " 0+processes;
378 print "uninterruptible.value " 0+stat["D"];
379 print "idle.value " 0+stat["I"];
380 print "runnable.value " 0+stat["R"];
381 print "sleeping.value " 0+stat["S"];
382 print "stopped.value " 0+stat["T"];
383 print "zombie.value " 0+stat["Z"];
384 }'
385 elif [ "$OPERSYS" = "NetBSD" ]; then
386 # First line is header. Remove it.
387 # shellcheck disable=SC2016
388 "$ps" -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | "$awk" '
389 { processes++; stat[$1]++ }
390 END {
391 print "processes.value " 0+processes;
392 print "uninterruptible.value " 0+stat["D"];
393 print "idle.value " 0+stat["I"];
394 print "suspended.value " 0+stat["U"];
395 print "runnable.value " 0+stat["R"];
396 print "sleeping.value " 0+stat["S"];
397 print "stopped.value " 0+stat["T"];
398 print "zombie.value " 0+stat["Z"];
399 }'
400
401 elif [ "$OPERSYS" = "Darwin" ]; then
402 # First line is header. Remove it.
403 # shellcheck disable=SC2016
404 "$ps" -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | "$awk" '
405 { processes++; stat[$1]++ }
406 END {
407 print "processes.value " 0+processes;
408 print "uninterruptible.value " 0+stat["U"];
409 print "idle.value " 0+stat["I"];
410 print "runnable.value " 0+stat["R"];
411 print "sleeping.value " 0+stat["S"];
412 print "stopped.value " 0+stat["T"];
413 print "zombie.value " 0+stat["Z"];
414 }'
415
416 elif [ "$OPERSYS" = "CYGWIN" ]; then
417 # First line is header. Remove it. Also remove WINPID duplicates.
418 # shellcheck disable=SC2016
419 "$ps" -aW | sed '1d' | cut -c 30-36 | sort -u | "$awk" '
420 { processes++; }
421 END {
422 print "processes.value " 0+processes;
423 }'
424
425 elif [ "$OPERSYS" = "HP-UX" ]; then
426 # First line is header. Remove it.
427 # shellcheck disable=SC2016
428 "$ps" -el | sed '1d' | "$awk" '{print $2}' | "$awk" '
429 { processes++; stat[$1]++ }
430 END {
431 print "processes.value " 0+processes;
432 print "nonexistent.value " 0+stat["0"];
433 print "sleeping.value " 0+stat["S"];
434 print "waiting.value " 0+stat["W"];
435 print "runnable.value " 0+stat["R"];
436 print "intermediate.value " 0+stat["I"];
437 print "terminated.value " 0+stat["Z"];
438 print "stopped.value " 0+stat["T"];
439 print "growing.value " 0+stat["X"];
440 }'
441
442 fi