1 /******************************************************************************
2 *
3 * Nagios check_mrtg plugin
4 *
5 * License: GPL
6 * Copyright (c) 1999-2006 nagios-plugins team
7 *
8 * Last Modified: $Date$
9 *
10 * Description:
11 *
12 * This file contains the check_mrtg plugin
13 *
14 * This plugin will check either the average or maximum value of one of the
15 * two variables recorded in an MRTG log file.
16 *
17 *
18 * License Information:
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 $Id$
36 ******************************************************************************/
38 const char *progname = "check_mrtg";
39 const char *revision = "$Revision$";
40 const char *copyright = "1999-2006";
41 const char *email = "nagiosplug-devel@lists.sourceforge.net";
43 #include "common.h"
44 #include "utils.h"
46 int process_arguments (int, char **);
47 int validate_arguments (void);
48 void print_help (void);
49 void print_usage (void);
51 char *log_file = NULL;
52 int expire_minutes = 0;
53 int use_average = TRUE;
54 int variable_number = -1;
55 unsigned long value_warning_threshold = 0L;
56 unsigned long value_critical_threshold = 0L;
57 char *label;
58 char *units;
60 int
61 main (int argc, char **argv)
62 {
63 int result = STATE_UNKNOWN;
64 FILE *fp;
65 int line;
66 char input_buffer[MAX_INPUT_BUFFER];
67 char *temp_buffer;
68 time_t current_time;
69 time_t timestamp = 0L;
70 unsigned long average_value_rate = 0L;
71 unsigned long maximum_value_rate = 0L;
72 unsigned long rate = 0L;
74 setlocale (LC_ALL, "");
75 bindtextdomain (PACKAGE, LOCALEDIR);
76 textdomain (PACKAGE);
78 if (process_arguments (argc, argv) == ERROR)
79 usage4 (_("Could not parse arguments\n"));
81 /* open the MRTG log file for reading */
82 fp = fopen (log_file, "r");
83 if (fp == NULL) {
84 printf (_("Unable to open MRTG log file\n"));
85 return STATE_UNKNOWN;
86 }
88 line = 0;
89 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
91 line++;
93 /* skip the first line of the log file */
94 if (line == 1)
95 continue;
97 /* break out of read loop if we've passed the number of entries we want to read */
98 if (line > 2)
99 break;
101 /* grab the timestamp */
102 temp_buffer = strtok (input_buffer, " ");
103 timestamp = strtoul (temp_buffer, NULL, 10);
105 /* grab the average value 1 rate */
106 temp_buffer = strtok (NULL, " ");
107 if (variable_number == 1)
108 average_value_rate = strtoul (temp_buffer, NULL, 10);
110 /* grab the average value 2 rate */
111 temp_buffer = strtok (NULL, " ");
112 if (variable_number == 2)
113 average_value_rate = strtoul (temp_buffer, NULL, 10);
115 /* grab the maximum value 1 rate */
116 temp_buffer = strtok (NULL, " ");
117 if (variable_number == 1)
118 maximum_value_rate = strtoul (temp_buffer, NULL, 10);
120 /* grab the maximum value 2 rate */
121 temp_buffer = strtok (NULL, " ");
122 if (variable_number == 2)
123 maximum_value_rate = strtoul (temp_buffer, NULL, 10);
124 }
126 /* close the log file */
127 fclose (fp);
129 /* if we couldn't read enough data, return an unknown error */
130 if (line <= 2) {
131 printf (_("Unable to process MRTG log file\n"));
132 return STATE_UNKNOWN;
133 }
135 /* make sure the MRTG data isn't too old */
136 time (¤t_time);
137 if (expire_minutes > 0
138 && (current_time - timestamp) > (expire_minutes * 60)) {
139 printf (_("MRTG data has expired (%d minutes old)\n"),
140 (int) ((current_time - timestamp) / 60));
141 return STATE_WARNING;
142 }
144 /* else check the incoming/outgoing rates */
145 if (use_average == TRUE)
146 rate = average_value_rate;
147 else
148 rate = maximum_value_rate;
150 if (rate > value_critical_threshold)
151 result = STATE_CRITICAL;
152 else if (rate > value_warning_threshold)
153 result = STATE_WARNING;
155 printf("%s. %s = %lu %s|%s\n",
156 (use_average == TRUE) ? _("Avg") : _("Max"),
157 label, rate, units,
158 perfdata(label, (long) rate, units,
159 (int) value_warning_threshold, (long) value_warning_threshold,
160 (int) value_critical_threshold, (long) value_critical_threshold,
161 0, 0, 0, 0));
163 return result;
164 }
168 /* process command-line arguments */
169 int
170 process_arguments (int argc, char **argv)
171 {
172 int c;
174 int option = 0;
175 static struct option longopts[] = {
176 {"logfile", required_argument, 0, 'F'},
177 {"expires", required_argument, 0, 'e'},
178 {"aggregation", required_argument, 0, 'a'},
179 {"variable", required_argument, 0, 'v'},
180 {"critical", required_argument, 0, 'c'},
181 {"warning", required_argument, 0, 'w'},
182 {"label", required_argument, 0, 'l'},
183 {"units", required_argument, 0, 'u'},
184 {"verbose", no_argument, 0, 'v'},
185 {"version", no_argument, 0, 'V'},
186 {"help", no_argument, 0, 'h'},
187 {0, 0, 0, 0}
188 };
190 if (argc < 2)
191 return ERROR;
193 for (c = 1; c < argc; c++) {
194 if (strcmp ("-to", argv[c]) == 0)
195 strcpy (argv[c], "-t");
196 else if (strcmp ("-wt", argv[c]) == 0)
197 strcpy (argv[c], "-w");
198 else if (strcmp ("-ct", argv[c]) == 0)
199 strcpy (argv[c], "-c");
200 }
202 while (1) {
203 c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", longopts,
204 &option);
206 if (c == -1 || c == EOF)
207 break;
209 switch (c) {
210 case 'F': /* input file */
211 log_file = optarg;
212 break;
213 case 'e': /* ups name */
214 expire_minutes = atoi (optarg);
215 break;
216 case 'a': /* port */
217 if (!strcmp (optarg, "MAX"))
218 use_average = FALSE;
219 else
220 use_average = TRUE;
221 break;
222 case 'v':
223 variable_number = atoi (optarg);
224 if (variable_number < 1 || variable_number > 2)
225 usage4 (_("Invalid variable number"));
226 break;
227 case 'w': /* critical time threshold */
228 value_warning_threshold = strtoul (optarg, NULL, 10);
229 break;
230 case 'c': /* warning time threshold */
231 value_critical_threshold = strtoul (optarg, NULL, 10);
232 break;
233 case 'l': /* label */
234 label = optarg;
235 break;
236 case 'u': /* timeout */
237 units = optarg;
238 break;
239 case 'V': /* version */
240 print_revision (progname, revision);
241 exit (STATE_OK);
242 case 'h': /* help */
243 print_help ();
244 exit (STATE_OK);
245 case '?': /* help */
246 usage2 (_("Unknown argument"), optarg);
247 }
248 }
250 c = optind;
251 if (log_file == NULL && argc > c) {
252 log_file = argv[c++];
253 }
255 if (expire_minutes <= 0 && argc > c) {
256 if (is_intpos (argv[c]))
257 expire_minutes = atoi (argv[c++]);
258 else
259 die (STATE_UNKNOWN,
260 _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
261 argv[c], progname);
262 }
264 if (argc > c && strcmp (argv[c], "MAX") == 0) {
265 use_average = FALSE;
266 c++;
267 }
268 else if (argc > c && strcmp (argv[c], "AVG") == 0) {
269 use_average = TRUE;
270 c++;
271 }
273 if (argc > c && variable_number == -1) {
274 variable_number = atoi (argv[c++]);
275 if (variable_number < 1 || variable_number > 2) {
276 printf ("%s :", argv[c]);
277 usage (_("Invalid variable number\n"));
278 }
279 }
281 if (argc > c && value_warning_threshold == 0) {
282 value_warning_threshold = strtoul (argv[c++], NULL, 10);
283 }
285 if (argc > c && value_critical_threshold == 0) {
286 value_critical_threshold = strtoul (argv[c++], NULL, 10);
287 }
289 if (argc > c && strlen (label) == 0) {
290 label = argv[c++];
291 }
293 if (argc > c && strlen (units) == 0) {
294 units = argv[c++];
295 }
297 return validate_arguments ();
298 }
300 int
301 validate_arguments (void)
302 {
303 if (variable_number == -1)
304 usage4 (_("You must supply the variable number"));
306 if (label == NULL)
307 label = strdup ("value");
309 if (units == NULL)
310 units = strdup ("");
312 return OK;
313 }
317 void
318 print_help (void)
319 {
320 print_revision (progname, revision);
322 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
323 printf (COPYRIGHT, copyright, email);
325 printf ("%s\n", _("This plugin will check either the average or maximum value of one of the"));
326 printf ("%s\n", _("two variables recorded in an MRTG log file."));
328 printf ("\n\n");
330 print_usage ();
332 printf (_(UT_HELP_VRSN));
334 printf (_("\
335 -F, --logfile=FILE\n\
336 The MRTG log file containing the data you want to monitor\n\
337 -e, --expires=MINUTES\n\
338 Minutes before MRTG data is considered to be too old\n\
339 -a, --aggregation=AVG|MAX\n\
340 Should we check average or maximum values?\n\
341 -v, --variable=INTEGER\n\
342 Which variable set should we inspect? (1 or 2)\n\
343 -w, --warning=INTEGER\n\
344 Threshold value for data to result in WARNING status\n\
345 -c, --critical=INTEGER\n\
346 Threshold value for data to result in CRITICAL status\n"));
348 printf (_("\
349 -l, --label=STRING\n\
350 Type label for data (Examples: Conns, \"Processor Load\", In, Out)\n\
351 -u, --units=STRING\n\
352 Option units label for data (Example: Packets/Sec, Errors/Sec, \n\
353 \"Bytes Per Second\", \"%% Utilization\")\n"));
355 printf (_("\
356 If the value exceeds the <vwl> threshold, a WARNING status is returned. If\n\
357 the value exceeds the <vcl> threshold, a CRITICAL status is returned. If\n\
358 the data in the log file is older than <expire_minutes> old, a WARNING\n\
359 status is returned and a warning message is printed.\n\n"));
361 printf(_("This plugin is useful for monitoring MRTG data that does not correspond to\n\
362 bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).\n\
363 It can be used to monitor any kind of data that MRTG is monitoring - errors,\n\
364 packets/sec, etc. I use MRTG in conjuction with the Novell NLM that allows\n\
365 me to track processor utilization, user connections, drive space, etc and\n\
366 this plugin works well for monitoring that kind of data as well.\n\n"));
368 printf (_("Notes:\n\
369 - This plugin only monitors one of the two variables stored in the MRTG log\n\
370 file. If you want to monitor both values you will have to define two\n\
371 commands with different values for the <variable> argument. Of course,\n\
372 you can always hack the code to make this plugin work for you...\n\
373 - MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from\n\
374 http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html\n"));
376 printf (_(UT_SUPPORT));
377 }
381 /* original command line:
382 <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
384 void
385 print_usage (void)
386 {
387 printf (_("Usage:"));
388 printf ("%s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n",progname);
389 printf ("[-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n");
390 }