Code

reverting my changes from !=TRUE to == ERROR, that's not good ;-( sorry
[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  $Id$
18  
19 ******************************************************************************/
21 const char *progname = "check_mrtg";
22 const char *revision =  "$Revision$";
23 const char *copyright = "1999-2004";
24 const char *email = "nagiosplug-devel@lists.sourceforge.net";
26 #include "common.h"
27 #include "utils.h"
29 int process_arguments (int, char **);
30 int validate_arguments (void);
31 void print_help (void);
32 void print_usage (void);
34 char *log_file = NULL;
35 int expire_minutes = 0;
36 int use_average = TRUE;
37 int variable_number = -1;
38 unsigned long value_warning_threshold = 0L;
39 unsigned long value_critical_threshold = 0L;
40 char *label;
41 char *units;
43 int
44 main (int argc, char **argv)
45 {
46         int result = STATE_UNKNOWN;
47         FILE *fp;
48         int line;
49         char input_buffer[MAX_INPUT_BUFFER];
50         char *temp_buffer;
51         time_t current_time;
52         char* message;
53         time_t timestamp = 0L;
54         unsigned long average_value_rate = 0L;
55         unsigned long maximum_value_rate = 0L;
56         unsigned long rate = 0L;
58         setlocale (LC_ALL, "");
59         bindtextdomain (PACKAGE, LOCALEDIR);
60         textdomain (PACKAGE);
62         if (process_arguments (argc, argv) == ERROR)
63                 usage4 (_("Could not parse arguments\n"));
65         /* open the MRTG log file for reading */
66         fp = fopen (log_file, "r");
67         if (fp == NULL) {
68                 printf (_("Unable to open MRTG log file\n"));
69                 return STATE_UNKNOWN;
70         }
72         line = 0;
73         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
75                 line++;
77                 /* skip the first line of the log file */
78                 if (line == 1)
79                         continue;
81                 /* break out of read loop if we've passed the number of entries we want to read */
82                 if (line > 2)
83                         break;
85                 /* grab the timestamp */
86                 temp_buffer = strtok (input_buffer, " ");
87                 timestamp = strtoul (temp_buffer, NULL, 10);
89                 /* grab the average value 1 rate */
90                 temp_buffer = strtok (NULL, " ");
91                 if (variable_number == 1)
92                         average_value_rate = strtoul (temp_buffer, NULL, 10);
94                 /* grab the average value 2 rate */
95                 temp_buffer = strtok (NULL, " ");
96                 if (variable_number == 2)
97                         average_value_rate = strtoul (temp_buffer, NULL, 10);
99                 /* grab the maximum value 1 rate */
100                 temp_buffer = strtok (NULL, " ");
101                 if (variable_number == 1)
102                         maximum_value_rate = strtoul (temp_buffer, NULL, 10);
104                 /* grab the maximum value 2 rate */
105                 temp_buffer = strtok (NULL, " ");
106                 if (variable_number == 2)
107                         maximum_value_rate = strtoul (temp_buffer, NULL, 10);
108         }
110         /* close the log file */
111         fclose (fp);
113         /* if we couldn't read enough data, return an unknown error */
114         if (line <= 2) {
115                 result = STATE_UNKNOWN;
116                 asprintf (&message, _("Unable to process MRTG log file\n"));
117         }
119         /* make sure the MRTG data isn't too old */
120         if (result == STATE_OK) {
121                 time (&current_time);
122                 if (expire_minutes > 0
123                                 && (current_time - timestamp) > (expire_minutes * 60)) {
124                         result = STATE_WARNING;
125                         asprintf (&message, _("MRTG data has expired (%d minutes old)\n"),
126                                                          (int) ((current_time - timestamp) / 60));
127                 }
128         }
130         /* else check the incoming/outgoing rates */
131         if (result == STATE_OK) {
132                 if (use_average == TRUE)
133                         rate = average_value_rate;
134                 else
135                         rate = maximum_value_rate;
137                 if (rate > value_critical_threshold)
138                         result = STATE_CRITICAL;
139                 else if (rate > value_warning_threshold)
140                         result = STATE_WARNING;
142                 asprintf (&message, "%s. %s = %lu %s|%s",
143                           (use_average == TRUE) ? _("Avg") : _("Max"),
144                           label, rate, units,
145                           perfdata(label, (long) rate, units,
146                                    (int) value_warning_threshold, (long) value_warning_threshold,
147                                    (int) value_critical_threshold, (long) value_critical_threshold,
148                                    0, 0, 0, 0));
149         }
151         printf ("%s\n", message);
153         return result;
158 /* process command-line arguments */
159 int
160 process_arguments (int argc, char **argv)
162         int c;
164         int option = 0;
165         static struct option longopts[] = {
166                 {"logfile", required_argument, 0, 'F'},
167                 {"expires", required_argument, 0, 'e'},
168                 {"aggregation", required_argument, 0, 'a'},
169                 {"variable", required_argument, 0, 'v'},
170                 {"critical", required_argument, 0, 'c'},
171                 {"warning", required_argument, 0, 'w'},
172                 {"label", required_argument, 0, 'l'},
173                 {"units", required_argument, 0, 'u'},
174                 {"verbose", no_argument, 0, 'v'},
175                 {"version", no_argument, 0, 'V'},
176                 {"help", no_argument, 0, 'h'},
177                 {0, 0, 0, 0}
178         };
180         if (argc < 2)
181                 return ERROR;
183         for (c = 1; c < argc; c++) {
184                 if (strcmp ("-to", argv[c]) == 0)
185                         strcpy (argv[c], "-t");
186                 else if (strcmp ("-wt", argv[c]) == 0)
187                         strcpy (argv[c], "-w");
188                 else if (strcmp ("-ct", argv[c]) == 0)
189                         strcpy (argv[c], "-c");
190         }
192         while (1) {
193                 c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", longopts,
194                                                                          &option);
196                 if (c == -1 || c == EOF)
197                         break;
199                 switch (c) {
200                 case 'F':                                                                       /* input file */
201                         log_file = optarg;
202                         break;
203                 case 'e':                                                                       /* ups name */
204                         expire_minutes = atoi (optarg);
205                         break;
206                 case 'a':                                                                       /* port */
207                         if (!strcmp (optarg, "MAX"))
208                                 use_average = FALSE;
209                         else
210                                 use_average = TRUE;
211                         break;
212                 case 'v':
213                         variable_number = atoi (optarg);
214                         if (variable_number < 1 || variable_number > 2)
215                                 usage4 (_("Invalid variable number"));
216                         break;
217                 case 'w':                                                                       /* critical time threshold */
218                         value_warning_threshold = strtoul (optarg, NULL, 10);
219                         break;
220                 case 'c':                                                                       /* warning time threshold */
221                         value_critical_threshold = strtoul (optarg, NULL, 10);
222                         break;
223                 case 'l':                                                                       /* label */
224                         label = optarg;
225                         break;
226                 case 'u':                                                                       /* timeout */
227                         units = optarg;
228                         break;
229                 case 'V':                                                                       /* version */
230                         print_revision (progname, revision);
231                         exit (STATE_OK);
232                 case 'h':                                                                       /* help */
233                         print_help ();
234                         exit (STATE_OK);
235                 case '?':                                                                       /* help */
236                         printf (_("%s: Unknown argument: %s\n\n"), progname, optarg);
237                         print_usage ();
238                         exit (STATE_UNKNOWN);
239                 }
240         }
242         c = optind;
243         if (log_file == NULL && argc > c) {
244                 log_file = argv[c++];
245         }
247         if (expire_minutes <= 0 && argc > c) {
248                 if (is_intpos (argv[c]))
249                         expire_minutes = atoi (argv[c++]);
250                 else
251                         die (STATE_UNKNOWN,
252                                    _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
253                                    argv[c], progname);
254         }
256         if (argc > c && strcmp (argv[c], "MAX") == 0) {
257                 use_average = FALSE;
258                 c++;
259         }
260         else if (argc > c && strcmp (argv[c], "AVG") == 0) {
261                 use_average = TRUE;
262                 c++;
263         }
265         if (argc > c && variable_number == -1) {
266                 variable_number = atoi (argv[c++]);
267                 if (variable_number < 1 || variable_number > 2) {
268                         printf ("%s :", argv[c]);
269                         usage (_("Invalid variable number\n"));
270                 }
271         }
273         if (argc > c && value_warning_threshold == 0) {
274                 value_warning_threshold = strtoul (argv[c++], NULL, 10);
275         }
277         if (argc > c && value_critical_threshold == 0) {
278                 value_critical_threshold = strtoul (argv[c++], NULL, 10);
279         }
281         if (argc > c && strlen (label) == 0) {
282                 label = argv[c++];
283         }
285         if (argc > c && strlen (units) == 0) {
286                 units = argv[c++];
287         }
289         return validate_arguments ();
292 int
293 validate_arguments (void)
295         if (variable_number == -1)
296                 usage4 (_("You must supply the variable number"));
298         if (label == NULL)
299                 label = strdup ("value");
301         if (units == NULL)
302                 units = strdup ("");
304         return OK;
309 void
310 print_help (void)
312         print_revision (progname, revision);
314         printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
315         printf (COPYRIGHT, copyright, email);
317         printf(_("\
318 This plugin will check either the average or maximum value of one of the\n\
319 two variables recorded in an MRTG log file.\n\n"));
321         print_usage ();
323         printf (_(UT_HELP_VRSN));
325         printf (_("\
326  -F, --logfile=FILE\n\
327    The MRTG log file containing the data you want to monitor\n\
328  -e, --expires=MINUTES\n\
329    Minutes before MRTG data is considered to be too old\n\
330  -a, --aggregation=AVG|MAX\n\
331    Should we check average or maximum values?\n\
332  -v, --variable=INTEGER\n\
333    Which variable set should we inspect? (1 or 2)\n\
334  -w, --warning=INTEGER\n\
335    Threshold value for data to result in WARNING status\n\
336  -c, --critical=INTEGER\n\
337    Threshold value for data to result in CRITICAL status\n"));
339         printf (_("\
340  -l, --label=STRING\n\
341    Type label for data (Examples: Conns, \"Processor Load\", In, Out)\n\
342  -u, --units=STRING\n\
343    Option units label for data (Example: Packets/Sec, Errors/Sec, \n\
344    \"Bytes Per Second\", \"%% Utilization\")\n"));
346         printf (_("\
347 If the value exceeds the <vwl> threshold, a WARNING status is returned.  If\n\
348 the value exceeds the <vcl> threshold, a CRITICAL status is returned.  If\n\
349 the data in the log file is older than <expire_minutes> old, a WARNING\n\
350 status is returned and a warning message is printed.\n\n"));
352         printf(_("This plugin is useful for monitoring MRTG data that does not correspond to\n\
353 bandwidth usage.  (Use the check_mrtgtraf plugin for monitoring bandwidth).\n\
354 It can be used to monitor any kind of data that MRTG is monitoring - errors,\n\
355 packets/sec, etc.  I use MRTG in conjuction with the Novell NLM that allows\n\
356 me to track processor utilization, user connections, drive space, etc and\n\
357 this plugin works well for monitoring that kind of data as well.\n\n"));
359         printf (_("Notes:\n\
360 - This plugin only monitors one of the two variables stored in the MRTG log\n\
361   file.  If you want to monitor both values you will have to define two\n\
362   commands with different values for the <variable> argument.  Of course,\n\
363   you can always hack the code to make this plugin work for you...\n\
364 - MRTG stands for the Multi Router Traffic Grapher.  It can be downloaded from\n\
365   http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html\n"));
367         printf (_(UT_SUPPORT));
372 /* original command line: 
373          <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
375 void
376 print_usage (void)
378         printf ("\
379 Usage: %s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n\
380                   [-l label] [-u units] [-e expire_minutes] [-t timeout]\n\
381                                                                         [-v]\n", progname);