Code

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