diff options
Diffstat (limited to 'plugins/check_nagios.c')
-rw-r--r-- | plugins/check_nagios.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c new file mode 100644 index 00000000..04258354 --- /dev/null +++ b/plugins/check_nagios.c | |||
@@ -0,0 +1,267 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * CHECK_NAGIOS.C | ||
4 | * | ||
5 | * Program: Nagios process plugin for Nagios | ||
6 | * License: GPL | ||
7 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) | ||
8 | * | ||
9 | * $Id$ | ||
10 | * | ||
11 | * License Information: | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #include "common.h" | ||
30 | #include "popen.h" | ||
31 | #include "utils.h" | ||
32 | |||
33 | #define PROGNAME "check_nagios" | ||
34 | |||
35 | int process_arguments (int, char **); | ||
36 | void print_usage (void); | ||
37 | void print_help (void); | ||
38 | |||
39 | char *status_log = NULL; | ||
40 | char *process_string = NULL; | ||
41 | int expire_minutes = 0; | ||
42 | |||
43 | int | ||
44 | main (int argc, char **argv) | ||
45 | { | ||
46 | int result = STATE_UNKNOWN; | ||
47 | char input_buffer[MAX_INPUT_BUFFER]; | ||
48 | unsigned long latest_entry_time = 0L; | ||
49 | unsigned long temp_entry_time = 0L; | ||
50 | int proc_entries = 0; | ||
51 | time_t current_time; | ||
52 | char *temp_ptr; | ||
53 | FILE *fp; | ||
54 | |||
55 | if (process_arguments (argc, argv) == ERROR) | ||
56 | usage ("Could not parse arguments\n"); | ||
57 | |||
58 | /* Set signal handling and alarm */ | ||
59 | if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { | ||
60 | printf ("Cannot catch SIGALRM"); | ||
61 | return STATE_UNKNOWN; | ||
62 | } | ||
63 | |||
64 | /* handle timeouts gracefully... */ | ||
65 | alarm (timeout_interval); | ||
66 | |||
67 | /* open the status log */ | ||
68 | fp = fopen (status_log, "r"); | ||
69 | if (fp == NULL) { | ||
70 | printf ("Error: Cannot open status log for reading!\n"); | ||
71 | return STATE_CRITICAL; | ||
72 | } | ||
73 | |||
74 | /* get the date/time of the last item updated in the log */ | ||
75 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { | ||
76 | temp_ptr = strtok (input_buffer, "]"); | ||
77 | temp_entry_time = | ||
78 | (temp_ptr == NULL) ? 0L : strtoul (temp_ptr + 1, NULL, 10); | ||
79 | if (temp_entry_time > latest_entry_time) | ||
80 | latest_entry_time = temp_entry_time; | ||
81 | } | ||
82 | fclose (fp); | ||
83 | |||
84 | /* run the command to check for the Nagios process.. */ | ||
85 | child_process = spopen (PS_RAW_COMMAND); | ||
86 | if (child_process == NULL) { | ||
87 | printf ("Could not open pipe: %s\n", PS_RAW_COMMAND); | ||
88 | return STATE_UNKNOWN; | ||
89 | } | ||
90 | |||
91 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | ||
92 | if (child_stderr == NULL) { | ||
93 | printf ("Could not open stderr for %s\n", PS_RAW_COMMAND); | ||
94 | } | ||
95 | |||
96 | /* cound the number of matching Nagios processes... */ | ||
97 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | ||
98 | if (strstr (input_buffer, process_string)) | ||
99 | proc_entries++; | ||
100 | } | ||
101 | |||
102 | /* If we get anything on stderr, at least set warning */ | ||
103 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) | ||
104 | result = max (result, STATE_WARNING); | ||
105 | |||
106 | /* close stderr */ | ||
107 | (void) fclose (child_stderr); | ||
108 | |||
109 | /* close the pipe */ | ||
110 | if (spclose (child_process)) | ||
111 | result = max (result, STATE_WARNING); | ||
112 | |||
113 | /* reset the alarm handler */ | ||
114 | alarm (0); | ||
115 | |||
116 | if (proc_entries == 0) { | ||
117 | printf ("Could not locate a running Nagios process!\n"); | ||
118 | return STATE_CRITICAL; | ||
119 | } | ||
120 | |||
121 | result = STATE_OK; | ||
122 | |||
123 | time (¤t_time); | ||
124 | if ((current_time - latest_entry_time) > (expire_minutes * 60)) | ||
125 | result = STATE_WARNING; | ||
126 | |||
127 | printf | ||
128 | ("Nagios %s: located %d process%s, status log updated %d second%s ago\n", | ||
129 | (result == STATE_OK) ? "ok" : "problem", proc_entries, | ||
130 | (proc_entries == 1) ? "" : "es", | ||
131 | (int) (current_time - latest_entry_time), | ||
132 | ((int) (current_time - latest_entry_time) == 1) ? "" : "s"); | ||
133 | |||
134 | return result; | ||
135 | } | ||
136 | |||
137 | |||
138 | |||
139 | |||
140 | |||
141 | /* process command-line arguments */ | ||
142 | int | ||
143 | process_arguments (int argc, char **argv) | ||
144 | { | ||
145 | int c; | ||
146 | |||
147 | #ifdef HAVE_GETOPT_H | ||
148 | int option_index = 0; | ||
149 | static struct option long_options[] = { | ||
150 | {"filename", required_argument, 0, 'F'}, | ||
151 | {"expires", required_argument, 0, 'e'}, | ||
152 | {"command", required_argument, 0, 'C'}, | ||
153 | {"version", no_argument, 0, 'V'}, | ||
154 | {"help", no_argument, 0, 'h'}, | ||
155 | {0, 0, 0, 0} | ||
156 | }; | ||
157 | #endif | ||
158 | |||
159 | if (argc < 2) | ||
160 | return ERROR; | ||
161 | |||
162 | if (!is_option (argv[1])) { | ||
163 | status_log = argv[1]; | ||
164 | if (is_intnonneg (argv[2])) | ||
165 | expire_minutes = atoi (argv[2]); | ||
166 | else | ||
167 | terminate (STATE_UNKNOWN, | ||
168 | "Expiration time must be an integer (seconds)\nType '%s -h' for additional help\n", | ||
169 | PROGNAME); | ||
170 | process_string = argv[3]; | ||
171 | return OK; | ||
172 | } | ||
173 | |||
174 | while (1) { | ||
175 | #ifdef HAVE_GETOPT_H | ||
176 | c = getopt_long (argc, argv, "+hVF:C:e:", long_options, &option_index); | ||
177 | #else | ||
178 | c = getopt (argc, argv, "+hVF:C:e:"); | ||
179 | #endif | ||
180 | |||
181 | if (c == -1 || c == EOF || c == 1) | ||
182 | break; | ||
183 | |||
184 | switch (c) { | ||
185 | case '?': /* print short usage statement if args not parsable */ | ||
186 | printf ("%s: Unknown argument: %c\n\n", my_basename (argv[0]), optopt); | ||
187 | print_usage (); | ||
188 | exit (STATE_UNKNOWN); | ||
189 | case 'h': /* help */ | ||
190 | print_help (); | ||
191 | exit (STATE_OK); | ||
192 | case 'V': /* version */ | ||
193 | print_revision (my_basename (argv[0]), "$Revision$"); | ||
194 | exit (STATE_OK); | ||
195 | case 'F': /* hostname */ | ||
196 | status_log = optarg; | ||
197 | break; | ||
198 | case 'C': /* hostname */ | ||
199 | process_string = optarg; | ||
200 | break; | ||
201 | case 'e': /* hostname */ | ||
202 | if (is_intnonneg (optarg)) | ||
203 | expire_minutes = atoi (optarg); | ||
204 | else | ||
205 | terminate (STATE_UNKNOWN, | ||
206 | "Expiration time must be an integer (seconds)\nType '%s -h' for additional help\n", | ||
207 | PROGNAME); | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | |||
213 | if (status_log == NULL) | ||
214 | terminate (STATE_UNKNOWN, | ||
215 | "You must provide the status_log\nType '%s -h' for additional help\n", | ||
216 | PROGNAME); | ||
217 | else if (process_string == NULL) | ||
218 | terminate (STATE_UNKNOWN, | ||
219 | "You must provide a process string\nType '%s -h' for additional help\n", | ||
220 | PROGNAME); | ||
221 | |||
222 | return OK; | ||
223 | } | ||
224 | |||
225 | |||
226 | |||
227 | |||
228 | |||
229 | void | ||
230 | print_usage (void) | ||
231 | { | ||
232 | printf | ||
233 | ("Usage: %s -F <status log file> -e <expire_minutes> -C <process_string>\n", | ||
234 | PROGNAME); | ||
235 | } | ||
236 | |||
237 | |||
238 | |||
239 | |||
240 | |||
241 | void | ||
242 | print_help (void) | ||
243 | { | ||
244 | print_revision (PROGNAME, "$Revision$"); | ||
245 | printf | ||
246 | ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" | ||
247 | "This plugin attempts to check the status of the Nagios process on the local\n" | ||
248 | "machine. The plugin will check to make sure the Nagios status log is no older\n" | ||
249 | "than the number of minutes specified by the <expire_minutes> option. It also\n" | ||
250 | "uses the /bin/ps command to check for a process matching whatever you specify\n" | ||
251 | "by the <process_string> argument.\n"); | ||
252 | print_usage (); | ||
253 | printf | ||
254 | ("\nOptions:\n" | ||
255 | "-F, --filename=FILE\n" | ||
256 | " Name of the log file to check\n" | ||
257 | "-e, --expires=INTEGER\n" | ||
258 | " Seconds aging afterwhich logfile is condsidered stale\n" | ||
259 | "-C, --command=STRING\n" | ||
260 | " Command to search for in process table\n" | ||
261 | "-h, --help\n" | ||
262 | " Print this help screen\n" | ||
263 | "-V, --version\n" | ||
264 | " Print version information\n\n" | ||
265 | "Example:\n" | ||
266 | " ./check_nagios -H /usr/local/nagios/var/status.log -e 5 -C /usr/local/nagios/bin/nagios\n"); | ||
267 | } | ||