Back to index

nagios-plugins  1.4.16
check_mrtgtraf.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * 
00003 * Nagios check_mrtgtraf plugin
00004 * 
00005 * License: GPL
00006 * Copyright (c) 1999-2007 Nagios Plugins Development Team
00007 * 
00008 * Description:
00009 * 
00010 * This file contains the check_mtrgtraf plugin
00011 * 
00012 * This plugin will check the incoming/outgoing transfer rates of a router
00013 * switch, etc recorded in an MRTG log.
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 #include "common.h"
00033 #include "utils.h"
00034 
00035 const char *progname = "check_mrtgtraf";
00036 const char *copyright = "1999-2007";
00037 const char *email = "nagiosplug-devel@lists.sourceforge.net";
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 = -1;
00046 int use_average = TRUE;
00047 unsigned long incoming_warning_threshold = 0L;
00048 unsigned long incoming_critical_threshold = 0L;
00049 unsigned long outgoing_warning_threshold = 0L;
00050 unsigned long outgoing_critical_threshold = 0L;
00051 
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        char *error_message;
00063        time_t timestamp = 0L;
00064        unsigned long average_incoming_rate = 0L;
00065        unsigned long average_outgoing_rate = 0L;
00066        unsigned long maximum_incoming_rate = 0L;
00067        unsigned long maximum_outgoing_rate = 0L;
00068        unsigned long incoming_rate = 0L;
00069        unsigned long outgoing_rate = 0L;
00070        double adjusted_incoming_rate = 0.0;
00071        double adjusted_outgoing_rate = 0.0;
00072        char incoming_speed_rating[8];
00073        char outgoing_speed_rating[8];
00074 
00075        setlocale (LC_ALL, "");
00076        bindtextdomain (PACKAGE, LOCALEDIR);
00077        textdomain (PACKAGE);
00078 
00079        /* Parse extra opts if any */
00080        argv=np_extra_opts (&argc, argv, progname);
00081 
00082        if (process_arguments (argc, argv) == ERROR)
00083               usage4 (_("Could not parse arguments"));
00084 
00085        /* open the MRTG log file for reading */
00086        fp = fopen (log_file, "r");
00087        if (fp == NULL)
00088               usage4 (_("Unable to open MRTG log file"));
00089 
00090        line = 0;
00091        while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
00092 
00093               line++;
00094 
00095               /* skip the first line of the log file */
00096               if (line == 1)
00097                      continue;
00098 
00099               /* break out of read loop */
00100               /* if we've passed the number of entries we want to read */
00101               if (line > 2)
00102                      break;
00103 
00104               /* grab the timestamp */
00105               temp_buffer = strtok (input_buffer, " ");
00106               timestamp = strtoul (temp_buffer, NULL, 10);
00107 
00108               /* grab the average incoming transfer rate */
00109               temp_buffer = strtok (NULL, " ");
00110               average_incoming_rate = strtoul (temp_buffer, NULL, 10);
00111 
00112               /* grab the average outgoing transfer rate */
00113               temp_buffer = strtok (NULL, " ");
00114               average_outgoing_rate = strtoul (temp_buffer, NULL, 10);
00115 
00116               /* grab the maximum incoming transfer rate */
00117               temp_buffer = strtok (NULL, " ");
00118               maximum_incoming_rate = strtoul (temp_buffer, NULL, 10);
00119 
00120               /* grab the maximum outgoing transfer rate */
00121               temp_buffer = strtok (NULL, " ");
00122               maximum_outgoing_rate = strtoul (temp_buffer, NULL, 10);
00123        }
00124 
00125        /* close the log file */
00126        fclose (fp);
00127 
00128        /* if we couldn't read enough data, return an unknown error */
00129        if (line <= 2)
00130               usage4 (_("Unable to process MRTG log file"));
00131 
00132        /* make sure the MRTG data isn't too old */
00133        time (&current_time);
00134        if ((expire_minutes > 0) &&
00135            (current_time - timestamp) > (expire_minutes * 60))
00136               die (STATE_WARNING,  _("MRTG data has expired (%d minutes old)\n"),
00137                    (int) ((current_time - timestamp) / 60));
00138 
00139        /* else check the incoming/outgoing rates */
00140        if (use_average == TRUE) {
00141               incoming_rate = average_incoming_rate;
00142               outgoing_rate = average_outgoing_rate;
00143        }
00144        else {
00145               incoming_rate = maximum_incoming_rate;
00146               outgoing_rate = maximum_outgoing_rate;
00147        }
00148 
00149        /* report incoming traffic in Bytes/sec */
00150        if (incoming_rate < 1024) {
00151               strcpy (incoming_speed_rating, "B/s");
00152               adjusted_incoming_rate = (double) incoming_rate;
00153        }
00154 
00155        /* report incoming traffic in KBytes/sec */
00156        else if (incoming_rate < (1024 * 1024)) {
00157               strcpy (incoming_speed_rating, "KB/s");
00158               adjusted_incoming_rate = (double) (incoming_rate / 1024.0);
00159        }
00160 
00161        /* report incoming traffic in MBytes/sec */
00162        else {
00163               strcpy (incoming_speed_rating, "MB/s");
00164               adjusted_incoming_rate = (double) (incoming_rate / 1024.0 / 1024.0);
00165        }
00166 
00167        /* report outgoing traffic in Bytes/sec */
00168        if (outgoing_rate < 1024) {
00169               strcpy (outgoing_speed_rating, "B/s");
00170               adjusted_outgoing_rate = (double) outgoing_rate;
00171        }
00172 
00173        /* report outgoing traffic in KBytes/sec */
00174        else if (outgoing_rate < (1024 * 1024)) {
00175               strcpy (outgoing_speed_rating, "KB/s");
00176               adjusted_outgoing_rate = (double) (outgoing_rate / 1024.0);
00177        }
00178 
00179        /* report outgoing traffic in MBytes/sec */
00180        else {
00181               strcpy (outgoing_speed_rating, "MB/s");
00182               adjusted_outgoing_rate = (double) (outgoing_rate / 1024.0 / 1024.0);
00183        }
00184 
00185        if (incoming_rate > incoming_critical_threshold
00186                      || outgoing_rate > outgoing_critical_threshold) {
00187               result = STATE_CRITICAL;
00188        }
00189        else if (incoming_rate > incoming_warning_threshold
00190                                     || outgoing_rate > outgoing_warning_threshold) {
00191               result = STATE_WARNING;
00192        }
00193 
00194        asprintf (&error_message, _("%s. In = %0.1f %s, %s. Out = %0.1f %s|%s %s\n"),
00195                  (use_average == TRUE) ? _("Avg") : _("Max"), adjusted_incoming_rate,
00196                  incoming_speed_rating, (use_average == TRUE) ? _("Avg") : _("Max"),
00197                  adjusted_outgoing_rate, outgoing_speed_rating,
00198                  fperfdata("in", adjusted_incoming_rate, incoming_speed_rating,
00199                           (int)incoming_warning_threshold, incoming_warning_threshold,
00200                           (int)incoming_critical_threshold, incoming_critical_threshold,
00201                           TRUE, 0, FALSE, 0),
00202                  fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating,
00203                           (int)outgoing_warning_threshold, outgoing_warning_threshold,
00204                           (int)outgoing_critical_threshold, outgoing_critical_threshold,
00205                           TRUE, 0, FALSE, 0));
00206 
00207        printf (_("Traffic %s - %s\n"), state_text(result), error_message);
00208 
00209        return result;
00210 }
00211 
00212 
00213 
00214 /* process command-line arguments */
00215 int
00216 process_arguments (int argc, char **argv)
00217 {
00218        int c;
00219 
00220        int option = 0;
00221        static struct option longopts[] = {
00222               {"filename", required_argument, 0, 'F'},
00223               {"expires", required_argument, 0, 'e'},
00224               {"aggregation", required_argument, 0, 'a'},
00225               {"critical", required_argument, 0, 'c'},
00226               {"warning", required_argument, 0, 'w'},
00227               {"version", no_argument, 0, 'V'},
00228               {"help", no_argument, 0, 'h'},
00229               {0, 0, 0, 0}
00230        };
00231 
00232        if (argc < 2)
00233               return ERROR;
00234 
00235        for (c = 1; c < argc; c++) {
00236               if (strcmp ("-to", argv[c]) == 0)
00237                      strcpy (argv[c], "-t");
00238               else if (strcmp ("-wt", argv[c]) == 0)
00239                      strcpy (argv[c], "-w");
00240               else if (strcmp ("-ct", argv[c]) == 0)
00241                      strcpy (argv[c], "-c");
00242        }
00243 
00244        while (1) {
00245               c = getopt_long (argc, argv, "hVF:e:a:c:w:", longopts, &option);
00246 
00247               if (c == -1 || c == EOF)
00248                      break;
00249 
00250               switch (c) {
00251               case 'F':                                                             /* input file */
00252                      log_file = optarg;
00253                      break;
00254               case 'e':                                                             /* expiration time */
00255                      expire_minutes = atoi (optarg);
00256                      break;
00257               case 'a':                                                             /* aggregation (AVE or MAX) */
00258                      if (!strcmp (optarg, "MAX"))
00259                             use_average = FALSE;
00260                      else
00261                             use_average = TRUE;
00262                      break;
00263               case 'c':                                                             /* warning threshold */
00264                      sscanf (optarg, "%lu,%lu", &incoming_critical_threshold,
00265                                                  &outgoing_critical_threshold);
00266                      break;
00267               case 'w':                                                             /* critical threshold */
00268                      sscanf (optarg, "%lu,%lu", &incoming_warning_threshold,
00269                                                  &outgoing_warning_threshold);
00270                      break;
00271               case 'V':                                                             /* version */
00272                      print_revision (progname, NP_VERSION);
00273                      exit (STATE_OK);
00274               case 'h':                                                             /* help */
00275                      print_help ();
00276                      exit (STATE_OK);
00277               case '?':                                                             /* help */
00278                      usage5 ();
00279               }
00280        }
00281 
00282        c = optind;
00283        if (argc > c && log_file == NULL) {
00284               log_file = argv[c++];
00285        }
00286 
00287        if (argc > c && expire_minutes == -1) {
00288               expire_minutes = atoi (argv[c++]);
00289        }
00290 
00291        if (argc > c && strcmp (argv[c], "MAX") == 0) {
00292               use_average = FALSE;
00293               c++;
00294        }
00295        else if (argc > c && strcmp (argv[c], "AVG") == 0) {
00296               use_average = TRUE;
00297               c++;
00298        }
00299 
00300        if (argc > c && incoming_warning_threshold == 0) {
00301               incoming_warning_threshold = strtoul (argv[c++], NULL, 10);
00302        }
00303 
00304        if (argc > c && incoming_critical_threshold == 0) {
00305               incoming_critical_threshold = strtoul (argv[c++], NULL, 10);
00306        }
00307 
00308        if (argc > c && outgoing_warning_threshold == 0) {
00309               outgoing_warning_threshold = strtoul (argv[c++], NULL, 10);
00310        }
00311        
00312        if (argc > c && outgoing_critical_threshold == 0) {
00313               outgoing_critical_threshold = strtoul (argv[c++], NULL, 10);
00314        }
00315 
00316        return validate_arguments ();
00317 }
00318 
00319 
00320 int
00321 validate_arguments (void)
00322 {
00323        return OK;
00324 }
00325 
00326 
00327 void
00328 print_help (void)
00329 {
00330        print_revision (progname, NP_VERSION);
00331 
00332        printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
00333        printf (COPYRIGHT, copyright, email);
00334 
00335        printf ("%s\n", _("This plugin will check the incoming/outgoing transfer rates of a router,"));
00336   printf ("%s\n", _("switch, etc recorded in an MRTG log.  If the newest log entry is older"));
00337   printf ("%s\n", _("than <expire_minutes>, a WARNING status is returned. If either the"));
00338   printf ("%s\n", _("incoming or outgoing rates exceed the <icl> or <ocl> thresholds (in"));
00339   printf ("%s\n", _("Bytes/sec), a CRITICAL status results.  If either of the rates exceed"));
00340   printf ("%s\n", _("the <iwl> or <owl> thresholds (in Bytes/sec), a WARNING status results."));
00341 
00342   printf ("\n\n");
00343 
00344        print_usage ();
00345 
00346        printf (UT_HELP_VRSN);
00347        printf (UT_EXTRA_OPTS);
00348 
00349        printf (" %s\n", "-F, --filename=STRING");
00350   printf ("    %s\n", _("File to read log from"));
00351   printf (" %s\n", "-e, --expires=INTEGER");
00352   printf ("    %s\n", _("Minutes after which log expires"));
00353   printf (" %s\n", "-a, --aggregation=(AVG|MAX)");
00354   printf ("    %s\n", _("Test average or maximum"));
00355   printf (" %s\n", "-w, --warning");
00356   printf ("    %s\n", _("Warning threshold pair <incoming>,<outgoing>"));
00357   printf (" %s\n", "-c, --critical");
00358   printf ("    %s\n", _("Critical threshold pair <incoming>,<outgoing>"));
00359 
00360   printf ("\n");
00361        printf ("%s\n", _("Notes:"));
00362   printf (" %s\n", _("- MRTG stands for Multi Router Traffic Grapher. It can be downloaded from"));
00363   printf (" %s\n", "  http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
00364   printf (" %s\n", _("- While MRTG can monitor things other than traffic rates, this"));
00365   printf (" %s\n", _("  plugin probably won't work with much else without modification."));
00366   printf (" %s\n", _("- The calculated i/o rates are a little off from what MRTG actually"));
00367   printf (" %s\n", _("  reports.  I'm not sure why this is right now, but will look into it"));
00368   printf (" %s\n", _("  for future enhancements of this plugin."));
00369 
00370        printf (UT_SUPPORT);
00371 }
00372 
00373 
00374 
00375 void
00376 print_usage (void)
00377 {
00378        printf (_("Usage"));
00379   printf (" %s -F <log_file> -a <AVG | MAX> -w <warning_pair>\n",progname);
00380   printf ("-c <critical_pair> [-e expire_minutes]\n");
00381 }