summaryrefslogtreecommitdiffstats
path: root/plugins/check_nagios.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_nagios.c')
-rw-r--r--plugins/check_nagios.c306
1 files changed, 141 insertions, 165 deletions
diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c
index 40d68f0..48629be 100644
--- a/plugins/check_nagios.c
+++ b/plugins/check_nagios.c
@@ -1,58 +1,56 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_nagios plugin 3 * Monitoring check_nagios plugin
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 1999-2007 Monitoring Plugins Development Team 6 * Copyright (c) 1999-2024 Monitoring Plugins Development Team
7* 7 *
8* Description: 8 * Description:
9* 9 *
10* This file contains the check_nagios plugin 10 * This file contains the check_nagios plugin
11* 11 *
12* This plugin checks the status of the Nagios process on the local machine. 12 * This plugin checks the status of the Nagios process on the local machine.
13* The plugin will check to make sure the Nagios status log is no older than 13 * The plugin will check to make sure the Nagios status log is no older than
14* the number of minutes specified by the expires option. 14 * the number of minutes specified by the expires option.
15* It also checks the process table for a process matching the command 15 * It also checks the process table for a process matching the command
16* argument. 16 * argument.
17* 17 *
18* 18 *
19* This program is free software: you can redistribute it and/or modify 19 * This program is free software: you can redistribute it and/or modify
20* it under the terms of the GNU General Public License as published by 20 * it under the terms of the GNU General Public License as published by
21* the Free Software Foundation, either version 3 of the License, or 21 * the Free Software Foundation, either version 3 of the License, or
22* (at your option) any later version. 22 * (at your option) any later version.
23* 23 *
24* This program is distributed in the hope that it will be useful, 24 * This program is distributed in the hope that it will be useful,
25* but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27* GNU General Public License for more details. 27 * GNU General Public License for more details.
28* 28 *
29* You should have received a copy of the GNU General Public License 29 * You should have received a copy of the GNU General Public License
30* along with this program. If not, see <http://www.gnu.org/licenses/>. 30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31* 31 *
32* 32 *
33*****************************************************************************/ 33 *****************************************************************************/
34 34
35const char *progname = "check_nagios"; 35const char *progname = "check_nagios";
36const char *copyright = "1999-2007"; 36const char *copyright = "1999-2024";
37const char *email = "devel@monitoring-plugins.org"; 37const char *email = "devel@monitoring-plugins.org";
38 38
39#include "common.h" 39#include "common.h"
40#include "runcmd.h" 40#include "runcmd.h"
41#include "utils.h" 41#include "utils.h"
42 42
43int process_arguments (int, char **); 43static int process_arguments(int /*argc*/, char ** /*argv*/);
44void print_help (void); 44static void print_help(void);
45void print_usage (void); 45void print_usage(void);
46 46
47char *status_log = NULL; 47static char *status_log = NULL;
48char *process_string = NULL; 48static char *process_string = NULL;
49int expire_minutes = 0; 49static int expire_minutes = 0;
50 50
51int verbose = 0; 51static int verbose = 0;
52 52
53int 53int main(int argc, char **argv) {
54main (int argc, char **argv)
55{
56 int result = STATE_UNKNOWN; 54 int result = STATE_UNKNOWN;
57 char input_buffer[MAX_INPUT_BUFFER]; 55 char input_buffer[MAX_INPUT_BUFFER];
58 unsigned long latest_entry_time = 0L; 56 unsigned long latest_entry_time = 0L;
@@ -73,253 +71,231 @@ main (int argc, char **argv)
73#endif /* PS_USES_PROCETIME */ 71#endif /* PS_USES_PROCETIME */
74 char procprog[MAX_INPUT_BUFFER]; 72 char procprog[MAX_INPUT_BUFFER];
75 char *procargs; 73 char *procargs;
76 int pos, cols; 74 int pos;
75 int cols;
77 int expected_cols = PS_COLS - 1; 76 int expected_cols = PS_COLS - 1;
78 const char *zombie = "Z"; 77 const char *zombie = "Z";
79 char *temp_string; 78 char *temp_string;
80 output chld_out, chld_err; 79 output chld_out;
80 output chld_err;
81 size_t i; 81 size_t i;
82 82
83 setlocale (LC_ALL, ""); 83 setlocale(LC_ALL, "");
84 bindtextdomain (PACKAGE, LOCALEDIR); 84 bindtextdomain(PACKAGE, LOCALEDIR);
85 textdomain (PACKAGE); 85 textdomain(PACKAGE);
86 86
87 /* Parse extra opts if any */ 87 /* Parse extra opts if any */
88 argv=np_extra_opts (&argc, argv, progname); 88 argv = np_extra_opts(&argc, argv, progname);
89 89
90 if (process_arguments (argc, argv) == ERROR) 90 if (process_arguments(argc, argv) == ERROR)
91 usage_va(_("Could not parse arguments")); 91 usage_va(_("Could not parse arguments"));
92 92
93 /* Set signal handling and alarm timeout */ 93 /* Set signal handling and alarm timeout */
94 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { 94 if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
95 usage_va(_("Cannot catch SIGALRM")); 95 usage_va(_("Cannot catch SIGALRM"));
96 } 96 }
97 97
98 /* handle timeouts gracefully... */ 98 /* handle timeouts gracefully... */
99 alarm (timeout_interval); 99 alarm(timeout_interval);
100 100
101 /* open the status log */ 101 /* open the status log */
102 fp = fopen (status_log, "r"); 102 fp = fopen(status_log, "r");
103 if (fp == NULL) { 103 if (fp == NULL) {
104 die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot open status log for reading!")); 104 die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot open status log for reading!"));
105 } 105 }
106 106
107 /* get the date/time of the last item updated in the log */ 107 /* get the date/time of the last item updated in the log */
108 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { 108 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
109 if ((temp_ptr = strstr (input_buffer, "created=")) != NULL) { 109 if ((temp_ptr = strstr(input_buffer, "created=")) != NULL) {
110 temp_entry_time = strtoul (temp_ptr + 8, NULL, 10); 110 temp_entry_time = strtoul(temp_ptr + 8, NULL, 10);
111 latest_entry_time = temp_entry_time; 111 latest_entry_time = temp_entry_time;
112 break; 112 break;
113 } else if ((temp_ptr = strtok (input_buffer, "]")) != NULL) { 113 }
114 temp_entry_time = strtoul (temp_ptr + 1, NULL, 10); 114 if ((temp_ptr = strtok(input_buffer, "]")) != NULL) {
115 temp_entry_time = strtoul(temp_ptr + 1, NULL, 10);
115 if (temp_entry_time > latest_entry_time) 116 if (temp_entry_time > latest_entry_time)
116 latest_entry_time = temp_entry_time; 117 latest_entry_time = temp_entry_time;
117 } 118 }
118 } 119 }
119 fclose (fp); 120 fclose(fp);
120 121
121 if (verbose >= 2) 122 if (verbose >= 2)
122 printf("command: %s\n", PS_COMMAND); 123 printf("command: %s\n", PS_COMMAND);
123 124
124 /* run the command to check for the Nagios process.. */ 125 /* run the command to check for the Nagios process.. */
125 if((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0) 126 if ((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0)
126 result = STATE_WARNING; 127 result = STATE_WARNING;
127 128
128 /* count the number of matching Nagios processes... */ 129 /* count the number of matching Nagios processes... */
129 for(i = 0; i < chld_out.lines; i++) { 130 for (i = 0; i < chld_out.lines; i++) {
130 cols = sscanf (chld_out.line[i], PS_FORMAT, PS_VARLIST); 131 cols = sscanf(chld_out.line[i], PS_FORMAT, PS_VARLIST);
131 /* Zombie processes do not give a procprog command */ 132 /* Zombie processes do not give a procprog command */
132 if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) { 133 if (cols == (expected_cols - 1) && strstr(procstat, zombie)) {
133 cols = expected_cols; 134 cols = expected_cols;
134 /* Set some value for procargs for the strip command further below 135 /* Set some value for procargs for the strip command further below
135 * Seen to be a problem on some Solaris 7 and 8 systems */ 136 * Seen to be a problem on some Solaris 7 and 8 systems */
136 chld_out.line[i][pos] = '\n'; 137 chld_out.line[i][pos] = '\n';
137 chld_out.line[i][pos+1] = 0x0; 138 chld_out.line[i][pos + 1] = 0x0;
138 } 139 }
139 if ( cols >= expected_cols ) { 140 if (cols >= expected_cols) {
140 xasprintf (&procargs, "%s", chld_out.line[i] + pos); 141 xasprintf(&procargs, "%s", chld_out.line[i] + pos);
141 strip (procargs); 142 strip(procargs);
142 143
143 /* Some ps return full pathname for command. This removes path */ 144 /* Some ps return full pathname for command. This removes path */
144 temp_string = strtok ((char *)procprog, "/"); 145 temp_string = strtok((char *)procprog, "/");
145 while (temp_string) { 146 while (temp_string) {
146 strcpy(procprog, temp_string); 147 strcpy(procprog, temp_string);
147 temp_string = strtok (NULL, "/"); 148 temp_string = strtok(NULL, "/");
148 } 149 }
149 150
150 /* May get empty procargs */ 151 /* May get empty procargs */
151 if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs,"")) { 152 if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs, "")) {
152 proc_entries++; 153 proc_entries++;
153 if (verbose >= 2) { 154 if (verbose >= 2) {
154 printf (_("Found process: %s %s\n"), procprog, procargs); 155 printf(_("Found process: %s %s\n"), procprog, procargs);
155 } 156 }
156 } 157 }
157 } 158 }
158 } 159 }
159 160
160 /* If we get anything on stderr, at least set warning */ 161 /* If we get anything on stderr, at least set warning */
161 if(chld_err.buflen) 162 if (chld_err.buflen)
162 result = max_state (result, STATE_WARNING); 163 result = max_state(result, STATE_WARNING);
163 164
164 /* reset the alarm handler */ 165 /* reset the alarm handler */
165 alarm (0); 166 alarm(0);
166 167
167 if (proc_entries == 0) { 168 if (proc_entries == 0) {
168 die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Could not locate a running Nagios process!")); 169 die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Could not locate a running Nagios process!"));
169 } 170 }
170 171
171 if (latest_entry_time == 0L) { 172 if (latest_entry_time == 0L) {
172 die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot parse Nagios log file for valid time")); 173 die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot parse Nagios log file for valid time"));
173 } 174 }
174 175
175 time (&current_time); 176 time(&current_time);
176 if ((int)(current_time - latest_entry_time) > (expire_minutes * 60)) { 177 if ((int)(current_time - latest_entry_time) > (expire_minutes * 60)) {
177 result = STATE_WARNING; 178 result = STATE_WARNING;
178 } else { 179 } else {
179 result = STATE_OK; 180 result = STATE_OK;
180 } 181 }
181 182
182 printf ("NAGIOS %s: ", (result == STATE_OK) ? _("OK") : _("WARNING")); 183 printf("NAGIOS %s: ", (result == STATE_OK) ? _("OK") : _("WARNING"));
183 printf (ngettext ("%d process", "%d processes", proc_entries), proc_entries); 184 printf(ngettext("%d process", "%d processes", proc_entries), proc_entries);
184 printf (", "); 185 printf(", ");
185 printf ( 186 printf(ngettext("status log updated %d second ago", "status log updated %d seconds ago", (int)(current_time - latest_entry_time)),
186 ngettext ("status log updated %d second ago", 187 (int)(current_time - latest_entry_time));
187 "status log updated %d seconds ago", 188 printf("\n");
188 (int) (current_time - latest_entry_time) ),
189 (int) (current_time - latest_entry_time) );
190 printf ("\n");
191 189
192 return result; 190 return result;
193} 191}
194 192
195
196
197/* process command-line arguments */ 193/* process command-line arguments */
198int 194int process_arguments(int argc, char **argv) {
199process_arguments (int argc, char **argv)
200{
201 int c; 195 int c;
202 196
203 int option = 0; 197 int option = 0;
204 static struct option longopts[] = { 198 static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'},
205 {"filename", required_argument, 0, 'F'}, 199 {"command", required_argument, 0, 'C'}, {"timeout", optional_argument, 0, 't'},
206 {"expires", required_argument, 0, 'e'}, 200 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'},
207 {"command", required_argument, 0, 'C'}, 201 {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0}};
208 {"timeout", optional_argument, 0, 't'},
209 {"version", no_argument, 0, 'V'},
210 {"help", no_argument, 0, 'h'},
211 {"verbose", no_argument, 0, 'v'},
212 {0, 0, 0, 0}
213 };
214 202
215 if (argc < 2) 203 if (argc < 2)
216 return ERROR; 204 return ERROR;
217 205
218 if (!is_option (argv[1])) { 206 if (!is_option(argv[1])) {
219 status_log = argv[1]; 207 status_log = argv[1];
220 if (is_intnonneg (argv[2])) 208 if (is_intnonneg(argv[2]))
221 expire_minutes = atoi (argv[2]); 209 expire_minutes = atoi(argv[2]);
222 else 210 else
223 die (STATE_UNKNOWN, 211 die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n"));
224 _("Expiration time must be an integer (seconds)\n"));
225 process_string = argv[3]; 212 process_string = argv[3];
226 return OK; 213 return OK;
227 } 214 }
228 215
229 while (1) { 216 while (1) {
230 c = getopt_long (argc, argv, "+hVvF:C:e:t:", longopts, &option); 217 c = getopt_long(argc, argv, "+hVvF:C:e:t:", longopts, &option);
231 218
232 if (c == -1 || c == EOF || c == 1) 219 if (c == -1 || c == EOF || c == 1)
233 break; 220 break;
234 221
235 switch (c) { 222 switch (c) {
236 case 'h': /* help */ 223 case 'h': /* help */
237 print_help (); 224 print_help();
238 exit (STATE_UNKNOWN); 225 exit(STATE_UNKNOWN);
239 case 'V': /* version */ 226 case 'V': /* version */
240 print_revision (progname, NP_VERSION); 227 print_revision(progname, NP_VERSION);
241 exit (STATE_UNKNOWN); 228 exit(STATE_UNKNOWN);
242 case 'F': /* status log */ 229 case 'F': /* status log */
243 status_log = optarg; 230 status_log = optarg;
244 break; 231 break;
245 case 'C': /* command */ 232 case 'C': /* command */
246 process_string = optarg; 233 process_string = optarg;
247 break; 234 break;
248 case 'e': /* expiry time */ 235 case 'e': /* expiry time */
249 if (is_intnonneg (optarg)) 236 if (is_intnonneg(optarg))
250 expire_minutes = atoi (optarg); 237 expire_minutes = atoi(optarg);
251 else 238 else
252 die (STATE_UNKNOWN, 239 die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n"));
253 _("Expiration time must be an integer (seconds)\n"));
254 break; 240 break;
255 case 't': /* timeout */ 241 case 't': /* timeout */
256 if (is_intnonneg (optarg)) 242 if (is_intnonneg(optarg))
257 timeout_interval = atoi (optarg); 243 timeout_interval = atoi(optarg);
258 else 244 else
259 die (STATE_UNKNOWN, 245 die(STATE_UNKNOWN, _("Timeout must be an integer (seconds)\n"));
260 _("Timeout must be an integer (seconds)\n"));
261 break; 246 break;
262 case 'v': 247 case 'v':
263 verbose++; 248 verbose++;
264 break; 249 break;
265 default: /* print short usage_va statement if args not parsable */ 250 default: /* print short usage_va statement if args not parsable */
266 usage5(); 251 usage5();
267 } 252 }
268 } 253 }
269 254
270
271 if (status_log == NULL) 255 if (status_log == NULL)
272 die (STATE_UNKNOWN, _("You must provide the status_log\n")); 256 die(STATE_UNKNOWN, _("You must provide the status_log\n"));
273 257
274 if (process_string == NULL) 258 if (process_string == NULL)
275 die (STATE_UNKNOWN, _("You must provide a process string\n")); 259 die(STATE_UNKNOWN, _("You must provide a process string\n"));
276 260
277 return OK; 261 return OK;
278} 262}
279 263
264void print_help(void) {
265 print_revision(progname, NP_VERSION);
280 266
267 printf(_(COPYRIGHT), copyright, email);
281 268
282void 269 printf("%s\n", _("This plugin checks the status of the Nagios process on the local machine"));
283print_help (void) 270 printf("%s\n", _("The plugin will check to make sure the Nagios status log is no older than"));
284{ 271 printf("%s\n", _("the number of minutes specified by the expires option."));
285 print_revision (progname, NP_VERSION); 272 printf("%s\n", _("It also checks the process table for a process matching the command argument."));
286 273
287 printf (_(COPYRIGHT), copyright, email); 274 printf("\n\n");
288 275
289 printf ("%s\n", _("This plugin checks the status of the Nagios process on the local machine")); 276 print_usage();
290 printf ("%s\n", _("The plugin will check to make sure the Nagios status log is no older than"));
291 printf ("%s\n", _("the number of minutes specified by the expires option."));
292 printf ("%s\n", _("It also checks the process table for a process matching the command argument."));
293 277
294 printf ("\n\n"); 278 printf(UT_HELP_VRSN);
279 printf(UT_EXTRA_OPTS);
295 280
296 print_usage (); 281 printf(" %s\n", "-F, --filename=FILE");
282 printf(" %s\n", _("Name of the log file to check"));
283 printf(" %s\n", "-e, --expires=INTEGER");
284 printf(" %s\n", _("Minutes aging after which logfile is considered stale"));
285 printf(" %s\n", "-C, --command=STRING");
286 printf(" %s\n", _("Substring to search for in process arguments"));
287 printf(" %s\n", "-t, --timeout=INTEGER");
288 printf(" %s\n", _("Timeout for the plugin in seconds"));
289 printf(UT_VERBOSE);
297 290
298 printf (UT_HELP_VRSN); 291 printf("\n");
299 printf (UT_EXTRA_OPTS); 292 printf("%s\n", _("Examples:"));
293 printf(" %s\n", "check_nagios -t 20 -e 5 -F /usr/local/nagios/var/status.log -C /usr/local/nagios/bin/nagios");
300 294
301 printf (" %s\n", "-F, --filename=FILE"); 295 printf(UT_SUPPORT);
302 printf (" %s\n", _("Name of the log file to check"));
303 printf (" %s\n", "-e, --expires=INTEGER");
304 printf (" %s\n", _("Minutes aging after which logfile is considered stale"));
305 printf (" %s\n", "-C, --command=STRING");
306 printf (" %s\n", _("Substring to search for in process arguments"));
307 printf (" %s\n", "-t, --timeout=INTEGER");
308 printf (" %s\n", _("Timeout for the plugin in seconds"));
309 printf (UT_VERBOSE);
310
311 printf ("\n");
312 printf ("%s\n", _("Examples:"));
313 printf (" %s\n", "check_nagios -t 20 -e 5 -F /usr/local/nagios/var/status.log -C /usr/local/nagios/bin/nagios");
314
315 printf (UT_SUPPORT);
316} 296}
317 297
318 298void print_usage(void) {
319 299 printf("%s\n", _("Usage:"));
320void 300 printf("%s -F <status log file> -t <timeout_seconds> -e <expire_minutes> -C <process_string>\n", progname);
321print_usage (void)
322{
323 printf ("%s\n", _("Usage:"));
324 printf ("%s -F <status log file> -t <timeout_seconds> -e <expire_minutes> -C <process_string>\n", progname);
325} 301}