Code

markup for translation
[nagiosplug.git] / plugins / check_nagios.c
1 /******************************************************************************
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; either version 2 of the License, or
6  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  GNU General Public License for more details.
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 ******************************************************************************/
19 const char *progname = "check_nagios";
20 const char *revision = "$Revision$";
21 const char *copyright = "1999-2003";
22 const char *email = "nagiosplug-devel@lists.sourceforge.net";
24 #include "common.h"
25 #include "popen.h"
26 #include "utils.h"
28 void
29 print_usage (void)
30 {
31         printf (_("\
32 Usage: %s -F <status log file> -e <expire_minutes> -C <process_string>\n"),
33                 progname);
34 }
36 void
37 print_help (void)
38 {
39         print_revision (progname, revision);
41         printf (_(COPYRIGHT), copyright, email);
43         printf (_("\
44 This plugin attempts to check the status of the Nagios process on the local\n\
45 machine. The plugin will check to make sure the Nagios status log is no older\n\
46 than the number of minutes specified by the <expire_minutes> option.  It also\n\
47 uses the /bin/ps command to check for a process matching whatever you specify\n\
48 by the <process_string> argument.\n"));
50         print_usage ();
52         printf (_(UT_HELP_VRSN));
54         printf (_("\
55 -F, --filename=FILE\n\
56    Name of the log file to check\n\
57 -e, --expires=INTEGER\n\
58    Seconds aging afterwhich logfile is condsidered stale\n\
59 -C, --command=STRING\n\
60    Command to search for in process table\n"));
62         printf (_("\
63 Example:\n\
64    ./check_nagios -e 5 \\\
65    -F /usr/local/nagios/var/status.log \\\
66    -C /usr/local/nagios/bin/nagios\n"));
67 }
68 \f
69 int process_arguments (int, char **);
71 char *status_log = NULL;
72 char *process_string = NULL;
73 int expire_minutes = 0;
75 int verbose = 0;
77 int
78 main (int argc, char **argv)
79 {
80         int result = STATE_UNKNOWN;
81         char input_buffer[MAX_INPUT_BUFFER];
82         unsigned long latest_entry_time = 0L;
83         unsigned long temp_entry_time = 0L;
84         int proc_entries = 0;
85         time_t current_time;
86         char *temp_ptr;
87         FILE *fp;
88         int procuid = 0;
89         int procppid = 0;
90         int procvsz = 0;
91         int procrss = 0;
92         float procpcpu = 0;
93         char procstat[8];
94         char procprog[MAX_INPUT_BUFFER];
95         char *procargs;
96         int pos, cols;
98         if (process_arguments (argc, argv) == ERROR)
99                 usage (_("Could not parse arguments\n"));
101         /* Set signal handling and alarm */
102         if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
103                 printf (_("Cannot catch SIGALRM"));
104                 return STATE_UNKNOWN;
105         }
107         /* handle timeouts gracefully... */
108         alarm (timeout_interval);
110         /* open the status log */
111         fp = fopen (status_log, "r");
112         if (fp == NULL) {
113                 printf (_("Error: Cannot open status log for reading!\n"));
114                 return STATE_CRITICAL;
115         }
117         /* get the date/time of the last item updated in the log */
118         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
119                 temp_ptr = strtok (input_buffer, "]");
120                 temp_entry_time =
121                         (temp_ptr == NULL) ? 0L : strtoul (temp_ptr + 1, NULL, 10);
122                 if (temp_entry_time > latest_entry_time)
123                         latest_entry_time = temp_entry_time;
124         }
125         fclose (fp);
127         /* run the command to check for the Nagios process.. */
128         child_process = spopen (PS_COMMAND);
129         if (child_process == NULL) {
130                 printf (_("Could not open pipe: %s\n"), PS_COMMAND);
131                 return STATE_UNKNOWN;
132         }
134         child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
135         if (child_stderr == NULL) {
136                 printf (_("Could not open stderr for %s\n"), PS_COMMAND);
137         }
139         fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
141         /* count the number of matching Nagios processes... */
142         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
143                 cols = sscanf (input_buffer, PS_FORMAT, PS_VARLIST);
144                 if ( cols >= 6 ) {
145                         asprintf (&procargs, "%s", input_buffer + pos);
146                         strip (procargs);
147                         
148                         if (!strstr(procargs, argv[0]) && strstr(procargs, process_string)) {
149                                 proc_entries++;
150                                 if (verbose)
151                                         printf (_("Found process: %s\n"), procargs);
152                         }
153                 }
154         }
156         /* If we get anything on stderr, at least set warning */
157         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
158                 result = max_state (result, STATE_WARNING);
160         /* close stderr */
161         (void) fclose (child_stderr);
163         /* close the pipe */
164         if (spclose (child_process))
165                 result = max_state (result, STATE_WARNING);
167         /* reset the alarm handler */
168         alarm (0);
170         if (proc_entries == 0) {
171                 printf (_("Could not locate a running Nagios process!\n"));
172                 return STATE_CRITICAL;
173         }
175         result = STATE_OK;
177         time (&current_time);
178         if ((int)(current_time - latest_entry_time) > (expire_minutes * 60))
179                 result = STATE_WARNING;
181         printf
182                 (_("Nagios %s: located %d process%s, status log updated %d second%s ago\n"),
183                  (result == STATE_OK) ? "ok" : "problem", proc_entries,
184                  (proc_entries == 1) ? "" : "es",
185                  (int) (current_time - latest_entry_time),
186                  ((int) (current_time - latest_entry_time) == 1) ? "" : "s");
188         return result;
195 /* process command-line arguments */
196 int
197 process_arguments (int argc, char **argv)
199         int c;
201         int option_index = 0;
202         static struct option long_options[] = {
203                 {"filename", required_argument, 0, 'F'},
204                 {"expires", required_argument, 0, 'e'},
205                 {"command", required_argument, 0, 'C'},
206                 {"version", no_argument, 0, 'V'},
207                 {"help", no_argument, 0, 'h'},
208                 {"verbose", no_argument, 0, 'v'},
209                 {0, 0, 0, 0}
210         };
212         if (argc < 2)
213                 return ERROR;
215         if (!is_option (argv[1])) {
216                 status_log = argv[1];
217                 if (is_intnonneg (argv[2]))
218                         expire_minutes = atoi (argv[2]);
219                 else
220                         terminate (STATE_UNKNOWN,
221                                                                  _("Expiration time must be an integer (seconds)\nType '%s -h' for additional help\n"),
222                                                                  progname);
223                 process_string = argv[3];
224                 return OK;
225         }
227         while (1) {
228                 c = getopt_long (argc, argv, "+hVvF:C:e:", long_options, &option_index);
230                 if (c == -1 || c == EOF || c == 1)
231                         break;
233                 switch (c) {
234                 case '?':                                                                       /* print short usage statement if args not parsable */
235                         printf (_("%s: Unknown argument: %c\n\n"), progname, optopt);
236                         print_usage ();
237                         exit (STATE_UNKNOWN);
238                 case 'h':                                                                       /* help */
239                         print_help ();
240                         exit (STATE_OK);
241                 case 'V':                                                                       /* version */
242                         print_revision (progname, "$Revision$");
243                         exit (STATE_OK);
244                 case 'F':                                                                       /* status log */
245                         status_log = optarg;
246                         break;
247                 case 'C':                                                                       /* command */
248                         process_string = optarg;
249                         break;
250                 case 'e':                                                                       /* expiry time */
251                         if (is_intnonneg (optarg))
252                                 expire_minutes = atoi (optarg);
253                         else
254                                 terminate (STATE_UNKNOWN,
255                                                                          _("Expiration time must be an integer (seconds)\nType '%s -h' for additional help\n"),
256                                                                          progname);
257                         break;
258                 case 'v':
259                         verbose++;
260                         break;
261                 }
262         }
265         if (status_log == NULL)
266                 terminate (STATE_UNKNOWN,
267                                                          _("You must provide the status_log\nType '%s -h' for additional help\n"),
268                                                          progname);
269         else if (process_string == NULL)
270                 terminate (STATE_UNKNOWN,
271                                                          _("You must provide a process string\nType '%s -h' for additional help\n"),
272                                                          progname);
274         return OK;