Code

- bindtextdomain for gettext, a few other smale cleanups here and there
[nagiosplug.git] / plugins / check_mrtg.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_mrtg";
20 const char *revision =  "$Revision$";
21 const char *copyright = "1999-2001";
22 const char *email = "nagiosplug-devel@lists.sourceforge.net";
24 #include "common.h"
25 #include "utils.h"
27 int process_arguments (int, char **);
28 int validate_arguments (void);
29 void print_help (void);
30 void print_usage (void);
32 char *log_file = NULL;
33 int expire_minutes = 0;
34 int use_average = TRUE;
35 int variable_number = -1;
36 unsigned long value_warning_threshold = 0L;
37 unsigned long value_critical_threshold = 0L;
38 char *value_label;
39 char *units_label;
41 int
42 main (int argc, char **argv)
43 {
44         int result = STATE_OK;
45         FILE *fp;
46         int line;
47         char input_buffer[MAX_INPUT_BUFFER];
48         char *temp_buffer;
49         time_t current_time;
50         char error_message[MAX_INPUT_BUFFER];
51         time_t timestamp = 0L;
52         unsigned long average_value_rate = 0L;
53         unsigned long maximum_value_rate = 0L;
54         unsigned long value_rate = 0L;
56         setlocale (LC_ALL, "");
57         bindtextdomain (PACKAGE, LOCALEDIR);
58         textdomain (PACKAGE);
60         if (process_arguments (argc, argv) != OK)
61                 usage (_("Invalid command arguments supplied\n"));
63         /* open the MRTG log file for reading */
64         fp = fopen (log_file, "r");
65         if (fp == NULL) {
66                 printf (_("Unable to open MRTG log file\n"));
67                 return STATE_UNKNOWN;
68         }
70         line = 0;
71         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
73                 line++;
75                 /* skip the first line of the log file */
76                 if (line == 1)
77                         continue;
79                 /* break out of read loop if we've passed the number of entries we want to read */
80                 if (line > 2)
81                         break;
83                 /* grab the timestamp */
84                 temp_buffer = strtok (input_buffer, " ");
85                 timestamp = strtoul (temp_buffer, NULL, 10);
87                 /* grab the average value 1 rate */
88                 temp_buffer = strtok (NULL, " ");
89                 if (variable_number == 1)
90                         average_value_rate = strtoul (temp_buffer, NULL, 10);
92                 /* grab the average value 2 rate */
93                 temp_buffer = strtok (NULL, " ");
94                 if (variable_number == 2)
95                         average_value_rate = strtoul (temp_buffer, NULL, 10);
97                 /* grab the maximum value 1 rate */
98                 temp_buffer = strtok (NULL, " ");
99                 if (variable_number == 1)
100                         maximum_value_rate = strtoul (temp_buffer, NULL, 10);
102                 /* grab the maximum value 2 rate */
103                 temp_buffer = strtok (NULL, " ");
104                 if (variable_number == 2)
105                         maximum_value_rate = strtoul (temp_buffer, NULL, 10);
106         }
108         /* close the log file */
109         fclose (fp);
111         /* if we couldn't read enough data, return an unknown error */
112         if (line <= 2) {
113                 result = STATE_UNKNOWN;
114                 sprintf (error_message, _("Unable to process MRTG log file\n"));
115         }
117         /* make sure the MRTG data isn't too old */
118         if (result == STATE_OK) {
119                 time (&current_time);
120                 if (expire_minutes > 0
121                                 && (current_time - timestamp) > (expire_minutes * 60)) {
122                         result = STATE_WARNING;
123                         sprintf (error_message, _("MRTG data has expired (%d minutes old)\n"),
124                                                          (int) ((current_time - timestamp) / 60));
125                 }
126         }
128         /* else check the incoming/outgoing rates */
129         if (result == STATE_OK) {
131                 if (use_average == TRUE)
132                         value_rate = average_value_rate;
133                 else
134                         value_rate = maximum_value_rate;
136                 if (value_rate > value_critical_threshold)
137                         result = STATE_CRITICAL;
138                 else if (value_rate > value_warning_threshold)
139                         result = STATE_WARNING;
140         }
142         sprintf (error_message, "%s. %s = %lu %s",
143                                          (use_average == TRUE) ? _("Ave") : _("Max"), value_label, value_rate,
144                                          units_label);
145         printf ("%s\n", error_message);
147         return result;
149 \f
150 /* process command-line arguments */
151 int
152 process_arguments (int argc, char **argv)
154         int c;
156         int option = 0;
157         static struct option longopts[] = {
158                 {"logfile", required_argument, 0, 'F'},
159                 {"expires", required_argument, 0, 'e'},
160                 {"aggregation", required_argument, 0, 'a'},
161                 {"variable", required_argument, 0, 'v'},
162                 {"critical", required_argument, 0, 'c'},
163                 {"warning", required_argument, 0, 'w'},
164                 {"label", required_argument, 0, 'l'},
165                 {"units", required_argument, 0, 'u'},
166                 {"verbose", no_argument, 0, 'v'},
167                 {"version", no_argument, 0, 'V'},
168                 {"help", no_argument, 0, 'h'},
169                 {0, 0, 0, 0}
170         };
172         if (argc < 2)
173                 return ERROR;
175         for (c = 1; c < argc; c++) {
176                 if (strcmp ("-to", argv[c]) == 0)
177                         strcpy (argv[c], "-t");
178                 else if (strcmp ("-wt", argv[c]) == 0)
179                         strcpy (argv[c], "-w");
180                 else if (strcmp ("-ct", argv[c]) == 0)
181                         strcpy (argv[c], "-c");
182         }
184         while (1) {
185                 c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", longopts,
186                                                                          &option);
188                 if (c == -1 || c == EOF)
189                         break;
191                 switch (c) {
192                 case 'F':                                                                       /* input file */
193                         log_file = optarg;
194                         break;
195                 case 'e':                                                                       /* ups name */
196                         expire_minutes = atoi (optarg);
197                         break;
198                 case 'a':                                                                       /* port */
199                         if (!strcmp (optarg, "MAX"))
200                                 use_average = FALSE;
201                         else
202                                 use_average = TRUE;
203                         break;
204                 case 'v':
205                         variable_number = atoi (optarg);
206                         if (variable_number < 1 || variable_number > 2)
207                                 usage (_("Invalid variable number\n"));
208                         break;
209                 case 'w':                                                                       /* critical time threshold */
210                         value_warning_threshold = strtoul (optarg, NULL, 10);
211                         break;
212                 case 'c':                                                                       /* warning time threshold */
213                         value_critical_threshold = strtoul (optarg, NULL, 10);
214                         break;
215                 case 'l':                                                                       /* label */
216                         value_label = optarg;
217                         break;
218                 case 'u':                                                                       /* timeout */
219                         units_label = optarg;
220                         break;
221                 case 'V':                                                                       /* version */
222                         print_revision (progname, revision);
223                         exit (STATE_OK);
224                 case 'h':                                                                       /* help */
225                         print_help ();
226                         exit (STATE_OK);
227                 case '?':                                                                       /* help */
228                         usage (_("Invalid argument\n"));
229                 }
230         }
232         c = optind;
233         if (log_file == NULL && argc > c) {
234                 log_file = argv[c++];
235         }
237         if (expire_minutes <= 0 && argc > c) {
238                 if (is_intpos (argv[c]))
239                         expire_minutes = atoi (argv[c++]);
240                 else
241                         die (STATE_UNKNOWN,
242                                    _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
243                                    argv[c], progname);
244         }
246         if (argc > c && strcmp (argv[c], "MAX") == 0) {
247                 use_average = FALSE;
248                 c++;
249         }
250         else if (argc > c && strcmp (argv[c], "AVG") == 0) {
251                 use_average = TRUE;
252                 c++;
253         }
255         if (argc > c && variable_number == -1) {
256                 variable_number = atoi (argv[c++]);
257                 if (variable_number < 1 || variable_number > 2) {
258                         printf ("%s :", argv[c]);
259                         usage (_("Invalid variable number\n"));
260                 }
261         }
263         if (argc > c && value_warning_threshold == 0) {
264                 value_warning_threshold = strtoul (argv[c++], NULL, 10);
265         }
267         if (argc > c && value_critical_threshold == 0) {
268                 value_critical_threshold = strtoul (argv[c++], NULL, 10);
269         }
271         if (argc > c && strlen (value_label) == 0) {
272                 value_label = argv[c++];
273         }
275         if (argc > c && strlen (units_label) == 0) {
276                 units_label = argv[c++];
277         }
279         return validate_arguments ();
282 int
283 validate_arguments (void)
285         if (variable_number == -1)
286                 usage (_("You must supply the variable number\n"));
288         if (value_label == NULL)
289                 value_label = strdup ("");
291         if (units_label == NULL)
292                 units_label = strdup ("");
294         return OK;
301 \f
302 void
303 print_help (void)
305         print_revision (progname, revision);
307         printf (_("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"));
308         printf (_(COPYRIGHT), copyright, email);
310         printf(_("\
311 This plugin will check either the average or maximum value of one of the\n\
312 two variables recorded in an MRTG log file.\n"));
314         print_usage ();
316         printf (_(UT_HELP_VRSN));
318         printf (_("\
319  -F, --logfile=FILE\n\
320    The MRTG log file containing the data you want to monitor\n\
321  -e, --expires=MINUTES\n\
322    Minutes before MRTG data is considered to be too old\n\
323  -a, --aggregation=AVG|MAX\n\
324    Should we check average or maximum values?\n\
325  -v, --variable=INTEGER\n\
326    Which variable set should we inspect? (1 or 2)\n\
327  -w, --warning=INTEGER\n\
328    Threshold value for data to result in WARNING status\n\
329  -c, --critical=INTEGER\n\
330    Threshold value for data to result in CRITICAL status\n"));
332         printf (_("\
333  -l, --label=STRING\n\
334    Type label for data (Examples: Conns, \"Processor Load\", In, Out)\n\
335  -u, --units=STRING\n\
336    Option units label for data (Example: Packets/Sec, Errors/Sec, \n\
337    \"Bytes Per Second\", \"%% Utilization\")\n"));
339         printf (_("\
340 If the value exceeds the <vwl> threshold, a WARNING status is returned.  If\n\
341 the value exceeds the <vcl> threshold, a CRITICAL status is returned.  If\n\
342 the data in the log file is older than <expire_minutes> old, a WARNING\n\
343 status is returned and a warning message is printed.\n\n"));
345         printf(_("This plugin is useful for monitoring MRTG data that does not correspond to\n\
346 bandwidth usage.  (Use the check_mrtgtraf plugin for monitoring bandwidth).\n\
347 It can be used to monitor any kind of data that MRTG is monitoring - errors,\n\
348 packets/sec, etc.  I use MRTG in conjuction with the Novell NLM that allows\n\
349 me to track processor utilization, user connections, drive space, etc and\n\
350 this plugin works well for monitoring that kind of data as well.\n\n"));
352         printf (_("Notes:\n\
353 - This plugin only monitors one of the two variables stored in the MRTG log\n\
354   file.  If you want to monitor both values you will have to define two\n\
355   commands with different values for the <variable> argument.  Of course,\n\
356   you can always hack the code to make this plugin work for you...\n\
357 - MRTG stands for the Multi Router Traffic Grapher.  It can be downloaded from\n\
358   http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html\n"));
360         printf (_(UT_SUPPORT));
366 /* original command line: 
367          <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
369 void
370 print_usage (void)
372         printf (_("\
373 Usage: %s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n\
374   [-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n"), progname);
375         printf (_(UT_HLP_VRS), progname, progname);