Code

Remove getopt_long checks
[nagiosplug.git] / plugins / check_mrtg.c
1 /******************************************************************************
2  *
3  * Program: MRTG (Multi-Router Traffic Grapher) generic plugin for Nagios
4  * License: GPL
5  *
6  * License Information:
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  *
24  *****************************************************************************/
26 const char *progname = "check_mrtg";
27 #define REVISION "$Revision$"
28 #define COPYRIGHT "Copyright (c) 1999-2001 Ethan Galstad"
30 #define SUMMARY "\
31 This plugin will check either the average or maximum value of one of the\n\
32 two variables recorded in an MRTG log file.\n"
34 /* old command line: 
35          <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
36 #define OPTIONS "\
37 -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n\
38             [-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]"
40 #define LONGOPTIONS "\
41  -F, --logfile=FILE\n\
42    The MRTG log file containing the data you want to monitor\n\
43  -e, --expires=MINUTES\n\
44    Minutes before MRTG data is considered to be too old\n\
45  -a, --aggregation=AVG|MAX\n\
46    Should we check average or maximum values?\n\
47  -v, --variable=INTEGER\n\
48    Which variable set should we inspect? 1 or 2?\n\
49  -w, --warning=INTEGER\n\
50    Threshold value for data to result in WARNING status\n\
51  -c, --critical=INTEGER\n\
52    Threshold value for data to result in CRITICAL status\n\
53  -l, --label=STRING\n\
54    Type label for data (Examples: Conns, \"Processor Load\", In, Out)\n\
55  -u, --units=STRING\n\
56    Option units label for data (Example: Packets/Sec, Errors/Sec, \n\
57    \"Bytes Per Second\", \"%% Utilization\")\n\
58  -h, --help\n\
59    Print detailed help screen\n\
60  -V, --version\n\
61    Print version information\n"
63 #define DESCRIPTION "\
64 If the value exceeds the <vwl> threshold, a WARNING status is returned.  If\n\
65 the value exceeds the <vcl> threshold, a CRITICAL status is returned.  If\n\
66 the data in the log file is older than <expire_minutes> old, a WARNING\n\
67 status is returned and a warning message is printed.\n\
68 \n\
69 This plugin is useful for monitoring MRTG data that does not correspond to\n\
70 bandwidth usage.  (Use the check_mrtgtraf plugin for monitoring bandwidth).\n\
71 It can be used to monitor any kind of data that MRTG is monitoring - errors,\n\
72 packets/sec, etc.  I use MRTG in conjuction with the Novell NLM that allows\n\
73 me to track processor utilization, user connections, drive space, etc and\n\
74 this plugin works well for monitoring that kind of data as well.\n\
75 \n\
76 Notes:\n\
77 - This plugin only monitors one of the two variables stored in the MRTG log\n\
78   file.  If you want to monitor both values you will have to define two\n\
79   commands with different values for the <variable> argument.  Of course,\n\
80   you can always hack the code to make this plugin work for you...\n\
81 - MRTG stands for the Multi Router Traffic Grapher.  It can be downloaded from\n\
82   http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html\n"
84 #include "config.h"
85 #include "common.h"
86 #include "utils.h"
88 int process_arguments (int, char **);
89 int validate_arguments (void);
90 void print_help (void);
91 void print_usage (void);
93 char *log_file = NULL;
94 int expire_minutes = 0;
95 int use_average = TRUE;
96 int variable_number = -1;
97 unsigned long value_warning_threshold = 0L;
98 unsigned long value_critical_threshold = 0L;
99 char *value_label = "";
100 char *units_label = "";
102 int
103 main (int argc, char **argv)
105         int result = STATE_OK;
106         FILE *fp;
107         int line;
108         char input_buffer[MAX_INPUT_BUFFER];
109         char *temp_buffer;
110         time_t current_time;
111         char error_message[MAX_INPUT_BUFFER];
112         time_t timestamp = 0L;
113         unsigned long average_value_rate = 0L;
114         unsigned long maximum_value_rate = 0L;
115         unsigned long value_rate = 0L;
117         if (process_arguments (argc, argv) != OK)
118                 usage ("Invalid command arguments supplied\n");
120         /* open the MRTG log file for reading */
121         fp = fopen (log_file, "r");
122         if (fp == NULL) {
123                 printf ("Unable to open MRTG log file\n");
124                 return STATE_UNKNOWN;
125         }
127         line = 0;
128         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
130                 line++;
132                 /* skip the first line of the log file */
133                 if (line == 1)
134                         continue;
136                 /* break out of read loop if we've passed the number of entries we want to read */
137                 if (line > 2)
138                         break;
140                 /* grab the timestamp */
141                 temp_buffer = strtok (input_buffer, " ");
142                 timestamp = strtoul (temp_buffer, NULL, 10);
144                 /* grab the average value 1 rate */
145                 temp_buffer = strtok (NULL, " ");
146                 if (variable_number == 1)
147                         average_value_rate = strtoul (temp_buffer, NULL, 10);
149                 /* grab the average value 2 rate */
150                 temp_buffer = strtok (NULL, " ");
151                 if (variable_number == 2)
152                         average_value_rate = strtoul (temp_buffer, NULL, 10);
154                 /* grab the maximum value 1 rate */
155                 temp_buffer = strtok (NULL, " ");
156                 if (variable_number == 1)
157                         maximum_value_rate = strtoul (temp_buffer, NULL, 10);
159                 /* grab the maximum value 2 rate */
160                 temp_buffer = strtok (NULL, " ");
161                 if (variable_number == 2)
162                         maximum_value_rate = strtoul (temp_buffer, NULL, 10);
163         }
165         /* close the log file */
166         fclose (fp);
168         /* if we couldn't read enough data, return an unknown error */
169         if (line <= 2) {
170                 result = STATE_UNKNOWN;
171                 sprintf (error_message, "Unable to process MRTG log file\n");
172         }
174         /* make sure the MRTG data isn't too old */
175         if (result == STATE_OK) {
176                 time (&current_time);
177                 if (expire_minutes > 0
178                                 && (current_time - timestamp) > (expire_minutes * 60)) {
179                         result = STATE_WARNING;
180                         sprintf (error_message, "MRTG data has expired (%d minutes old)\n",
181                                                          (int) ((current_time - timestamp) / 60));
182                 }
183         }
185         /* else check the incoming/outgoing rates */
186         if (result == STATE_OK) {
188                 if (use_average == TRUE)
189                         value_rate = average_value_rate;
190                 else
191                         value_rate = maximum_value_rate;
193                 if (value_rate > value_critical_threshold)
194                         result = STATE_CRITICAL;
195                 else if (value_rate > value_warning_threshold)
196                         result = STATE_WARNING;
197         }
199         sprintf (error_message, "%s. %s = %lu %s",
200                                          (use_average == TRUE) ? "Ave" : "Max", value_label, value_rate,
201                                          units_label);
202         printf ("%s\n", error_message);
204         return result;
211 /* process command-line arguments */
212 int
213 process_arguments (int argc, char **argv)
215         int c;
217         int option_index = 0;
218         static struct option long_options[] = {
219                 {"logfile", required_argument, 0, 'F'},
220                 {"expires", required_argument, 0, 'e'},
221                 {"aggregation", required_argument, 0, 'a'},
222                 {"variable", required_argument, 0, 'v'},
223                 {"critical", required_argument, 0, 'c'},
224                 {"warning", required_argument, 0, 'w'},
225                 {"label", required_argument, 0, 'l'},
226                 {"units", required_argument, 0, 'u'},
227                 {"verbose", no_argument, 0, 'v'},
228                 {"version", no_argument, 0, 'V'},
229                 {"help", no_argument, 0, 'h'},
230                 {0, 0, 0, 0}
231         };
233         if (argc < 2)
234                 return ERROR;
236         for (c = 1; c < argc; c++) {
237                 if (strcmp ("-to", argv[c]) == 0)
238                         strcpy (argv[c], "-t");
239                 else if (strcmp ("-wt", argv[c]) == 0)
240                         strcpy (argv[c], "-w");
241                 else if (strcmp ("-ct", argv[c]) == 0)
242                         strcpy (argv[c], "-c");
243         }
245         while (1) {
246                 c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", long_options,
247                                                                          &option_index);
249                 if (c == -1 || c == EOF)
250                         break;
252                 switch (c) {
253                 case 'F':                                                                       /* input file */
254                         log_file = optarg;
255                         break;
256                 case 'e':                                                                       /* ups name */
257                         expire_minutes = atoi (optarg);
258                         break;
259                 case 'a':                                                                       /* port */
260                         if (!strcmp (optarg, "MAX"))
261                                 use_average = FALSE;
262                         else
263                                 use_average = TRUE;
264                         break;
265                 case 'v':
266                         variable_number = atoi (optarg);
267                         if (variable_number < 1 || variable_number > 2)
268                                 usage ("Invalid variable number\n");
269                         break;
270                 case 'w':                                                                       /* critical time threshold */
271                         value_warning_threshold = strtoul (optarg, NULL, 10);
272                         break;
273                 case 'c':                                                                       /* warning time threshold */
274                         value_critical_threshold = strtoul (optarg, NULL, 10);
275                         break;
276                 case 'l':                                                                       /* label */
277                         value_label = optarg;
278                         break;
279                 case 'u':                                                                       /* timeout */
280                         units_label = optarg;
281                         break;
282                 case 'V':                                                                       /* version */
283                         print_revision (progname, REVISION);
284                         exit (STATE_OK);
285                 case 'h':                                                                       /* help */
286                         print_help ();
287                         exit (STATE_OK);
288                 case '?':                                                                       /* help */
289                         usage ("Invalid argument\n");
290                 }
291         }
293         c = optind;
294         if (log_file == NULL && argc > c) {
295                 log_file = argv[c++];
296         }
298         if (expire_minutes <= 0 && argc > c) {
299                 if (is_intpos (argv[c]))
300                         expire_minutes = atoi (argv[c++]);
301                 else
302                         terminate (STATE_UNKNOWN,
303                                    "%s is not a valid expiration time\nUse '%s -h' for additional help\n",
304                                    argv[c], progname);
305         }
307         if (argc > c && strcmp (argv[c], "MAX") == 0) {
308                 use_average = FALSE;
309                 c++;
310         }
311         else if (argc > c && strcmp (argv[c], "AVG") == 0) {
312                 use_average = TRUE;
313                 c++;
314         }
316         if (argc > c && variable_number == -1) {
317                 variable_number = atoi (argv[c++]);
318                 if (variable_number < 1 || variable_number > 2) {
319                         printf ("%s :", argv[c]);
320                         usage ("Invalid variable number\n");
321                 }
322         }
324         if (argc > c && value_warning_threshold == 0) {
325                 value_warning_threshold = strtoul (argv[c++], NULL, 10);
326         }
328         if (argc > c && value_critical_threshold == 0) {
329                 value_critical_threshold = strtoul (argv[c++], NULL, 10);
330         }
332         if (argc > c && strlen (value_label) == 0) {
333                 value_label = argv[c++];
334         }
336         if (argc > c && strlen (units_label) == 0) {
337                 units_label = argv[c++];
338         }
340         return validate_arguments ();
343 int
344 validate_arguments (void)
346         if (variable_number == -1)
347                 usage ("You must supply the variable number\n");
349         return OK;
352 void
353 print_help (void)
355         print_revision (progname, REVISION);
356         printf ("%s\n\n%s\n", COPYRIGHT, SUMMARY);
357         print_usage ();
358         printf ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n");
359         support ();
362 void
363 print_usage (void)
365         printf ("Usage:\n" " %s %s\n"
366                                         " %s (-h | --help) for detailed help\n"
367                                         " %s (-V | --version) for version information\n",
368                                         progname, OPTIONS, progname, progname);