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 *label;
39 char *units;
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* message;
51 time_t timestamp = 0L;
52 unsigned long average_value_rate = 0L;
53 unsigned long maximum_value_rate = 0L;
54 unsigned long 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 asprintf (&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 (¤t_time);
120 if (expire_minutes > 0
121 && (current_time - timestamp) > (expire_minutes * 60)) {
122 result = STATE_WARNING;
123 asprintf (&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) {
130 if (use_average == TRUE)
131 rate = average_value_rate;
132 else
133 rate = maximum_value_rate;
135 if (rate > value_critical_threshold)
136 result = STATE_CRITICAL;
137 else if (rate > value_warning_threshold)
138 result = STATE_WARNING;
140 asprintf (&message, "%s. %s = %lu %s|%s",
141 (use_average == TRUE) ? _("Avg") : _("Max"),
142 label, rate, units,
143 perfdata(label, rate, units,
144 value_warning_threshold, value_warning_threshold,
145 value_critical_threshold, value_critical_threshold,
146 0, 0, 0, 0));
147 }
149 printf ("%s\n", message);
151 return result;
152 }
153 \f
154 /* process command-line arguments */
155 int
156 process_arguments (int argc, char **argv)
157 {
158 int c;
160 int option = 0;
161 static struct option longopts[] = {
162 {"logfile", required_argument, 0, 'F'},
163 {"expires", required_argument, 0, 'e'},
164 {"aggregation", required_argument, 0, 'a'},
165 {"variable", required_argument, 0, 'v'},
166 {"critical", required_argument, 0, 'c'},
167 {"warning", required_argument, 0, 'w'},
168 {"label", required_argument, 0, 'l'},
169 {"units", required_argument, 0, 'u'},
170 {"verbose", no_argument, 0, 'v'},
171 {"version", no_argument, 0, 'V'},
172 {"help", no_argument, 0, 'h'},
173 {0, 0, 0, 0}
174 };
176 if (argc < 2)
177 return ERROR;
179 for (c = 1; c < argc; c++) {
180 if (strcmp ("-to", argv[c]) == 0)
181 strcpy (argv[c], "-t");
182 else if (strcmp ("-wt", argv[c]) == 0)
183 strcpy (argv[c], "-w");
184 else if (strcmp ("-ct", argv[c]) == 0)
185 strcpy (argv[c], "-c");
186 }
188 while (1) {
189 c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", longopts,
190 &option);
192 if (c == -1 || c == EOF)
193 break;
195 switch (c) {
196 case 'F': /* input file */
197 log_file = optarg;
198 break;
199 case 'e': /* ups name */
200 expire_minutes = atoi (optarg);
201 break;
202 case 'a': /* port */
203 if (!strcmp (optarg, "MAX"))
204 use_average = FALSE;
205 else
206 use_average = TRUE;
207 break;
208 case 'v':
209 variable_number = atoi (optarg);
210 if (variable_number < 1 || variable_number > 2)
211 usage (_("Invalid variable number\n"));
212 break;
213 case 'w': /* critical time threshold */
214 value_warning_threshold = strtoul (optarg, NULL, 10);
215 break;
216 case 'c': /* warning time threshold */
217 value_critical_threshold = strtoul (optarg, NULL, 10);
218 break;
219 case 'l': /* label */
220 label = optarg;
221 break;
222 case 'u': /* timeout */
223 units = optarg;
224 break;
225 case 'V': /* version */
226 print_revision (progname, revision);
227 exit (STATE_OK);
228 case 'h': /* help */
229 print_help ();
230 exit (STATE_OK);
231 case '?': /* help */
232 usage (_("Invalid argument\n"));
233 }
234 }
236 c = optind;
237 if (log_file == NULL && argc > c) {
238 log_file = argv[c++];
239 }
241 if (expire_minutes <= 0 && argc > c) {
242 if (is_intpos (argv[c]))
243 expire_minutes = atoi (argv[c++]);
244 else
245 die (STATE_UNKNOWN,
246 _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
247 argv[c], progname);
248 }
250 if (argc > c && strcmp (argv[c], "MAX") == 0) {
251 use_average = FALSE;
252 c++;
253 }
254 else if (argc > c && strcmp (argv[c], "AVG") == 0) {
255 use_average = TRUE;
256 c++;
257 }
259 if (argc > c && variable_number == -1) {
260 variable_number = atoi (argv[c++]);
261 if (variable_number < 1 || variable_number > 2) {
262 printf ("%s :", argv[c]);
263 usage (_("Invalid variable number\n"));
264 }
265 }
267 if (argc > c && value_warning_threshold == 0) {
268 value_warning_threshold = strtoul (argv[c++], NULL, 10);
269 }
271 if (argc > c && value_critical_threshold == 0) {
272 value_critical_threshold = strtoul (argv[c++], NULL, 10);
273 }
275 if (argc > c && strlen (label) == 0) {
276 label = argv[c++];
277 }
279 if (argc > c && strlen (units) == 0) {
280 units = argv[c++];
281 }
283 return validate_arguments ();
284 }
286 int
287 validate_arguments (void)
288 {
289 if (variable_number == -1)
290 usage (_("You must supply the variable number\n"));
292 if (label == NULL)
293 label = strdup ("value");
295 if (units == NULL)
296 units = strdup ("");
298 return OK;
299 }
305 \f
306 void
307 print_help (void)
308 {
309 print_revision (progname, revision);
311 printf (_("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"));
312 printf (_(COPYRIGHT), copyright, email);
314 printf(_("\
315 This plugin will check either the average or maximum value of one of the\n\
316 two variables recorded in an MRTG log file.\n"));
318 print_usage ();
320 printf (_(UT_HELP_VRSN));
322 printf (_("\
323 -F, --logfile=FILE\n\
324 The MRTG log file containing the data you want to monitor\n\
325 -e, --expires=MINUTES\n\
326 Minutes before MRTG data is considered to be too old\n\
327 -a, --aggregation=AVG|MAX\n\
328 Should we check average or maximum values?\n\
329 -v, --variable=INTEGER\n\
330 Which variable set should we inspect? (1 or 2)\n\
331 -w, --warning=INTEGER\n\
332 Threshold value for data to result in WARNING status\n\
333 -c, --critical=INTEGER\n\
334 Threshold value for data to result in CRITICAL status\n"));
336 printf (_("\
337 -l, --label=STRING\n\
338 Type label for data (Examples: Conns, \"Processor Load\", In, Out)\n\
339 -u, --units=STRING\n\
340 Option units label for data (Example: Packets/Sec, Errors/Sec, \n\
341 \"Bytes Per Second\", \"%% Utilization\")\n"));
343 printf (_("\
344 If the value exceeds the <vwl> threshold, a WARNING status is returned. If\n\
345 the value exceeds the <vcl> threshold, a CRITICAL status is returned. If\n\
346 the data in the log file is older than <expire_minutes> old, a WARNING\n\
347 status is returned and a warning message is printed.\n\n"));
349 printf(_("This plugin is useful for monitoring MRTG data that does not correspond to\n\
350 bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).\n\
351 It can be used to monitor any kind of data that MRTG is monitoring - errors,\n\
352 packets/sec, etc. I use MRTG in conjuction with the Novell NLM that allows\n\
353 me to track processor utilization, user connections, drive space, etc and\n\
354 this plugin works well for monitoring that kind of data as well.\n\n"));
356 printf (_("Notes:\n\
357 - This plugin only monitors one of the two variables stored in the MRTG log\n\
358 file. If you want to monitor both values you will have to define two\n\
359 commands with different values for the <variable> argument. Of course,\n\
360 you can always hack the code to make this plugin work for you...\n\
361 - MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from\n\
362 http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html\n"));
364 printf (_(UT_SUPPORT));
365 }
370 /* original command line:
371 <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
373 void
374 print_usage (void)
375 {
376 printf (_("\
377 Usage: %s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n\
378 [-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n"), progname);
379 printf (_(UT_HLP_VRS), progname, progname);
380 }