1 /*****************************************************************************
3 * Monitoring check_mrtg plugin
6 * Copyright (c) 1999-2024 Monitoring Plugins Development Team
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";
39 static int process_arguments(int /*argc*/, char ** /*argv*/);
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;
53 int main(int argc
, char **argv
) {
54 setlocale(LC_ALL
, "");
55 bindtextdomain(PACKAGE
, LOCALEDIR
);
58 /* Parse extra opts if any */
59 argv
= np_extra_opts(&argc
, argv
, progname
);
61 if (process_arguments(argc
, argv
) == ERROR
)
62 usage4(_("Could not parse arguments\n"));
64 /* open the MRTG log file for reading */
65 FILE *mtrg_log_file
= fopen(log_file
, "r");
66 if (mtrg_log_file
== NULL
) {
67 printf(_("Unable to open MRTG log file\n"));
71 time_t timestamp
= 0L;
72 unsigned long average_value_rate
= 0L;
73 unsigned long maximum_value_rate
= 0L;
74 char input_buffer
[MAX_INPUT_BUFFER
];
76 while (fgets(input_buffer
, MAX_INPUT_BUFFER
- 1, mtrg_log_file
)) {
80 /* skip the first line of the log file */
84 /* break out of read loop if we've passed the number of entries we want to read */
88 /* grab the timestamp */
89 char *temp_buffer
= strtok(input_buffer
, " ");
90 timestamp
= strtoul(temp_buffer
, NULL
, 10);
92 /* grab the average value 1 rate */
93 temp_buffer
= strtok(NULL
, " ");
94 if (variable_number
== 1)
95 average_value_rate
= strtoul(temp_buffer
, NULL
, 10);
97 /* grab the average value 2 rate */
98 temp_buffer
= strtok(NULL
, " ");
99 if (variable_number
== 2)
100 average_value_rate
= strtoul(temp_buffer
, NULL
, 10);
102 /* grab the maximum value 1 rate */
103 temp_buffer
= strtok(NULL
, " ");
104 if (variable_number
== 1)
105 maximum_value_rate
= strtoul(temp_buffer
, NULL
, 10);
107 /* grab the maximum value 2 rate */
108 temp_buffer
= strtok(NULL
, " ");
109 if (variable_number
== 2)
110 maximum_value_rate
= strtoul(temp_buffer
, NULL
, 10);
113 /* close the log file */
114 fclose(mtrg_log_file
);
116 /* if we couldn't read enough data, return an unknown error */
118 printf(_("Unable to process MRTG log file\n"));
119 return STATE_UNKNOWN
;
122 /* make sure the MRTG data isn't too old */
125 if (expire_minutes
> 0 && (current_time
- timestamp
) > (expire_minutes
* 60)) {
126 printf(_("MRTG data has expired (%d minutes old)\n"), (int)((current_time
- timestamp
) / 60));
127 return STATE_WARNING
;
130 unsigned long rate
= 0L;
131 /* else check the incoming/outgoing rates */
133 rate
= average_value_rate
;
135 rate
= maximum_value_rate
;
137 int result
= STATE_OK
;
138 if (rate
> value_critical_threshold
)
139 result
= STATE_CRITICAL
;
140 else if (rate
> value_warning_threshold
)
141 result
= STATE_WARNING
;
143 printf("%s. %s = %lu %s|%s\n", (use_average
) ? _("Avg") : _("Max"), label
, rate
, units
,
144 perfdata(label
, (long)rate
, units
, (int)value_warning_threshold
, (long)value_warning_threshold
, (int)value_critical_threshold
,
145 (long)value_critical_threshold
, 0, 0, 0, 0));
150 /* process command-line arguments */
151 int process_arguments(int argc
, char **argv
) {
152 static struct option longopts
[] = {
153 {"logfile", required_argument
, 0, 'F'}, {"expires", required_argument
, 0, 'e'}, {"aggregation", required_argument
, 0, 'a'},
154 {"variable", required_argument
, 0, 'v'}, {"critical", required_argument
, 0, 'c'}, {"warning", required_argument
, 0, 'w'},
155 {"label", required_argument
, 0, 'l'}, {"units", required_argument
, 0, 'u'}, {"variable", required_argument
, 0, 'v'},
156 {"version", no_argument
, 0, 'V'}, {"help", no_argument
, 0, 'h'}, {0, 0, 0, 0}};
161 for (int i
= 1; i
< argc
; i
++) {
162 if (strcmp("-to", argv
[i
]) == 0)
163 strcpy(argv
[i
], "-t");
164 else if (strcmp("-wt", argv
[i
]) == 0)
165 strcpy(argv
[i
], "-w");
166 else if (strcmp("-ct", argv
[i
]) == 0)
167 strcpy(argv
[i
], "-c");
173 option_char
= getopt_long(argc
, argv
, "hVF:e:a:v:c:w:l:u:", longopts
, &option
);
175 if (option_char
== -1 || option_char
== EOF
)
178 switch (option_char
) {
179 case 'F': /* input file */
182 case 'e': /* ups name */
183 expire_minutes
= atoi(optarg
);
186 if (!strcmp(optarg
, "MAX"))
192 variable_number
= atoi(optarg
);
193 if (variable_number
< 1 || variable_number
> 2)
194 usage4(_("Invalid variable number"));
196 case 'w': /* critical time threshold */
197 value_warning_threshold
= strtoul(optarg
, NULL
, 10);
199 case 'c': /* warning time threshold */
200 value_critical_threshold
= strtoul(optarg
, NULL
, 10);
202 case 'l': /* label */
205 case 'u': /* timeout */
208 case 'V': /* version */
209 print_revision(progname
, NP_VERSION
);
219 option_char
= optind
;
220 if (log_file
== NULL
&& argc
> option_char
) {
221 log_file
= argv
[option_char
++];
224 if (expire_minutes
<= 0 && argc
> option_char
) {
225 if (is_intpos(argv
[option_char
]))
226 expire_minutes
= atoi(argv
[option_char
++]);
228 die(STATE_UNKNOWN
, _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), argv
[option_char
], progname
);
231 if (argc
> option_char
&& strcmp(argv
[option_char
], "MAX") == 0) {
234 } else if (argc
> option_char
&& strcmp(argv
[option_char
], "AVG") == 0) {
239 if (argc
> option_char
&& variable_number
== -1) {
240 variable_number
= atoi(argv
[option_char
++]);
241 if (variable_number
< 1 || variable_number
> 2) {
242 printf("%s :", argv
[option_char
]);
243 usage(_("Invalid variable number\n"));
247 if (argc
> option_char
&& value_warning_threshold
== 0) {
248 value_warning_threshold
= strtoul(argv
[option_char
++], NULL
, 10);
251 if (argc
> option_char
&& value_critical_threshold
== 0) {
252 value_critical_threshold
= strtoul(argv
[option_char
++], NULL
, 10);
255 if (argc
> option_char
&& strlen(label
) == 0) {
256 label
= argv
[option_char
++];
259 if (argc
> option_char
&& strlen(units
) == 0) {
260 units
= argv
[option_char
++];
263 return validate_arguments();
266 int validate_arguments(void) {
267 if (variable_number
== -1)
268 usage4(_("You must supply the variable number"));
271 label
= strdup("value");
279 void print_help(void) {
280 print_revision(progname
, NP_VERSION
);
282 printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
283 printf(COPYRIGHT
, copyright
, email
);
285 printf("%s\n", _("This plugin will check either the average or maximum value of one of the"));
286 printf("%s\n", _("two variables recorded in an MRTG log file."));
292 printf(UT_HELP_VRSN
);
293 printf(UT_EXTRA_OPTS
);
295 printf(" %s\n", "-F, --logfile=FILE");
296 printf(" %s\n", _("The MRTG log file containing the data you want to monitor"));
297 printf(" %s\n", "-e, --expires=MINUTES");
298 printf(" %s\n", _("Minutes before MRTG data is considered to be too old"));
299 printf(" %s\n", "-a, --aggregation=AVG|MAX");
300 printf(" %s\n", _("Should we check average or maximum values?"));
301 printf(" %s\n", "-v, --variable=INTEGER");
302 printf(" %s\n", _("Which variable set should we inspect? (1 or 2)"));
303 printf(" %s\n", "-w, --warning=INTEGER");
304 printf(" %s\n", _("Threshold value for data to result in WARNING status"));
305 printf(" %s\n", "-c, --critical=INTEGER");
306 printf(" %s\n", _("Threshold value for data to result in CRITICAL status"));
307 printf(" %s\n", "-l, --label=STRING");
308 printf(" %s\n", _("Type label for data (Examples: Conns, \"Processor Load\", In, Out)"));
309 printf(" %s\n", "-u, --units=STRING");
310 printf(" %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,"));
311 printf(" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")"));
314 printf(" %s\n", _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If"));
315 printf(" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned. If"));
316 printf(" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING"));
317 printf(" %s\n", _("status is returned and a warning message is printed."));
320 printf(" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to"));
321 printf(" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth)."));
322 printf(" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,"));
323 printf(" %s\n", _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"));
324 printf(" %s\n", _("me to track processor utilization, user connections, drive space, etc and"));
325 printf(" %s\n\n", _("this plugin works well for monitoring that kind of data as well."));
327 printf("%s\n", _("Notes:"));
328 printf(" %s\n", _("- This plugin only monitors one of the two variables stored in the MRTG log"));
329 printf(" %s\n", _("file. If you want to monitor both values you will have to define two"));
330 printf(" %s\n", _("commands with different values for the <variable> argument. Of course,"));
331 printf(" %s\n", _("you can always hack the code to make this plugin work for you..."));
332 printf(" %s\n", _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from"));
333 printf(" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
338 /* original command line:
339 <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
341 void print_usage(void) {
342 printf("%s\n", _("Usage:"));
343 printf("%s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n", progname
);
344 printf("[-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n");