Code

add perf data
[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 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 (&current_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;
153 \f
154 /* process command-line arguments */
155 int
156 process_arguments (int argc, char **argv)
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 ();
286 int
287 validate_arguments (void)
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;
305 \f
306 void
307 print_help (void)
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));
370 /* original command line: 
371          <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
373 void
374 print_usage (void)
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);