summaryrefslogtreecommitdiffstats
path: root/plugins/check_mrtgtraf.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-11-28 00:35:51 +0100
committerGitHub <noreply@github.com>2025-11-28 00:35:51 +0100
commit16db5eed1e5c59493506fef4e69d564ee8e607ca (patch)
treee76f090874e11942c889e6acaf2bbc798d62120f /plugins/check_mrtgtraf.c
parent7827b55bbf3e0909b263f4e756c8dfcd12243b78 (diff)
parentcd7698a41945cdfe4cfe0e70cc9812f0c895b8db (diff)
downloadmonitoring-plugins-16db5eed1e5c59493506fef4e69d564ee8e607ca.tar.gz
Merge pull request #2183 from RincewindsHat/modern_output/check_mrtgtraf
check_mrtgtraf: modern output implementation
Diffstat (limited to 'plugins/check_mrtgtraf.c')
-rw-r--r--plugins/check_mrtgtraf.c219
1 files changed, 158 insertions, 61 deletions
diff --git a/plugins/check_mrtgtraf.c b/plugins/check_mrtgtraf.c
index 10ce936f..46b94f57 100644
--- a/plugins/check_mrtgtraf.c
+++ b/plugins/check_mrtgtraf.c
@@ -29,14 +29,18 @@
29 * 29 *
30 *****************************************************************************/ 30 *****************************************************************************/
31 31
32const char *progname = "check_mrtgtraf";
33const char *copyright = "1999-2024";
34const char *email = "devel@monitoring-plugins.org";
35
36#include "check_mrtgtraf.d/config.h" 32#include "check_mrtgtraf.d/config.h"
37#include "common.h" 33#include "common.h"
34#include "output.h"
35#include "perfdata.h"
36#include "states.h"
37#include "thresholds.h"
38#include "utils.h" 38#include "utils.h"
39 39
40const char *progname = "check_mrtgtraf";
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_mrtgtraf_config config; 46 check_mrtgtraf_config config;
@@ -61,10 +65,24 @@ int main(int argc, char **argv) {
61 65
62 const check_mrtgtraf_config config = tmp_config.config; 66 const check_mrtgtraf_config config = tmp_config.config;
63 67
68 if (config.output_format_is_set) {
69 mp_set_format(config.output_format);
70 }
71
72 mp_check overall = mp_check_init();
73 mp_subcheck sc_open_mrtg_log_file = mp_subcheck_init();
74
64 /* open the MRTG log file for reading */ 75 /* open the MRTG log file for reading */
65 FILE *mrtg_log_file_ptr = fopen(config.log_file, "r"); 76 FILE *mrtg_log_file_ptr = fopen(config.log_file, "r");
66 if (mrtg_log_file_ptr == NULL) { 77 if (mrtg_log_file_ptr == NULL) {
67 usage4(_("Unable to open MRTG log file")); 78 sc_open_mrtg_log_file = mp_set_subcheck_state(sc_open_mrtg_log_file, STATE_UNKNOWN);
79 xasprintf(&sc_open_mrtg_log_file.output, "unable to open MRTG log file");
80 mp_add_subcheck_to_check(&overall, sc_open_mrtg_log_file);
81 mp_exit(overall);
82 } else {
83 sc_open_mrtg_log_file = mp_set_subcheck_state(sc_open_mrtg_log_file, STATE_OK);
84 xasprintf(&sc_open_mrtg_log_file.output, "opened MRTG log file");
85 mp_add_subcheck_to_check(&overall, sc_open_mrtg_log_file);
68 } 86 }
69 87
70 time_t timestamp = 0L; 88 time_t timestamp = 0L;
@@ -75,7 +93,6 @@ int main(int argc, char **argv) {
75 unsigned long maximum_outgoing_rate = 0L; 93 unsigned long maximum_outgoing_rate = 0L;
76 int line = 0; 94 int line = 0;
77 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, mrtg_log_file_ptr)) { 95 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, mrtg_log_file_ptr)) {
78
79 line++; 96 line++;
80 97
81 /* skip the first line of the log file */ 98 /* skip the first line of the log file */
@@ -121,11 +138,20 @@ int main(int argc, char **argv) {
121 /* make sure the MRTG data isn't too old */ 138 /* make sure the MRTG data isn't too old */
122 time_t current_time; 139 time_t current_time;
123 time(&current_time); 140 time(&current_time);
141 mp_subcheck sc_expired = mp_subcheck_init();
124 if ((config.expire_minutes > 0) && (current_time - timestamp) > (config.expire_minutes * 60)) { 142 if ((config.expire_minutes > 0) && (current_time - timestamp) > (config.expire_minutes * 60)) {
125 die(STATE_WARNING, _("MRTG data has expired (%d minutes old)\n"), 143 xasprintf(&sc_expired.output, "MRTG data has expired (%d minutes old)",
126 (int)((current_time - timestamp) / 60)); 144 (int)((current_time - timestamp) / 60));
145 sc_expired = mp_set_subcheck_state(sc_expired, STATE_WARNING);
146 mp_add_subcheck_to_check(&overall, sc_expired);
147 mp_exit(overall);
127 } 148 }
128 149
150 xasprintf(&sc_expired.output, "MRTG data should be valid (%d minutes old)",
151 (int)((current_time - timestamp) / 60));
152 sc_expired = mp_set_subcheck_state(sc_expired, STATE_WARNING);
153 mp_add_subcheck_to_check(&overall, sc_expired);
154
129 unsigned long incoming_rate = 0L; 155 unsigned long incoming_rate = 0L;
130 unsigned long outgoing_rate = 0L; 156 unsigned long outgoing_rate = 0L;
131 /* else check the incoming/outgoing rates */ 157 /* else check the incoming/outgoing rates */
@@ -148,65 +174,72 @@ int main(int argc, char **argv) {
148 /* report incoming traffic in KBytes/sec */ 174 /* report incoming traffic in KBytes/sec */
149 else if (incoming_rate < (1024 * 1024)) { 175 else if (incoming_rate < (1024 * 1024)) {
150 strcpy(incoming_speed_rating, "KB"); 176 strcpy(incoming_speed_rating, "KB");
151 adjusted_incoming_rate = (double)(incoming_rate / 1024.0); 177 adjusted_incoming_rate = ((double)incoming_rate / 1024.0);
152 } 178 }
153 179
154 /* report incoming traffic in MBytes/sec */ 180 /* report incoming traffic in MBytes/sec */
155 else { 181 else {
156 strcpy(incoming_speed_rating, "MB"); 182 strcpy(incoming_speed_rating, "MB");
157 adjusted_incoming_rate = (double)(incoming_rate / 1024.0 / 1024.0); 183 adjusted_incoming_rate = ((double)incoming_rate / 1024.0 / 1024.0);
158 } 184 }
159 185
160 double adjusted_outgoing_rate = 0.0; 186 double adjusted_outgoing_rate = 0.0;
161 char outgoing_speed_rating[8]; 187 char outgoing_speed_rating[8];
162 /* report outgoing traffic in Bytes/sec */
163 if (outgoing_rate < 1024) { 188 if (outgoing_rate < 1024) {
189 /* report outgoing traffic in Bytes/sec */
164 strcpy(outgoing_speed_rating, "B"); 190 strcpy(outgoing_speed_rating, "B");
165 adjusted_outgoing_rate = (double)outgoing_rate; 191 adjusted_outgoing_rate = (double)outgoing_rate;
166 } 192 } else if (outgoing_rate < (1024 * 1024)) {
167 193 /* report outgoing traffic in KBytes/sec */
168 /* report outgoing traffic in KBytes/sec */
169 else if (outgoing_rate < (1024 * 1024)) {
170 strcpy(outgoing_speed_rating, "KB"); 194 strcpy(outgoing_speed_rating, "KB");
171 adjusted_outgoing_rate = (double)(outgoing_rate / 1024.0); 195 adjusted_outgoing_rate = ((double)outgoing_rate / 1024.0);
172 } 196 } else {
173 197 /* report outgoing traffic in MBytes/sec */
174 /* report outgoing traffic in MBytes/sec */
175 else {
176 strcpy(outgoing_speed_rating, "MB"); 198 strcpy(outgoing_speed_rating, "MB");
177 adjusted_outgoing_rate = (outgoing_rate / 1024.0 / 1024.0); 199 adjusted_outgoing_rate = ((double)outgoing_rate / 1024.0 / 1024.0);
178 } 200 }
179 201
180 int result = STATE_OK; 202 mp_perfdata pd_rate_in = perfdata_init();
181 if (incoming_rate > config.incoming_critical_threshold || 203 pd_rate_in.label = "in";
182 outgoing_rate > config.outgoing_critical_threshold) { 204 pd_rate_in = mp_set_pd_value(pd_rate_in, incoming_rate);
183 result = STATE_CRITICAL; 205 pd_rate_in.uom = "B";
184 } else if (incoming_rate > config.incoming_warning_threshold || 206 pd_rate_in = mp_pd_set_thresholds(pd_rate_in, config.incoming_thresholds);
185 outgoing_rate > config.outgoing_warning_threshold) { 207
186 result = STATE_WARNING; 208 mp_perfdata pd_rate_out = perfdata_init();
187 } 209 pd_rate_out.label = "out";
188 210 pd_rate_out = mp_set_pd_value(pd_rate_out, outgoing_rate);
189 char *error_message; 211 pd_rate_out.uom = "B";
190 xasprintf(&error_message, _("%s. In = %0.1f %s/s, %s. Out = %0.1f %s/s|%s %s\n"), 212 pd_rate_out = mp_pd_set_thresholds(pd_rate_out, config.outgoing_thresholds);
191 (config.use_average) ? _("Avg") : _("Max"), adjusted_incoming_rate, 213
192 incoming_speed_rating, (config.use_average) ? _("Avg") : _("Max"), 214 mp_subcheck sc_rate_in = mp_subcheck_init();
193 adjusted_outgoing_rate, outgoing_speed_rating, 215 sc_rate_in = mp_set_subcheck_state(sc_rate_in, mp_get_pd_status(pd_rate_in));
194 fperfdata("in", adjusted_incoming_rate, incoming_speed_rating, 216 mp_add_perfdata_to_subcheck(&sc_rate_in, pd_rate_in);
195 (int)config.incoming_warning_threshold, config.incoming_warning_threshold, 217 xasprintf(&sc_rate_in.output, "%s. In = %0.1f %s/s", (config.use_average) ? _("Avg") : _("Max"),
196 (int)config.incoming_critical_threshold, config.incoming_critical_threshold, 218 adjusted_incoming_rate, incoming_speed_rating);
197 true, 0, false, 0), 219
198 fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating, 220 mp_subcheck sc_rate_out = mp_subcheck_init();
199 (int)config.outgoing_warning_threshold, config.outgoing_warning_threshold, 221 sc_rate_out = mp_set_subcheck_state(sc_rate_out, mp_get_pd_status(pd_rate_out));
200 (int)config.outgoing_critical_threshold, config.outgoing_critical_threshold, 222 mp_add_perfdata_to_subcheck(&sc_rate_out, pd_rate_out);
201 true, 0, false, 0)); 223 xasprintf(&sc_rate_out.output, "%s. Out = %0.1f %s/s",
202 224 (config.use_average) ? _("Avg") : _("Max"), adjusted_outgoing_rate,
203 printf(_("Traffic %s - %s\n"), state_text(result), error_message); 225 outgoing_speed_rating);
204 226
205 return result; 227 mp_subcheck sc_rate = mp_subcheck_init();
228 xasprintf(&sc_rate.output, "Traffic");
229 mp_add_subcheck_to_subcheck(&sc_rate, sc_rate_in);
230 mp_add_subcheck_to_subcheck(&sc_rate, sc_rate_out);
231
232 mp_add_subcheck_to_check(&overall, sc_rate);
233
234 mp_exit(overall);
206} 235}
207 236
208/* process command-line arguments */ 237/* process command-line arguments */
209check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { 238check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) {
239 enum {
240 output_format_index = CHAR_MAX + 1,
241 };
242
210 static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, 243 static struct option longopts[] = {{"filename", required_argument, 0, 'F'},
211 {"expires", required_argument, 0, 'e'}, 244 {"expires", required_argument, 0, 'e'},
212 {"aggregation", required_argument, 0, 'a'}, 245 {"aggregation", required_argument, 0, 'a'},
@@ -214,6 +247,7 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) {
214 {"warning", required_argument, 0, 'w'}, 247 {"warning", required_argument, 0, 'w'},
215 {"version", no_argument, 0, 'V'}, 248 {"version", no_argument, 0, 'V'},
216 {"help", no_argument, 0, 'h'}, 249 {"help", no_argument, 0, 'h'},
250 {"output-format", required_argument, 0, output_format_index},
217 {0, 0, 0, 0}}; 251 {0, 0, 0, 0}};
218 252
219 check_mrtgtraf_config_wrapper result = { 253 check_mrtgtraf_config_wrapper result = {
@@ -237,6 +271,14 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) {
237 271
238 int option_char; 272 int option_char;
239 int option = 0; 273 int option = 0;
274 unsigned long incoming_warning_threshold = 0;
275 unsigned long incoming_critical_threshold = 0;
276 unsigned long outgoing_warning_threshold = 0;
277 unsigned long outgoing_critical_threshold = 0;
278 bool incoming_warning_set = false;
279 bool incoming_critical_set = false;
280 bool outgoing_warning_set = false;
281 bool outgoing_critical_set = false;
240 while (true) { 282 while (true) {
241 option_char = getopt_long(argc, argv, "hVF:e:a:c:w:", longopts, &option); 283 option_char = getopt_long(argc, argv, "hVF:e:a:c:w:", longopts, &option);
242 284
@@ -254,13 +296,15 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) {
254 case 'a': /* aggregation (AVE or MAX) */ 296 case 'a': /* aggregation (AVE or MAX) */
255 result.config.use_average = (bool)(strcmp(optarg, "MAX")); 297 result.config.use_average = (bool)(strcmp(optarg, "MAX"));
256 break; 298 break;
257 case 'c': /* warning threshold */ 299 case 'c': /* critical threshold */
258 sscanf(optarg, "%lu,%lu", &result.config.incoming_critical_threshold, 300 sscanf(optarg, "%lu,%lu", &incoming_critical_threshold, &outgoing_critical_threshold);
259 &result.config.outgoing_critical_threshold); 301 incoming_critical_set = true;
302 outgoing_critical_set = true;
260 break; 303 break;
261 case 'w': /* critical threshold */ 304 case 'w': /* warning threshold */
262 sscanf(optarg, "%lu,%lu", &result.config.incoming_warning_threshold, 305 sscanf(optarg, "%lu,%lu", &incoming_warning_threshold, &outgoing_warning_threshold);
263 &result.config.outgoing_warning_threshold); 306 incoming_warning_set = true;
307 incoming_critical_set = true;
264 break; 308 break;
265 case 'V': /* version */ 309 case 'V': /* version */
266 print_revision(progname, NP_VERSION); 310 print_revision(progname, NP_VERSION);
@@ -270,6 +314,17 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) {
270 exit(STATE_UNKNOWN); 314 exit(STATE_UNKNOWN);
271 case '?': /* help */ 315 case '?': /* help */
272 usage5(); 316 usage5();
317 case output_format_index: {
318 parsed_output_format parser = mp_parse_output_format(optarg);
319 if (!parser.parsing_success) {
320 printf("Invalid output format: %s\n", optarg);
321 exit(STATE_UNKNOWN);
322 }
323
324 result.config.output_format_is_set = true;
325 result.config.output_format = parser.output_format;
326 break;
327 }
273 } 328 }
274 } 329 }
275 330
@@ -290,22 +345,62 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) {
290 option_char++; 345 option_char++;
291 } 346 }
292 347
293 if (argc > option_char && result.config.incoming_warning_threshold == 0) { 348 if (argc > option_char && incoming_warning_threshold == 0) {
294 result.config.incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10); 349 incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10);
350 incoming_warning_set = true;
351 }
352
353 if (argc > option_char && incoming_critical_threshold == 0) {
354 incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10);
355 incoming_critical_set = true;
356 }
357
358 if (argc > option_char && outgoing_warning_threshold == 0) {
359 outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10);
360 outgoing_warning_set = true;
361 }
362
363 if (argc > option_char && outgoing_critical_threshold == 0) {
364 outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10);
365 outgoing_critical_set = true;
366 }
367
368 mp_range incoming_warning = mp_range_init();
369 if (incoming_warning_set) {
370 incoming_warning =
371 mp_range_set_end(incoming_warning, mp_create_pd_value(incoming_warning_threshold));
295 } 372 }
296 373
297 if (argc > option_char && result.config.incoming_critical_threshold == 0) { 374 result.config.incoming_thresholds =
298 result.config.incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10); 375 mp_thresholds_set_warn(result.config.incoming_thresholds, incoming_warning);
376
377 mp_range incoming_critical = mp_range_init();
378 if (incoming_critical_set) {
379 incoming_critical =
380 mp_range_set_end(incoming_critical, mp_create_pd_value(incoming_critical_threshold));
299 } 381 }
300 382
301 if (argc > option_char && result.config.outgoing_warning_threshold == 0) { 383 result.config.incoming_thresholds =
302 result.config.outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10); 384 mp_thresholds_set_crit(result.config.incoming_thresholds, incoming_critical);
385
386 mp_range outgoing_warning = mp_range_init();
387 if (outgoing_warning_set) {
388 outgoing_warning =
389 mp_range_set_end(outgoing_warning, mp_create_pd_value(outgoing_warning_threshold));
303 } 390 }
304 391
305 if (argc > option_char && result.config.outgoing_critical_threshold == 0) { 392 result.config.outgoing_thresholds =
306 result.config.outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10); 393 mp_thresholds_set_warn(result.config.outgoing_thresholds, outgoing_warning);
394
395 mp_range outgoing_critical = mp_range_init();
396 if (outgoing_critical_set) {
397 outgoing_critical =
398 mp_range_set_end(outgoing_critical, mp_create_pd_value(outgoing_critical_threshold));
307 } 399 }
308 400
401 result.config.outgoing_thresholds =
402 mp_thresholds_set_crit(result.config.outgoing_thresholds, outgoing_critical);
403
309 return result; 404 return result;
310} 405}
311 406
@@ -340,6 +435,8 @@ void print_help(void) {
340 printf(" %s\n", "-c, --critical"); 435 printf(" %s\n", "-c, --critical");
341 printf(" %s\n", _("Critical threshold pair <incoming>,<outgoing>")); 436 printf(" %s\n", _("Critical threshold pair <incoming>,<outgoing>"));
342 437
438 printf(UT_OUTPUT_FORMAT);
439
343 printf("\n"); 440 printf("\n");
344 printf("%s\n", _("Notes:")); 441 printf("%s\n", _("Notes:"));
345 printf(" %s\n", _("- MRTG stands for Multi Router Traffic Grapher. It can be downloaded from")); 442 printf(" %s\n", _("- MRTG stands for Multi Router Traffic Grapher. It can be downloaded from"));