Code

58717bffe8547194d603d35b1dfb802db99e3ab5
[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-2001";
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_OK;
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) != TRUE)
63                 usage (_("check_mrtg: 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;
155 \f
156 /* process command-line arguments */
157 int
158 process_arguments (int argc, char **argv)
160         int c;
162         int option = 0;
163         static struct option longopts[] = {
164                 {"logfile", required_argument, 0, 'F'},
165                 {"expires", required_argument, 0, 'e'},
166                 {"aggregation", required_argument, 0, 'a'},
167                 {"variable", required_argument, 0, 'v'},
168                 {"critical", required_argument, 0, 'c'},
169                 {"warning", required_argument, 0, 'w'},
170                 {"label", required_argument, 0, 'l'},
171                 {"units", required_argument, 0, 'u'},
172                 {"verbose", no_argument, 0, 'v'},
173                 {"version", no_argument, 0, 'V'},
174                 {"help", no_argument, 0, 'h'},
175                 {0, 0, 0, 0}
176         };
178         if (argc < 2)
179                 return ERROR;
181         for (c = 1; c < argc; c++) {
182                 if (strcmp ("-to", argv[c]) == 0)
183                         strcpy (argv[c], "-t");
184                 else if (strcmp ("-wt", argv[c]) == 0)
185                         strcpy (argv[c], "-w");
186                 else if (strcmp ("-ct", argv[c]) == 0)
187                         strcpy (argv[c], "-c");
188         }
190         while (1) {
191                 c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", longopts,
192                                                                          &option);
194                 if (c == -1 || c == EOF)
195                         break;
197                 switch (c) {
198                 case 'F':                                                                       /* input file */
199                         log_file = optarg;
200                         break;
201                 case 'e':                                                                       /* ups name */
202                         expire_minutes = atoi (optarg);
203                         break;
204                 case 'a':                                                                       /* port */
205                         if (!strcmp (optarg, "MAX"))
206                                 use_average = FALSE;
207                         else
208                                 use_average = TRUE;
209                         break;
210                 case 'v':
211                         variable_number = atoi (optarg);
212                         if (variable_number < 1 || variable_number > 2)
213                                 usage (_("Invalid variable number\n"));
214                         break;
215                 case 'w':                                                                       /* critical time threshold */
216                         value_warning_threshold = strtoul (optarg, NULL, 10);
217                         break;
218                 case 'c':                                                                       /* warning time threshold */
219                         value_critical_threshold = strtoul (optarg, NULL, 10);
220                         break;
221                 case 'l':                                                                       /* label */
222                         label = optarg;
223                         break;
224                 case 'u':                                                                       /* timeout */
225                         units = optarg;
226                         break;
227                 case 'V':                                                                       /* version */
228                         print_revision (progname, revision);
229                         exit (STATE_OK);
230                 case 'h':                                                                       /* help */
231                         print_help ();
232                         exit (STATE_OK);
233                 case '?':                                                                       /* help */
234                         printf (_("%s: Unknown argument: %s\n\n"), progname, optarg);
235                         print_usage ();
236                         exit (STATE_UNKNOWN);
237                 }
238         }
240         c = optind;
241         if (log_file == NULL && argc > c) {
242                 log_file = argv[c++];
243         }
245         if (expire_minutes <= 0 && argc > c) {
246                 if (is_intpos (argv[c]))
247                         expire_minutes = atoi (argv[c++]);
248                 else
249                         die (STATE_UNKNOWN,
250                                    _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
251                                    argv[c], progname);
252         }
254         if (argc > c && strcmp (argv[c], "MAX") == 0) {
255                 use_average = FALSE;
256                 c++;
257         }
258         else if (argc > c && strcmp (argv[c], "AVG") == 0) {
259                 use_average = TRUE;
260                 c++;
261         }
263         if (argc > c && variable_number == -1) {
264                 variable_number = atoi (argv[c++]);
265                 if (variable_number < 1 || variable_number > 2) {
266                         printf ("%s :", argv[c]);
267                         usage (_("Invalid variable number\n"));
268                 }
269         }
271         if (argc > c && value_warning_threshold == 0) {
272                 value_warning_threshold = strtoul (argv[c++], NULL, 10);
273         }
275         if (argc > c && value_critical_threshold == 0) {
276                 value_critical_threshold = strtoul (argv[c++], NULL, 10);
277         }
279         if (argc > c && strlen (label) == 0) {
280                 label = argv[c++];
281         }
283         if (argc > c && strlen (units) == 0) {
284                 units = argv[c++];
285         }
287         return validate_arguments ();
290 int
291 validate_arguments (void)
293         if (variable_number == -1)
294                 usage (_("You must supply the variable number\n"));
296         if (label == NULL)
297                 label = strdup ("value");
299         if (units == NULL)
300                 units = strdup ("");
302         return OK;
309 \f
310 void
311 print_help (void)
313         print_revision (progname, revision);
315         printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
316         printf (COPYRIGHT, copyright, email);
318         printf(_("\
319 This plugin will check either the average or maximum value of one of the\n\
320 two variables recorded in an MRTG log file.\n"));
322         print_usage ();
324         printf (_(UT_HELP_VRSN));
326         printf (_("\
327  -F, --logfile=FILE\n\
328    The MRTG log file containing the data you want to monitor\n\
329  -e, --expires=MINUTES\n\
330    Minutes before MRTG data is considered to be too old\n\
331  -a, --aggregation=AVG|MAX\n\
332    Should we check average or maximum values?\n\
333  -v, --variable=INTEGER\n\
334    Which variable set should we inspect? (1 or 2)\n\
335  -w, --warning=INTEGER\n\
336    Threshold value for data to result in WARNING status\n\
337  -c, --critical=INTEGER\n\
338    Threshold value for data to result in CRITICAL status\n"));
340         printf (_("\
341  -l, --label=STRING\n\
342    Type label for data (Examples: Conns, \"Processor Load\", In, Out)\n\
343  -u, --units=STRING\n\
344    Option units label for data (Example: Packets/Sec, Errors/Sec, \n\
345    \"Bytes Per Second\", \"%% Utilization\")\n"));
347         printf (_("\
348 If the value exceeds the <vwl> threshold, a WARNING status is returned.  If\n\
349 the value exceeds the <vcl> threshold, a CRITICAL status is returned.  If\n\
350 the data in the log file is older than <expire_minutes> old, a WARNING\n\
351 status is returned and a warning message is printed.\n\n"));
353         printf(_("This plugin is useful for monitoring MRTG data that does not correspond to\n\
354 bandwidth usage.  (Use the check_mrtgtraf plugin for monitoring bandwidth).\n\
355 It can be used to monitor any kind of data that MRTG is monitoring - errors,\n\
356 packets/sec, etc.  I use MRTG in conjuction with the Novell NLM that allows\n\
357 me to track processor utilization, user connections, drive space, etc and\n\
358 this plugin works well for monitoring that kind of data as well.\n\n"));
360         printf (_("Notes:\n\
361 - This plugin only monitors one of the two variables stored in the MRTG log\n\
362   file.  If you want to monitor both values you will have to define two\n\
363   commands with different values for the <variable> argument.  Of course,\n\
364   you can always hack the code to make this plugin work for you...\n\
365 - MRTG stands for the Multi Router Traffic Grapher.  It can be downloaded from\n\
366   http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html\n"));
368         printf (_(UT_SUPPORT));
374 /* original command line: 
375          <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
377 void
378 print_usage (void)
380         printf (_("\
381 Usage: %s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n\
382   [-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n"), progname);
383         printf (_(UT_HLP_VRS), progname, progname);