Code

Fix translations when extra-opts aren't enabled
[nagiosplug.git] / plugins / check_nagios.c
1 /*****************************************************************************
2
3 * Nagios check_nagios plugin
4
5 * License: GPL
6 * Copyright (c) 1999-2007 Nagios Plugins Development Team
7
8 * Description:
9
10 * This file contains the check_nagios plugin
11
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
14 * the number of minutes specified by the expires option.
15 * It also checks the process table for a process matching the command
16 * argument.
17
18
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
21 * the Free Software Foundation, either version 3 of the License, or
22 * (at your option) any later version.
23
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27 * GNU General Public License for more details.
28
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/>.
31
32
33 *****************************************************************************/
35 const char *progname = "check_nagios";
36 const char *copyright = "1999-2007";
37 const char *email = "nagiosplug-devel@lists.sourceforge.net";
39 #include "common.h"
40 #include "runcmd.h"
41 #include "utils.h"
43 int process_arguments (int, char **);
44 void print_help (void);
45 void print_usage (void);
47 char *status_log = NULL;
48 char *process_string = NULL;
49 int expire_minutes = 0;
51 int verbose = 0;
53 int
54 main (int argc, char **argv)
55 {
56         int result = STATE_UNKNOWN;
57         char input_buffer[MAX_INPUT_BUFFER];
58         unsigned long latest_entry_time = 0L;
59         unsigned long temp_entry_time = 0L;
60         int proc_entries = 0;
61         time_t current_time;
62         char *temp_ptr;
63         FILE *fp;
64         int procuid = 0;
65         int procpid = 0;
66         int procppid = 0;
67         int procvsz = 0;
68         int procrss = 0;
69         float procpcpu = 0;
70         char procstat[8];
71 #ifdef PS_USES_PROCETIME
72         char procetime[MAX_INPUT_BUFFER];
73 #endif /* PS_USES_PROCETIME */
74         char procprog[MAX_INPUT_BUFFER];
75         char *procargs;
76         int pos, cols;
77         int expected_cols = PS_COLS - 1;
78         const char *zombie = "Z";
79         char *temp_string;
80         output chld_out, chld_err;
81         size_t i;
83         setlocale (LC_ALL, "");
84         bindtextdomain (PACKAGE, LOCALEDIR);
85         textdomain (PACKAGE);
87         /* Parse extra opts if any */
88         argv=np_extra_opts (&argc, argv, progname);
90         if (process_arguments (argc, argv) == ERROR)
91                 usage_va(_("Could not parse arguments"));
93         /* Set signal handling and alarm timeout */
94         if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
95                 usage_va(_("Cannot catch SIGALRM"));
96         }
98         /* handle timeouts gracefully... */
99         alarm (timeout_interval);
101         /* open the status log */
102         fp = fopen (status_log, "r");
103         if (fp == NULL) {
104                 die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot open status log for reading!"));
105         }
107         /* get the date/time of the last item updated in the log */
108         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
109                 if ((temp_ptr = strstr (input_buffer, "created=")) != NULL) {
110                         temp_entry_time = strtoul (temp_ptr + 8, NULL, 10);
111                         latest_entry_time = temp_entry_time;
112                         break;
113                 } else if ((temp_ptr = strtok (input_buffer, "]")) != NULL) {
114                         temp_entry_time = strtoul (temp_ptr + 1, NULL, 10);
115                         if (temp_entry_time > latest_entry_time)
116                                 latest_entry_time = temp_entry_time;
117                 }
118         }
119         fclose (fp);
121         if (verbose >= 2)
122                 printf("command: %s\n", PS_COMMAND);
124         /* run the command to check for the Nagios process.. */
125         if((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0)
126                 result = STATE_WARNING;
128         /* count the number of matching Nagios processes... */
129         for(i = 0; i < chld_out.lines; i++) {
130                 cols = sscanf (chld_out.line[i], PS_FORMAT, PS_VARLIST);
131                 /* Zombie processes do not give a procprog command */
132                 if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) {
133                         cols = expected_cols;
134                         /* 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                         chld_out.line[i][pos] = '\n';
137                         chld_out.line[i][pos+1] = 0x0;
138                 }
139                 if ( cols >= expected_cols ) {
140                         asprintf (&procargs, "%s", chld_out.line[i] + pos);
141                         strip (procargs);
143                         /* Some ps return full pathname for command. This removes path */
144                         temp_string = strtok ((char *)procprog, "/");
145                         while (temp_string) {
146                                 strcpy(procprog, temp_string);
147                                 temp_string = strtok (NULL, "/");
148                         }
150                         /* May get empty procargs */
151                         if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs,"")) {
152                                 proc_entries++;
153                                 if (verbose >= 2) {
154                                         printf (_("Found process: %s %s\n"), procprog, procargs);
155                                 }
156                         }
157                 }
158         }
160         /* If we get anything on stderr, at least set warning */
161         if(chld_err.buflen)
162                 result = max_state (result, STATE_WARNING);
164         /* reset the alarm handler */
165         alarm (0);
167         if (proc_entries == 0) {
168                 die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Could not locate a running Nagios process!"));
169         }
171         if (latest_entry_time == 0L) {
172                 die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot parse Nagios log file for valid time"));
173         }
175         time (&current_time);
176         if ((int)(current_time - latest_entry_time) > (expire_minutes * 60)) {
177                 result = STATE_WARNING;
178         } else {
179                 result = STATE_OK;
180         }
182         printf ("NAGIOS %s: ", (result == STATE_OK) ? _("OK") : _("WARNING"));
183         printf (ngettext ("%d process", "%d processes", proc_entries), proc_entries);
184         printf (", ");
185         printf (
186           ngettext ("status log updated %d second ago",
187             "status log updated %d seconds ago",
188             (int) (current_time - latest_entry_time) ),
189             (int) (current_time - latest_entry_time) );
190         printf ("\n");
192         return result;
197 /* process command-line arguments */
198 int
199 process_arguments (int argc, char **argv)
201         int c;
203         int option = 0;
204         static struct option longopts[] = {
205                 {"filename", required_argument, 0, 'F'},
206                 {"expires", required_argument, 0, 'e'},
207                 {"command", required_argument, 0, 'C'},
208                 {"version", no_argument, 0, 'V'},
209                 {"help", no_argument, 0, 'h'},
210                 {"verbose", no_argument, 0, 'v'},
211                 {0, 0, 0, 0}
212         };
214         if (argc < 2)
215                 return ERROR;
217         if (!is_option (argv[1])) {
218                 status_log = argv[1];
219                 if (is_intnonneg (argv[2]))
220                         expire_minutes = atoi (argv[2]);
221                 else
222                         die (STATE_UNKNOWN,
223                                                                  _("Expiration time must be an integer (seconds)\n"));
224                 process_string = argv[3];
225                 return OK;
226         }
228         while (1) {
229                 c = getopt_long (argc, argv, "+hVvF:C:e:", longopts, &option);
231                 if (c == -1 || c == EOF || c == 1)
232                         break;
234                 switch (c) {
235                 case 'h':                                                                       /* help */
236                         print_help ();
237                         exit (STATE_OK);
238                 case 'V':                                                                       /* version */
239                         print_revision (progname, NP_VERSION);
240                         exit (STATE_OK);
241                 case 'F':                                                                       /* status log */
242                         status_log = optarg;
243                         break;
244                 case 'C':                                                                       /* command */
245                         process_string = optarg;
246                         break;
247                 case 'e':                                                                       /* expiry time */
248                         if (is_intnonneg (optarg))
249                                 expire_minutes = atoi (optarg);
250                         else
251                                 die (STATE_UNKNOWN,
252                                      _("Expiration time must be an integer (seconds)\n"));
253                         break;
254                 case 'v':
255                         verbose++;
256                         break;
257                 default:                                                                        /* print short usage_va statement if args not parsable */
258                         usage5();
259                 }
260         }
263         if (status_log == NULL)
264                 die (STATE_UNKNOWN, _("You must provide the status_log\n"));
266         if (process_string == NULL)
267                 die (STATE_UNKNOWN, _("You must provide a process string\n"));
269         return OK;
274 void
275 print_help (void)
277         print_revision (progname, NP_VERSION);
279         printf (_(COPYRIGHT), copyright, email);
281         printf ("%s\n", _("This plugin checks the status of the Nagios process on the local machine"));
282   printf ("%s\n", _("The plugin will check to make sure the Nagios status log is no older than"));
283   printf ("%s\n", _("the number of minutes specified by the expires option."));
284   printf ("%s\n", _("It also checks the process table for a process matching the command argument."));
286   printf ("\n\n");
288         print_usage ();
290         printf (UT_HELP_VRSN);
291         printf (UT_EXTRA_OPTS);
293         printf (" %s\n", "-F, --filename=FILE");
294   printf ("    %s\n", _("Name of the log file to check"));
295   printf (" %s\n", "-e, --expires=INTEGER");
296   printf ("    %s\n", _("Minutes aging after which logfile is considered stale"));
297   printf (" %s\n", "-C, --command=STRING");
298   printf ("    %s\n", _("Substring to search for in process arguments"));
299   printf (UT_VERBOSE);
301 #ifdef NP_EXTRA_OPTS
302   printf ("\n");
303   printf ("%s\n", _("Notes:"));
304   printf (UT_EXTRA_OPTS_NOTES);
305 #endif
307   printf ("\n");
308   printf ("%s\n", _("Examples:"));
309   printf (" %s\n", "check_nagios -e 5 -F /usr/local/nagios/var/status.log -C /usr/local/nagios/bin/nagios");
311   printf (UT_SUPPORT);
316 void
317 print_usage (void)
319   printf (_("Usage:"));
320         printf ("%s -F <status log file> -e <expire_minutes> -C <process_string>\n", progname);