Back to index

nagios-plugins  1.4.16
check_mrtg.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * 
00003 * Nagios check_mrtg plugin
00004 * 
00005 * License: GPL
00006 * Copyright (c) 1999-2007 Nagios Plugins Development Team
00007 * 
00008 * Description:
00009 * 
00010 * This file contains the check_mrtg plugin
00011 * 
00012 * This plugin will check either the average or maximum value of one of the
00013 * two variables recorded in an MRTG log file.
00014 * 
00015 * 
00016 * This program is free software: you can redistribute it and/or modify
00017 * it under the terms of the GNU General Public License as published by
00018 * the Free Software Foundation, either version 3 of the License, or
00019 * (at your option) any later version.
00020 * 
00021 * This program is distributed in the hope that it will be useful,
00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 * GNU General Public License for more details.
00025 * 
00026 * You should have received a copy of the GNU General Public License
00027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00028 * 
00029 * 
00030 *****************************************************************************/
00031 
00032 const char *progname = "check_mrtg";
00033 const char *copyright = "1999-2007";
00034 const char *email = "nagiosplug-devel@lists.sourceforge.net";
00035 
00036 #include "common.h"
00037 #include "utils.h"
00038 
00039 int process_arguments (int, char **);
00040 int validate_arguments (void);
00041 void print_help (void);
00042 void print_usage (void);
00043 
00044 char *log_file = NULL;
00045 int expire_minutes = 0;
00046 int use_average = TRUE;
00047 int variable_number = -1;
00048 unsigned long value_warning_threshold = 0L;
00049 unsigned long value_critical_threshold = 0L;
00050 char *label;
00051 char *units;
00052 
00053 int
00054 main (int argc, char **argv)
00055 {
00056        int result = STATE_OK;
00057        FILE *fp;
00058        int line;
00059        char input_buffer[MAX_INPUT_BUFFER];
00060        char *temp_buffer;
00061        time_t current_time;
00062        time_t timestamp = 0L;
00063        unsigned long average_value_rate = 0L;
00064        unsigned long maximum_value_rate = 0L;
00065        unsigned long rate = 0L;
00066 
00067        setlocale (LC_ALL, "");
00068        bindtextdomain (PACKAGE, LOCALEDIR);
00069        textdomain (PACKAGE);
00070 
00071        /* Parse extra opts if any */
00072        argv=np_extra_opts (&argc, argv, progname);
00073 
00074        if (process_arguments (argc, argv) == ERROR)
00075               usage4 (_("Could not parse arguments\n"));
00076 
00077        /* open the MRTG log file for reading */
00078        fp = fopen (log_file, "r");
00079        if (fp == NULL) {
00080               printf (_("Unable to open MRTG log file\n"));
00081               return STATE_UNKNOWN;
00082        }
00083 
00084        line = 0;
00085        while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
00086 
00087               line++;
00088 
00089               /* skip the first line of the log file */
00090               if (line == 1)
00091                      continue;
00092 
00093               /* break out of read loop if we've passed the number of entries we want to read */
00094               if (line > 2)
00095                      break;
00096 
00097               /* grab the timestamp */
00098               temp_buffer = strtok (input_buffer, " ");
00099               timestamp = strtoul (temp_buffer, NULL, 10);
00100 
00101               /* grab the average value 1 rate */
00102               temp_buffer = strtok (NULL, " ");
00103               if (variable_number == 1)
00104                      average_value_rate = strtoul (temp_buffer, NULL, 10);
00105 
00106               /* grab the average value 2 rate */
00107               temp_buffer = strtok (NULL, " ");
00108               if (variable_number == 2)
00109                      average_value_rate = strtoul (temp_buffer, NULL, 10);
00110 
00111               /* grab the maximum value 1 rate */
00112               temp_buffer = strtok (NULL, " ");
00113               if (variable_number == 1)
00114                      maximum_value_rate = strtoul (temp_buffer, NULL, 10);
00115 
00116               /* grab the maximum value 2 rate */
00117               temp_buffer = strtok (NULL, " ");
00118               if (variable_number == 2)
00119                      maximum_value_rate = strtoul (temp_buffer, NULL, 10);
00120        }
00121 
00122        /* close the log file */
00123        fclose (fp);
00124 
00125        /* if we couldn't read enough data, return an unknown error */
00126        if (line <= 2) {
00127               printf (_("Unable to process MRTG log file\n"));
00128               return STATE_UNKNOWN;
00129        }
00130 
00131        /* make sure the MRTG data isn't too old */
00132        time (&current_time);
00133        if (expire_minutes > 0
00134                      && (current_time - timestamp) > (expire_minutes * 60)) {
00135               printf (_("MRTG data has expired (%d minutes old)\n"),
00136                       (int) ((current_time - timestamp) / 60));
00137               return STATE_WARNING;
00138        }
00139 
00140        /* else check the incoming/outgoing rates */
00141        if (use_average == TRUE)
00142               rate = average_value_rate;
00143        else
00144               rate = maximum_value_rate;
00145 
00146        if (rate > value_critical_threshold)
00147               result = STATE_CRITICAL;
00148        else if (rate > value_warning_threshold)
00149               result = STATE_WARNING;
00150 
00151        printf("%s. %s = %lu %s|%s\n",
00152               (use_average == TRUE) ? _("Avg") : _("Max"),
00153               label, rate, units,
00154               perfdata(label, (long) rate, units,
00155                       (int) value_warning_threshold, (long) value_warning_threshold,
00156                       (int) value_critical_threshold, (long) value_critical_threshold,
00157                       0, 0, 0, 0));
00158 
00159        return result;
00160 }
00161 
00162 
00163 
00164 /* process command-line arguments */
00165 int
00166 process_arguments (int argc, char **argv)
00167 {
00168        int c;
00169 
00170        int option = 0;
00171        static struct option longopts[] = {
00172               {"logfile", required_argument, 0, 'F'},
00173               {"expires", required_argument, 0, 'e'},
00174               {"aggregation", required_argument, 0, 'a'},
00175               {"variable", required_argument, 0, 'v'},
00176               {"critical", required_argument, 0, 'c'},
00177               {"warning", required_argument, 0, 'w'},
00178               {"label", required_argument, 0, 'l'},
00179               {"units", required_argument, 0, 'u'},
00180               {"variable", required_argument, 0, 'v'},
00181               {"version", no_argument, 0, 'V'},
00182               {"help", no_argument, 0, 'h'},
00183               {0, 0, 0, 0}
00184        };
00185 
00186        if (argc < 2)
00187               return ERROR;
00188 
00189        for (c = 1; c < argc; c++) {
00190               if (strcmp ("-to", argv[c]) == 0)
00191                      strcpy (argv[c], "-t");
00192               else if (strcmp ("-wt", argv[c]) == 0)
00193                      strcpy (argv[c], "-w");
00194               else if (strcmp ("-ct", argv[c]) == 0)
00195                      strcpy (argv[c], "-c");
00196        }
00197 
00198        while (1) {
00199               c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", longopts,
00200                                                                 &option);
00201 
00202               if (c == -1 || c == EOF)
00203                      break;
00204 
00205               switch (c) {
00206               case 'F':                                                             /* input file */
00207                      log_file = optarg;
00208                      break;
00209               case 'e':                                                             /* ups name */
00210                      expire_minutes = atoi (optarg);
00211                      break;
00212               case 'a':                                                             /* port */
00213                      if (!strcmp (optarg, "MAX"))
00214                             use_average = FALSE;
00215                      else
00216                             use_average = TRUE;
00217                      break;
00218               case 'v':
00219                      variable_number = atoi (optarg);
00220                      if (variable_number < 1 || variable_number > 2)
00221                             usage4 (_("Invalid variable number"));
00222                      break;
00223               case 'w':                                                             /* critical time threshold */
00224                      value_warning_threshold = strtoul (optarg, NULL, 10);
00225                      break;
00226               case 'c':                                                             /* warning time threshold */
00227                      value_critical_threshold = strtoul (optarg, NULL, 10);
00228                      break;
00229               case 'l':                                                             /* label */
00230                      label = optarg;
00231                      break;
00232               case 'u':                                                             /* timeout */
00233                      units = optarg;
00234                      break;
00235               case 'V':                                                             /* version */
00236                      print_revision (progname, NP_VERSION);
00237                      exit (STATE_OK);
00238               case 'h':                                                             /* help */
00239                      print_help ();
00240                      exit (STATE_OK);
00241               case '?':                                                             /* help */
00242                      usage5 ();
00243               }
00244        }
00245 
00246        c = optind;
00247        if (log_file == NULL && argc > c) {
00248               log_file = argv[c++];
00249        }
00250 
00251        if (expire_minutes <= 0 && argc > c) {
00252               if (is_intpos (argv[c]))
00253                      expire_minutes = atoi (argv[c++]);
00254               else
00255                      die (STATE_UNKNOWN,
00256                                 _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
00257                                 argv[c], progname);
00258        }
00259 
00260        if (argc > c && strcmp (argv[c], "MAX") == 0) {
00261               use_average = FALSE;
00262               c++;
00263        }
00264        else if (argc > c && strcmp (argv[c], "AVG") == 0) {
00265               use_average = TRUE;
00266               c++;
00267        }
00268 
00269        if (argc > c && variable_number == -1) {
00270               variable_number = atoi (argv[c++]);
00271               if (variable_number < 1 || variable_number > 2) {
00272                      printf ("%s :", argv[c]);
00273                      usage (_("Invalid variable number\n"));
00274               }
00275        }
00276 
00277        if (argc > c && value_warning_threshold == 0) {
00278               value_warning_threshold = strtoul (argv[c++], NULL, 10);
00279        }
00280 
00281        if (argc > c && value_critical_threshold == 0) {
00282               value_critical_threshold = strtoul (argv[c++], NULL, 10);
00283        }
00284 
00285        if (argc > c && strlen (label) == 0) {
00286               label = argv[c++];
00287        }
00288 
00289        if (argc > c && strlen (units) == 0) {
00290               units = argv[c++];
00291        }
00292 
00293        return validate_arguments ();
00294 }
00295 
00296 int
00297 validate_arguments (void)
00298 {
00299        if (variable_number == -1)
00300               usage4 (_("You must supply the variable number"));
00301 
00302        if (label == NULL)
00303               label = strdup ("value");
00304 
00305        if (units == NULL)
00306               units = strdup ("");
00307 
00308        return OK;
00309 }
00310 
00311 
00312 
00313 void
00314 print_help (void)
00315 {
00316        print_revision (progname, NP_VERSION);
00317 
00318        printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
00319        printf (COPYRIGHT, copyright, email);
00320 
00321        printf ("%s\n", _("This plugin will check either the average or maximum value of one of the"));
00322   printf ("%s\n", _("two variables recorded in an MRTG log file."));
00323 
00324   printf ("\n\n");
00325 
00326        print_usage ();
00327 
00328        printf (UT_HELP_VRSN);
00329        printf (UT_EXTRA_OPTS);
00330 
00331        printf (" %s\n", "-F, --logfile=FILE");
00332   printf ("   %s\n", _("The MRTG log file containing the data you want to monitor"));
00333   printf (" %s\n", "-e, --expires=MINUTES");
00334   printf ("   %s\n", _("Minutes before MRTG data is considered to be too old"));
00335   printf (" %s\n", "-a, --aggregation=AVG|MAX");
00336   printf ("   %s\n", _("Should we check average or maximum values?"));
00337   printf (" %s\n", "-v, --variable=INTEGER");
00338   printf ("   %s\n", _("Which variable set should we inspect? (1 or 2)"));
00339   printf (" %s\n", "-w, --warning=INTEGER");
00340   printf ("   %s\n", _("Threshold value for data to result in WARNING status"));
00341   printf (" %s\n", "-c, --critical=INTEGER");
00342   printf ("   %s\n", _("Threshold value for data to result in CRITICAL status"));
00343        printf (" %s\n", "-l, --label=STRING");
00344   printf ("   %s\n", _("Type label for data (Examples: Conns, \"Processor Load\", In, Out)"));
00345   printf (" %s\n", "-u, --units=STRING");
00346   printf ("   %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,"));
00347   printf ("   %s\n", _("\"Bytes Per Second\", \"%% Utilization\")"));
00348 
00349   printf ("\n");
00350        printf (" %s\n", _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If"));
00351   printf (" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned.  If"));
00352   printf (" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING"));
00353   printf (" %s\n", _("status is returned and a warning message is printed."));
00354 
00355   printf ("\n");
00356        printf (" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to"));
00357   printf (" %s\n", _("bandwidth usage.  (Use the check_mrtgtraf plugin for monitoring bandwidth)."));
00358   printf (" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,"));
00359   printf (" %s\n", _("packets/sec, etc.  I use MRTG in conjuction with the Novell NLM that allows"));
00360   printf (" %s\n", _("me to track processor utilization, user connections, drive space, etc and"));
00361   printf (" %s\n\n", _("this plugin works well for monitoring that kind of data as well."));
00362 
00363        printf ("%s\n", _("Notes:"));
00364   printf (" %s\n", _("- This plugin only monitors one of the two variables stored in the MRTG log"));
00365   printf ("   %s\n", _("file.  If you want to monitor both values you will have to define two"));
00366   printf ("   %s\n", _("commands with different values for the <variable> argument.  Of course,"));
00367   printf ("   %s\n", _("you can always hack the code to make this plugin work for you..."));
00368   printf (" %s\n", _("- MRTG stands for the Multi Router Traffic Grapher.  It can be downloaded from"));
00369   printf ("   %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
00370 
00371        printf (UT_SUPPORT);
00372 }
00373 
00374 
00375 
00376 /* original command line:
00377         <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
00378 
00379 void
00380 print_usage (void)
00381 {
00382   printf ("%s\n", _("Usage:"));
00383        printf ("%s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n",progname);
00384   printf ("[-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n");
00385 }