check_mrtg: do not export local symbols
[monitoring-plugins.git] / plugins / check_mrtg.c
blobe82a0f9801c9b6239ebe0cb192a58bb4e94a07b4
1 /*****************************************************************************
3 * Monitoring check_mrtg plugin
5 * License: GPL
6 * Copyright (c) 1999-2024 Monitoring Plugins Development Team
8 * Description:
10 * This file contains the check_mrtg plugin
12 * This plugin will check either the average or maximum value of one of the
13 * two variables recorded in an MRTG log file.
16 * This program is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 *****************************************************************************/
32 const char *progname = "check_mrtg";
33 const char *copyright = "1999-2024";
34 const char *email = "devel@monitoring-plugins.org";
36 #include "common.h"
37 #include "utils.h"
39 static int process_arguments(int, char **);
40 static int validate_arguments(void);
41 static void print_help(void);
42 void print_usage(void);
44 static char *log_file = NULL;
45 static int expire_minutes = 0;
46 static bool use_average = true;
47 static int variable_number = -1;
48 static unsigned long value_warning_threshold = 0L;
49 static unsigned long value_critical_threshold = 0L;
50 static char *label;
51 static char *units;
53 int main(int argc, char **argv) {
54 int result = STATE_OK;
55 FILE *fp;
56 int line;
57 char input_buffer[MAX_INPUT_BUFFER];
58 char *temp_buffer;
59 time_t current_time;
60 time_t timestamp = 0L;
61 unsigned long average_value_rate = 0L;
62 unsigned long maximum_value_rate = 0L;
63 unsigned long rate = 0L;
65 setlocale(LC_ALL, "");
66 bindtextdomain(PACKAGE, LOCALEDIR);
67 textdomain(PACKAGE);
69 /* Parse extra opts if any */
70 argv = np_extra_opts(&argc, argv, progname);
72 if (process_arguments(argc, argv) == ERROR)
73 usage4(_("Could not parse arguments\n"));
75 /* open the MRTG log file for reading */
76 fp = fopen(log_file, "r");
77 if (fp == NULL) {
78 printf(_("Unable to open MRTG log file\n"));
79 return STATE_UNKNOWN;
82 line = 0;
83 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
85 line++;
87 /* skip the first line of the log file */
88 if (line == 1)
89 continue;
91 /* break out of read loop if we've passed the number of entries we want to read */
92 if (line > 2)
93 break;
95 /* grab the timestamp */
96 temp_buffer = strtok(input_buffer, " ");
97 timestamp = strtoul(temp_buffer, NULL, 10);
99 /* grab the average value 1 rate */
100 temp_buffer = strtok(NULL, " ");
101 if (variable_number == 1)
102 average_value_rate = strtoul(temp_buffer, NULL, 10);
104 /* grab the average value 2 rate */
105 temp_buffer = strtok(NULL, " ");
106 if (variable_number == 2)
107 average_value_rate = strtoul(temp_buffer, NULL, 10);
109 /* grab the maximum value 1 rate */
110 temp_buffer = strtok(NULL, " ");
111 if (variable_number == 1)
112 maximum_value_rate = strtoul(temp_buffer, NULL, 10);
114 /* grab the maximum value 2 rate */
115 temp_buffer = strtok(NULL, " ");
116 if (variable_number == 2)
117 maximum_value_rate = strtoul(temp_buffer, NULL, 10);
120 /* close the log file */
121 fclose(fp);
123 /* if we couldn't read enough data, return an unknown error */
124 if (line <= 2) {
125 printf(_("Unable to process MRTG log file\n"));
126 return STATE_UNKNOWN;
129 /* make sure the MRTG data isn't too old */
130 time(&current_time);
131 if (expire_minutes > 0 && (current_time - timestamp) > (expire_minutes * 60)) {
132 printf(_("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60));
133 return STATE_WARNING;
136 /* else check the incoming/outgoing rates */
137 if (use_average)
138 rate = average_value_rate;
139 else
140 rate = maximum_value_rate;
142 if (rate > value_critical_threshold)
143 result = STATE_CRITICAL;
144 else if (rate > value_warning_threshold)
145 result = STATE_WARNING;
147 printf("%s. %s = %lu %s|%s\n", (use_average) ? _("Avg") : _("Max"), label, rate, units,
148 perfdata(label, (long)rate, units, (int)value_warning_threshold, (long)value_warning_threshold, (int)value_critical_threshold,
149 (long)value_critical_threshold, 0, 0, 0, 0));
151 return result;
154 /* process command-line arguments */
155 int process_arguments(int argc, char **argv) {
156 int c;
158 int option = 0;
159 static struct option longopts[] = {
160 {"logfile", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'}, {"aggregation", required_argument, 0, 'a'},
161 {"variable", required_argument, 0, 'v'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'},
162 {"label", required_argument, 0, 'l'}, {"units", required_argument, 0, 'u'}, {"variable", required_argument, 0, 'v'},
163 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
165 if (argc < 2)
166 return ERROR;
168 for (c = 1; c < argc; c++) {
169 if (strcmp("-to", argv[c]) == 0)
170 strcpy(argv[c], "-t");
171 else if (strcmp("-wt", argv[c]) == 0)
172 strcpy(argv[c], "-w");
173 else if (strcmp("-ct", argv[c]) == 0)
174 strcpy(argv[c], "-c");
177 while (1) {
178 c = getopt_long(argc, argv, "hVF:e:a:v:c:w:l:u:", longopts, &option);
180 if (c == -1 || c == EOF)
181 break;
183 switch (c) {
184 case 'F': /* input file */
185 log_file = optarg;
186 break;
187 case 'e': /* ups name */
188 expire_minutes = atoi(optarg);
189 break;
190 case 'a': /* port */
191 if (!strcmp(optarg, "MAX"))
192 use_average = false;
193 else
194 use_average = true;
195 break;
196 case 'v':
197 variable_number = atoi(optarg);
198 if (variable_number < 1 || variable_number > 2)
199 usage4(_("Invalid variable number"));
200 break;
201 case 'w': /* critical time threshold */
202 value_warning_threshold = strtoul(optarg, NULL, 10);
203 break;
204 case 'c': /* warning time threshold */
205 value_critical_threshold = strtoul(optarg, NULL, 10);
206 break;
207 case 'l': /* label */
208 label = optarg;
209 break;
210 case 'u': /* timeout */
211 units = optarg;
212 break;
213 case 'V': /* version */
214 print_revision(progname, NP_VERSION);
215 exit(STATE_UNKNOWN);
216 case 'h': /* help */
217 print_help();
218 exit(STATE_UNKNOWN);
219 case '?': /* help */
220 usage5();
224 c = optind;
225 if (log_file == NULL && argc > c) {
226 log_file = argv[c++];
229 if (expire_minutes <= 0 && argc > c) {
230 if (is_intpos(argv[c]))
231 expire_minutes = atoi(argv[c++]);
232 else
233 die(STATE_UNKNOWN, _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), argv[c], progname);
236 if (argc > c && strcmp(argv[c], "MAX") == 0) {
237 use_average = false;
238 c++;
239 } else if (argc > c && strcmp(argv[c], "AVG") == 0) {
240 use_average = true;
241 c++;
244 if (argc > c && variable_number == -1) {
245 variable_number = atoi(argv[c++]);
246 if (variable_number < 1 || variable_number > 2) {
247 printf("%s :", argv[c]);
248 usage(_("Invalid variable number\n"));
252 if (argc > c && value_warning_threshold == 0) {
253 value_warning_threshold = strtoul(argv[c++], NULL, 10);
256 if (argc > c && value_critical_threshold == 0) {
257 value_critical_threshold = strtoul(argv[c++], NULL, 10);
260 if (argc > c && strlen(label) == 0) {
261 label = argv[c++];
264 if (argc > c && strlen(units) == 0) {
265 units = argv[c++];
268 return validate_arguments();
271 int validate_arguments(void) {
272 if (variable_number == -1)
273 usage4(_("You must supply the variable number"));
275 if (label == NULL)
276 label = strdup("value");
278 if (units == NULL)
279 units = strdup("");
281 return OK;
284 void print_help(void) {
285 print_revision(progname, NP_VERSION);
287 printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
288 printf(COPYRIGHT, copyright, email);
290 printf("%s\n", _("This plugin will check either the average or maximum value of one of the"));
291 printf("%s\n", _("two variables recorded in an MRTG log file."));
293 printf("\n\n");
295 print_usage();
297 printf(UT_HELP_VRSN);
298 printf(UT_EXTRA_OPTS);
300 printf(" %s\n", "-F, --logfile=FILE");
301 printf(" %s\n", _("The MRTG log file containing the data you want to monitor"));
302 printf(" %s\n", "-e, --expires=MINUTES");
303 printf(" %s\n", _("Minutes before MRTG data is considered to be too old"));
304 printf(" %s\n", "-a, --aggregation=AVG|MAX");
305 printf(" %s\n", _("Should we check average or maximum values?"));
306 printf(" %s\n", "-v, --variable=INTEGER");
307 printf(" %s\n", _("Which variable set should we inspect? (1 or 2)"));
308 printf(" %s\n", "-w, --warning=INTEGER");
309 printf(" %s\n", _("Threshold value for data to result in WARNING status"));
310 printf(" %s\n", "-c, --critical=INTEGER");
311 printf(" %s\n", _("Threshold value for data to result in CRITICAL status"));
312 printf(" %s\n", "-l, --label=STRING");
313 printf(" %s\n", _("Type label for data (Examples: Conns, \"Processor Load\", In, Out)"));
314 printf(" %s\n", "-u, --units=STRING");
315 printf(" %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,"));
316 printf(" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")"));
318 printf("\n");
319 printf(" %s\n", _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If"));
320 printf(" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned. If"));
321 printf(" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING"));
322 printf(" %s\n", _("status is returned and a warning message is printed."));
324 printf("\n");
325 printf(" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to"));
326 printf(" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth)."));
327 printf(" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,"));
328 printf(" %s\n", _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"));
329 printf(" %s\n", _("me to track processor utilization, user connections, drive space, etc and"));
330 printf(" %s\n\n", _("this plugin works well for monitoring that kind of data as well."));
332 printf("%s\n", _("Notes:"));
333 printf(" %s\n", _("- This plugin only monitors one of the two variables stored in the MRTG log"));
334 printf(" %s\n", _("file. If you want to monitor both values you will have to define two"));
335 printf(" %s\n", _("commands with different values for the <variable> argument. Of course,"));
336 printf(" %s\n", _("you can always hack the code to make this plugin work for you..."));
337 printf(" %s\n", _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from"));
338 printf(" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
340 printf(UT_SUPPORT);
343 /* original command line:
344 <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
346 void print_usage(void) {
347 printf("%s\n", _("Usage:"));
348 printf("%s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n", progname);
349 printf("[-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n");