summaryrefslogtreecommitdiffstats
path: root/plugins/check_mrtg.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_mrtg.c')
-rw-r--r--plugins/check_mrtg.c177
1 files changed, 130 insertions, 47 deletions
diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c
index 5bd276dc..cdc2a035 100644
--- a/plugins/check_mrtg.c
+++ b/plugins/check_mrtg.c
@@ -29,14 +29,18 @@
29 * 29 *
30 *****************************************************************************/ 30 *****************************************************************************/
31 31
32const char *progname = "check_mrtg";
33const char *copyright = "1999-2024";
34const char *email = "devel@monitoring-plugins.org";
35
36#include "common.h" 32#include "common.h"
33#include "output.h"
34#include "perfdata.h"
35#include "states.h"
36#include "thresholds.h"
37#include "utils.h" 37#include "utils.h"
38#include "check_mrtg.d/config.h" 38#include "check_mrtg.d/config.h"
39 39
40const char *progname = "check_mrtg";
41const char *copyright = "1999-2024";
42const char *email = "devel@monitoring-plugins.org";
43
40typedef struct { 44typedef struct {
41 int errorcode; 45 int errorcode;
42 check_mrtg_config config; 46 check_mrtg_config config;
@@ -62,11 +66,24 @@ int main(int argc, char **argv) {
62 66
63 const check_mrtg_config config = tmp_config.config; 67 const check_mrtg_config config = tmp_config.config;
64 68
69 if (config.output_format_is_set) {
70 mp_set_format(config.output_format);
71 }
72
73 mp_check overall = mp_check_init();
74
65 /* open the MRTG log file for reading */ 75 /* open the MRTG log file for reading */
76 mp_subcheck sc_open_mrtg_log_file = mp_subcheck_init();
66 FILE *mtrg_log_file = fopen(config.log_file, "r"); 77 FILE *mtrg_log_file = fopen(config.log_file, "r");
67 if (mtrg_log_file == NULL) { 78 if (mtrg_log_file == NULL) {
68 printf(_("Unable to open MRTG log file\n")); 79 xasprintf(&sc_open_mrtg_log_file.output, "unable to open MRTG log file");
69 return STATE_UNKNOWN; 80 sc_open_mrtg_log_file = mp_set_subcheck_state(sc_open_mrtg_log_file, STATE_UNKNOWN);
81 mp_add_subcheck_to_check(&overall, sc_open_mrtg_log_file);
82 mp_exit(overall);
83 } else {
84 xasprintf(&sc_open_mrtg_log_file.output, "opened MRTG log file");
85 sc_open_mrtg_log_file = mp_set_subcheck_state(sc_open_mrtg_log_file, STATE_OK);
86 mp_add_subcheck_to_check(&overall, sc_open_mrtg_log_file);
70 } 87 }
71 88
72 time_t timestamp = 0; 89 time_t timestamp = 0;
@@ -120,17 +137,32 @@ int main(int argc, char **argv) {
120 fclose(mtrg_log_file); 137 fclose(mtrg_log_file);
121 138
122 /* if we couldn't read enough data, return an unknown error */ 139 /* if we couldn't read enough data, return an unknown error */
140 mp_subcheck sc_process_mrtg_log_file = mp_subcheck_init();
123 if (line <= 2) { 141 if (line <= 2) {
124 printf(_("Unable to process MRTG log file\n")); 142 xasprintf(&sc_process_mrtg_log_file.output, "unable to process MRTG log file");
125 return STATE_UNKNOWN; 143 sc_process_mrtg_log_file = mp_set_subcheck_state(sc_process_mrtg_log_file, STATE_UNKNOWN);
144 mp_exit(overall);
145 } else {
146 xasprintf(&sc_process_mrtg_log_file.output, "processed MRTG log file");
147 sc_process_mrtg_log_file = mp_set_subcheck_state(sc_process_mrtg_log_file, STATE_OK);
148 mp_add_subcheck_to_check(&overall, sc_process_mrtg_log_file);
126 } 149 }
127 150
128 /* make sure the MRTG data isn't too old */ 151 /* make sure the MRTG data isn't too old */
129 time_t current_time; 152 time_t current_time;
130 time(&current_time); 153 time(&current_time);
154 mp_subcheck sc_data_expired = mp_subcheck_init();
131 if (config.expire_minutes > 0 && (current_time - timestamp) > (config.expire_minutes * 60)) { 155 if (config.expire_minutes > 0 && (current_time - timestamp) > (config.expire_minutes * 60)) {
132 printf(_("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60)); 156 xasprintf(&sc_data_expired.output, "MRTG data has expired (%d minutes old)",
133 return STATE_WARNING; 157 (int)((current_time - timestamp) / 60));
158 sc_data_expired = mp_set_subcheck_state(sc_data_expired, STATE_WARNING);
159 mp_add_subcheck_to_check(&overall, sc_data_expired);
160 mp_exit(overall);
161 } else {
162 xasprintf(&sc_data_expired.output, "MRTG data should be valid (%d minutes old)",
163 (int)((current_time - timestamp) / 60));
164 sc_data_expired = mp_set_subcheck_state(sc_data_expired, STATE_OK);
165 mp_add_subcheck_to_check(&overall, sc_data_expired);
134 } 166 }
135 167
136 unsigned long rate = 0L; 168 unsigned long rate = 0L;
@@ -141,27 +173,40 @@ int main(int argc, char **argv) {
141 rate = maximum_value_rate; 173 rate = maximum_value_rate;
142 } 174 }
143 175
144 int result = STATE_OK; 176 mp_subcheck sc_values = mp_subcheck_init();
145 if (config.value_critical_threshold_set && rate > config.value_critical_threshold) { 177 mp_perfdata pd_value = perfdata_init();
146 result = STATE_CRITICAL; 178 pd_value = mp_set_pd_value(pd_value, rate);
147 } else if (config.value_warning_threshold_set && rate > config.value_warning_threshold) { 179 pd_value.label = config.label;
148 result = STATE_WARNING; 180 pd_value = mp_pd_set_thresholds(pd_value, config.values_threshold);
149 }
150 181
151 printf("%s. %s = %lu %s|%s\n", (config.use_average) ? _("Avg") : _("Max"), config.label, rate, config.units, 182 sc_values = mp_set_subcheck_state(sc_values, mp_get_pd_status(pd_value));
152 perfdata(config.label, (long)rate, config.units, config.value_warning_threshold_set, (long)config.value_warning_threshold, 183 xasprintf(&sc_values.output, "%s. %s = %lu %s", (config.use_average) ? _("Avg") : _("Max"),
153 config.value_critical_threshold_set, (long)config.value_critical_threshold, 0, 0, 0, 0)); 184 config.label, rate, config.units);
154 185
155 return result; 186 mp_add_subcheck_to_check(&overall, sc_values);
187
188 mp_exit(overall);
156} 189}
157 190
158/* process command-line arguments */ 191/* process command-line arguments */
159check_mrtg_config_wrapper process_arguments(int argc, char **argv) { 192check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
160 static struct option longopts[] = { 193 enum {
161 {"logfile", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'}, {"aggregation", required_argument, 0, 'a'}, 194 output_format_index,
162 {"variable", required_argument, 0, 'v'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, 195 };
163 {"label", required_argument, 0, 'l'}, {"units", required_argument, 0, 'u'}, {"variable", required_argument, 0, 'v'}, 196
164 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; 197 static struct option longopts[] = {{"logfile", required_argument, 0, 'F'},
198 {"expires", required_argument, 0, 'e'},
199 {"aggregation", required_argument, 0, 'a'},
200 {"variable", required_argument, 0, 'v'},
201 {"critical", required_argument, 0, 'c'},
202 {"warning", required_argument, 0, 'w'},
203 {"label", required_argument, 0, 'l'},
204 {"units", required_argument, 0, 'u'},
205 {"variable", required_argument, 0, 'v'},
206 {"version", no_argument, 0, 'V'},
207 {"help", no_argument, 0, 'h'},
208 {"output-format", required_argument, 0, output_format_index},
209 {0, 0, 0, 0}};
165 210
166 check_mrtg_config_wrapper result = { 211 check_mrtg_config_wrapper result = {
167 .errorcode = OK, 212 .errorcode = OK,
@@ -208,14 +253,22 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
208 usage4(_("Invalid variable number")); 253 usage4(_("Invalid variable number"));
209 } 254 }
210 break; 255 break;
211 case 'w': /* critical time threshold */ 256 case 'w': /* critical time threshold */ {
212 result.config.value_warning_threshold_set = true; 257 mp_range_parsed tmp = mp_parse_range_string(optarg);
213 result.config.value_warning_threshold = strtoul(optarg, NULL, 10); 258 if (tmp.error != MP_PARSING_SUCCES) {
214 break; 259 die(STATE_UNKNOWN, "failed to parse warning threshold");
215 case 'c': /* warning time threshold */ 260 }
216 result.config.value_critical_threshold_set = true; 261 result.config.values_threshold =
217 result.config.value_critical_threshold = strtoul(optarg, NULL, 10); 262 mp_thresholds_set_warn(result.config.values_threshold, tmp.range);
218 break; 263 } break;
264 case 'c': /* warning time threshold */ {
265 mp_range_parsed tmp = mp_parse_range_string(optarg);
266 if (tmp.error != MP_PARSING_SUCCES) {
267 die(STATE_UNKNOWN, "failed to parse critical threshold");
268 }
269 result.config.values_threshold =
270 mp_thresholds_set_crit(result.config.values_threshold, tmp.range);
271 } break;
219 case 'l': /* label */ 272 case 'l': /* label */
220 result.config.label = optarg; 273 result.config.label = optarg;
221 break; 274 break;
@@ -230,6 +283,17 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
230 exit(STATE_UNKNOWN); 283 exit(STATE_UNKNOWN);
231 case '?': /* help */ 284 case '?': /* help */
232 usage5(); 285 usage5();
286 case output_format_index: {
287 parsed_output_format parser = mp_parse_output_format(optarg);
288 if (!parser.parsing_success) {
289 printf("Invalid output format: %s\n", optarg);
290 exit(STATE_UNKNOWN);
291 }
292
293 result.config.output_format_is_set = true;
294 result.config.output_format = parser.output_format;
295 break;
296 }
233 } 297 }
234 } 298 }
235 299
@@ -242,7 +306,9 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
242 if (is_intpos(argv[option_char])) { 306 if (is_intpos(argv[option_char])) {
243 result.config.expire_minutes = atoi(argv[option_char++]); 307 result.config.expire_minutes = atoi(argv[option_char++]);
244 } else { 308 } else {
245 die(STATE_UNKNOWN, _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), argv[option_char], progname); 309 die(STATE_UNKNOWN,
310 _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
311 argv[option_char], progname);
246 } 312 }
247 } 313 }
248 314
@@ -262,14 +328,22 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
262 } 328 }
263 } 329 }
264 330
265 if (argc > option_char && !result.config.value_warning_threshold_set) { 331 if (argc > option_char && !result.config.values_threshold.warning_is_set) {
266 result.config.value_warning_threshold_set = true; 332 mp_range_parsed tmp = mp_parse_range_string(argv[option_char++]);
267 result.config.value_warning_threshold = strtoul(argv[option_char++], NULL, 10); 333 if (tmp.error != MP_PARSING_SUCCES) {
334 die(STATE_UNKNOWN, "failed to parse warning threshold");
335 }
336 result.config.values_threshold =
337 mp_thresholds_set_warn(result.config.values_threshold, tmp.range);
268 } 338 }
269 339
270 if (argc > option_char && !result.config.value_critical_threshold_set) { 340 if (argc > option_char && !result.config.values_threshold.critical_is_set) {
271 result.config.value_critical_threshold_set = true; 341 mp_range_parsed tmp = mp_parse_range_string(argv[option_char++]);
272 result.config.value_critical_threshold = strtoul(argv[option_char++], NULL, 10); 342 if (tmp.error != MP_PARSING_SUCCES) {
343 die(STATE_UNKNOWN, "failed to parse critical threshold");
344 }
345 result.config.values_threshold =
346 mp_thresholds_set_crit(result.config.values_threshold, tmp.range);
273 } 347 }
274 348
275 if (argc > option_char && strlen(result.config.label) == 0) { 349 if (argc > option_char && strlen(result.config.label) == 0) {
@@ -333,26 +407,35 @@ void print_help(void) {
333 printf(" %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,")); 407 printf(" %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,"));
334 printf(" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")")); 408 printf(" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")"));
335 409
410 printf(UT_OUTPUT_FORMAT);
411
336 printf("\n"); 412 printf("\n");
337 printf(" %s\n", _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If")); 413 printf(" %s\n",
414 _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If"));
338 printf(" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned. If")); 415 printf(" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned. If"));
339 printf(" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING")); 416 printf(" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING"));
340 printf(" %s\n", _("status is returned and a warning message is printed.")); 417 printf(" %s\n", _("status is returned and a warning message is printed."));
341 418
342 printf("\n"); 419 printf("\n");
343 printf(" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to")); 420 printf(" %s\n",
344 printf(" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).")); 421 _("This plugin is useful for monitoring MRTG data that does not correspond to"));
345 printf(" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,")); 422 printf(" %s\n",
346 printf(" %s\n", _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows")); 423 _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth)."));
424 printf(" %s\n",
425 _("It can be used to monitor any kind of data that MRTG is monitoring - errors,"));
426 printf(" %s\n",
427 _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"));
347 printf(" %s\n", _("me to track processor utilization, user connections, drive space, etc and")); 428 printf(" %s\n", _("me to track processor utilization, user connections, drive space, etc and"));
348 printf(" %s\n\n", _("this plugin works well for monitoring that kind of data as well.")); 429 printf(" %s\n\n", _("this plugin works well for monitoring that kind of data as well."));
349 430
350 printf("%s\n", _("Notes:")); 431 printf("%s\n", _("Notes:"));
351 printf(" %s\n", _("- This plugin only monitors one of the two variables stored in the MRTG log")); 432 printf(" %s\n",
433 _("- This plugin only monitors one of the two variables stored in the MRTG log"));
352 printf(" %s\n", _("file. If you want to monitor both values you will have to define two")); 434 printf(" %s\n", _("file. If you want to monitor both values you will have to define two"));
353 printf(" %s\n", _("commands with different values for the <variable> argument. Of course,")); 435 printf(" %s\n", _("commands with different values for the <variable> argument. Of course,"));
354 printf(" %s\n", _("you can always hack the code to make this plugin work for you...")); 436 printf(" %s\n", _("you can always hack the code to make this plugin work for you..."));
355 printf(" %s\n", _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from")); 437 printf(" %s\n",
438 _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from"));
356 printf(" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html"); 439 printf(" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
357 440
358 printf(UT_SUPPORT); 441 printf(UT_SUPPORT);