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$
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 time_t timestamp = 0L;
53 unsigned long average_value_rate = 0L;
54 unsigned long maximum_value_rate = 0L;
55 unsigned long rate = 0L;
57 setlocale (LC_ALL, "");
58 bindtextdomain (PACKAGE, LOCALEDIR);
59 textdomain (PACKAGE);
61 if (process_arguments (argc, argv) == ERROR)
62 usage4 (_("Could not parse arguments\n"));
64 /* open the MRTG log file for reading */
65 fp = fopen (log_file, "r");
66 if (fp == NULL) {
67 printf (_("Unable to open MRTG log file\n"));
68 return STATE_UNKNOWN;
69 }
71 line = 0;
72 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
74 line++;
76 /* skip the first line of the log file */
77 if (line == 1)
78 continue;
80 /* break out of read loop if we've passed the number of entries we want to read */
81 if (line > 2)
82 break;
84 /* grab the timestamp */
85 temp_buffer = strtok (input_buffer, " ");
86 timestamp = strtoul (temp_buffer, NULL, 10);
88 /* grab the average value 1 rate */
89 temp_buffer = strtok (NULL, " ");
90 if (variable_number == 1)
91 average_value_rate = strtoul (temp_buffer, NULL, 10);
93 /* grab the average value 2 rate */
94 temp_buffer = strtok (NULL, " ");
95 if (variable_number == 2)
96 average_value_rate = strtoul (temp_buffer, NULL, 10);
98 /* grab the maximum value 1 rate */
99 temp_buffer = strtok (NULL, " ");
100 if (variable_number == 1)
101 maximum_value_rate = strtoul (temp_buffer, NULL, 10);
103 /* grab the maximum value 2 rate */
104 temp_buffer = strtok (NULL, " ");
105 if (variable_number == 2)
106 maximum_value_rate = strtoul (temp_buffer, NULL, 10);
107 }
109 /* close the log file */
110 fclose (fp);
112 /* if we couldn't read enough data, return an unknown error */
113 if (line <= 2) {
114 printf (_("Unable to process MRTG log file\n"));
115 return STATE_UNKNOWN;
116 }
118 /* make sure the MRTG data isn't too old */
119 time (¤t_time);
120 if (expire_minutes > 0
121 && (current_time - timestamp) > (expire_minutes * 60)) {
122 printf (_("MRTG data has expired (%d minutes old)\n"),
123 (int) ((current_time - timestamp) / 60));
124 return STATE_WARNING;
125 }
127 /* else check the incoming/outgoing rates */
128 if (use_average == TRUE)
129 rate = average_value_rate;
130 else
131 rate = maximum_value_rate;
133 if (rate > value_critical_threshold)
134 result = STATE_CRITICAL;
135 else if (rate > value_warning_threshold)
136 result = STATE_WARNING;
138 printf("%s. %s = %lu %s|%s\n",
139 (use_average == TRUE) ? _("Avg") : _("Max"),
140 label, rate, units,
141 perfdata(label, (long) rate, units,
142 (int) value_warning_threshold, (long) value_warning_threshold,
143 (int) value_critical_threshold, (long) value_critical_threshold,
144 0, 0, 0, 0));
146 return result;
147 }
151 /* process command-line arguments */
152 int
153 process_arguments (int argc, char **argv)
154 {
155 int c;
157 int option = 0;
158 static struct option longopts[] = {
159 {"logfile", required_argument, 0, 'F'},
160 {"expires", required_argument, 0, 'e'},
161 {"aggregation", required_argument, 0, 'a'},
162 {"variable", required_argument, 0, 'v'},
163 {"critical", required_argument, 0, 'c'},
164 {"warning", required_argument, 0, 'w'},
165 {"label", required_argument, 0, 'l'},
166 {"units", required_argument, 0, 'u'},
167 {"verbose", no_argument, 0, 'v'},
168 {"version", no_argument, 0, 'V'},
169 {"help", no_argument, 0, 'h'},
170 {0, 0, 0, 0}
171 };
173 if (argc < 2)
174 return ERROR;
176 for (c = 1; c < argc; c++) {
177 if (strcmp ("-to", argv[c]) == 0)
178 strcpy (argv[c], "-t");
179 else if (strcmp ("-wt", argv[c]) == 0)
180 strcpy (argv[c], "-w");
181 else if (strcmp ("-ct", argv[c]) == 0)
182 strcpy (argv[c], "-c");
183 }
185 while (1) {
186 c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", longopts,
187 &option);
189 if (c == -1 || c == EOF)
190 break;
192 switch (c) {
193 case 'F': /* input file */
194 log_file = optarg;
195 break;
196 case 'e': /* ups name */
197 expire_minutes = atoi (optarg);
198 break;
199 case 'a': /* port */
200 if (!strcmp (optarg, "MAX"))
201 use_average = FALSE;
202 else
203 use_average = TRUE;
204 break;
205 case 'v':
206 variable_number = atoi (optarg);
207 if (variable_number < 1 || variable_number > 2)
208 usage4 (_("Invalid variable number"));
209 break;
210 case 'w': /* critical time threshold */
211 value_warning_threshold = strtoul (optarg, NULL, 10);
212 break;
213 case 'c': /* warning time threshold */
214 value_critical_threshold = strtoul (optarg, NULL, 10);
215 break;
216 case 'l': /* label */
217 label = optarg;
218 break;
219 case 'u': /* timeout */
220 units = optarg;
221 break;
222 case 'V': /* version */
223 print_revision (progname, revision);
224 exit (STATE_OK);
225 case 'h': /* help */
226 print_help ();
227 exit (STATE_OK);
228 case '?': /* help */
229 usage2 (_("Unknown argument"), optarg);
230 }
231 }
233 c = optind;
234 if (log_file == NULL && argc > c) {
235 log_file = argv[c++];
236 }
238 if (expire_minutes <= 0 && argc > c) {
239 if (is_intpos (argv[c]))
240 expire_minutes = atoi (argv[c++]);
241 else
242 die (STATE_UNKNOWN,
243 _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
244 argv[c], progname);
245 }
247 if (argc > c && strcmp (argv[c], "MAX") == 0) {
248 use_average = FALSE;
249 c++;
250 }
251 else if (argc > c && strcmp (argv[c], "AVG") == 0) {
252 use_average = TRUE;
253 c++;
254 }
256 if (argc > c && variable_number == -1) {
257 variable_number = atoi (argv[c++]);
258 if (variable_number < 1 || variable_number > 2) {
259 printf ("%s :", argv[c]);
260 usage (_("Invalid variable number\n"));
261 }
262 }
264 if (argc > c && value_warning_threshold == 0) {
265 value_warning_threshold = strtoul (argv[c++], NULL, 10);
266 }
268 if (argc > c && value_critical_threshold == 0) {
269 value_critical_threshold = strtoul (argv[c++], NULL, 10);
270 }
272 if (argc > c && strlen (label) == 0) {
273 label = argv[c++];
274 }
276 if (argc > c && strlen (units) == 0) {
277 units = argv[c++];
278 }
280 return validate_arguments ();
281 }
283 int
284 validate_arguments (void)
285 {
286 if (variable_number == -1)
287 usage4 (_("You must supply the variable number"));
289 if (label == NULL)
290 label = strdup ("value");
292 if (units == NULL)
293 units = strdup ("");
295 return OK;
296 }
300 void
301 print_help (void)
302 {
303 print_revision (progname, revision);
305 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
306 printf (COPYRIGHT, copyright, email);
308 printf ("%s\n", _("This plugin will check either the average or maximum value of one of the"));
309 printf ("%s\n", _("two variables recorded in an MRTG log file."));
311 printf ("\n\n");
313 print_usage ();
315 printf (_(UT_HELP_VRSN));
317 printf (_("\
318 -F, --logfile=FILE\n\
319 The MRTG log file containing the data you want to monitor\n\
320 -e, --expires=MINUTES\n\
321 Minutes before MRTG data is considered to be too old\n\
322 -a, --aggregation=AVG|MAX\n\
323 Should we check average or maximum values?\n\
324 -v, --variable=INTEGER\n\
325 Which variable set should we inspect? (1 or 2)\n\
326 -w, --warning=INTEGER\n\
327 Threshold value for data to result in WARNING status\n\
328 -c, --critical=INTEGER\n\
329 Threshold value for data to result in CRITICAL status\n"));
331 printf (_("\
332 -l, --label=STRING\n\
333 Type label for data (Examples: Conns, \"Processor Load\", In, Out)\n\
334 -u, --units=STRING\n\
335 Option units label for data (Example: Packets/Sec, Errors/Sec, \n\
336 \"Bytes Per Second\", \"%% Utilization\")\n"));
338 printf (_("\
339 If the value exceeds the <vwl> threshold, a WARNING status is returned. If\n\
340 the value exceeds the <vcl> threshold, a CRITICAL status is returned. If\n\
341 the data in the log file is older than <expire_minutes> old, a WARNING\n\
342 status is returned and a warning message is printed.\n\n"));
344 printf(_("This plugin is useful for monitoring MRTG data that does not correspond to\n\
345 bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).\n\
346 It can be used to monitor any kind of data that MRTG is monitoring - errors,\n\
347 packets/sec, etc. I use MRTG in conjuction with the Novell NLM that allows\n\
348 me to track processor utilization, user connections, drive space, etc and\n\
349 this plugin works well for monitoring that kind of data as well.\n\n"));
351 printf (_("Notes:\n\
352 - This plugin only monitors one of the two variables stored in the MRTG log\n\
353 file. If you want to monitor both values you will have to define two\n\
354 commands with different values for the <variable> argument. Of course,\n\
355 you can always hack the code to make this plugin work for you...\n\
356 - MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from\n\
357 http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html\n"));
359 printf (_(UT_SUPPORT));
360 }
364 /* original command line:
365 <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
367 void
368 print_usage (void)
369 {
370 printf (_("Usage:"));
371 printf ("%s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n",progname);
372 printf ("[-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n");
373 }