]>
Commit | Line | Data |
---|---|---|
3decc5d1 JR |
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 |