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