Skip to content

Commit

Permalink
add exit status 2 option to --alert for making it possible to differe…
Browse files Browse the repository at this point in the history
…ntiate alerts from errors (exit status 1), closes #259
  • Loading branch information
vergoh committed Aug 19, 2024
1 parent ddddaa3 commit faf76f3
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 16 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
- Opening of body html tag was missing on some pages in image output
example cgi (examples/vnstat.cgi)
- New
- Add exit status 2 options to --alert for making it possible to
differentiate alerts from errors (exit status 1)
- Add --dbiflist also to vnstati command
- Image output example cgi (examples/vnstat.cgi) improvements
- Remove dependency to vnstat command
Expand Down
9 changes: 6 additions & 3 deletions man/vnstat.1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'\" t
.TH VNSTAT 1 "JANUARY 2024" "version 2.12" "User Manuals"
.TH VNSTAT 1 "AUGUST 2024" "version 2.13" "User Manuals"
.SH NAME
vnstat \- a console-based network traffic monitor

Expand Down Expand Up @@ -145,13 +145,16 @@ is exceeded.

.IP
.I exit
parameter takes a number from 0 to 3 and controls the exit status of the
parameter takes a number from 0 to 5 and controls the exit status of the
command. '0' always uses exit status 0, '1' always uses exit status 1, '2'
uses exit status 1 if usage estimate exceeds
.I limit
but otherwise exit status 0 and '3' uses exit status 1 if
.I limit
is exceeded but otherwise exit status 0.
is exceeded but otherwise exit status 0. '4' and '5' are equivalents of '2'
and '3' with the difference that exit status 2 is used instead of exit
status 1 when the condition is met. This can help differentiate alerts from
errors as errors will always use exit status 1.

.IP
.I type
Expand Down
16 changes: 12 additions & 4 deletions src/dbshow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1123,10 +1123,18 @@ int showalert(const char *interface, const AlertOutput output, const AlertExit a
adata.estimateexceeded = 1;
}

if (adata.limitexceeded && aexit == AE_Exit_1_On_Limit) {
ret = 1;
} else if (adata.estimateexceeded && aexit == AE_Exit_1_On_Estimate) {
ret = 1;
if (adata.limitexceeded) {
if (aexit == AE_Exit_1_On_Limit) {
ret = 1;
} else if (aexit == AE_Exit_2_On_Limit) {
ret = 2;
}
} else if (adata.estimateexceeded) {
if (aexit == AE_Exit_1_On_Estimate) {
ret = 1;
} else if (aexit == AE_Exit_2_On_Estimate) {
ret = 2;
}
}

if (output != AO_No_Output) {
Expand Down
4 changes: 3 additions & 1 deletion src/dbshow.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ typedef enum AlertExit {
AE_Always_Exit_0 = 0,
AE_Always_Exit_1,
AE_Exit_1_On_Estimate,
AE_Exit_1_On_Limit
AE_Exit_1_On_Limit,
AE_Exit_2_On_Estimate,
AE_Exit_2_On_Limit
} AlertExit;

typedef enum AlertType {
Expand Down
21 changes: 15 additions & 6 deletions src/vnstat_func.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ int parsealertargs(PARAMS *p, char **argv)
return 0;
}
p->alertexit = (unsigned int)atoi(argv[currentarg]);
if (p->alertexit > 3) {
if (p->alertexit > 5) {
printf("Error: Exit parameter out of range for %s.\n", argv[0]);
showalerthelp();
return 0;
Expand Down Expand Up @@ -714,11 +714,11 @@ int parsealertargs(PARAMS *p, char **argv)
currentarg++;

if ((p->alertcondition == AC_RX_Estimate || p->alertcondition == AC_TX_Estimate || p->alertcondition == AC_Total_Estimate) &&
(p->alertoutput == AO_Output_On_Estimate || p->alertexit == AE_Exit_1_On_Estimate)) {
(p->alertoutput == AO_Output_On_Estimate || p->alertexit == AE_Exit_1_On_Estimate || p->alertexit == AE_Exit_2_On_Estimate)) {
if (p->alertoutput == AO_Output_On_Estimate) {
printf("Error: Estimate conditions cannot be used in combination with output parameter \"2\".\n");
}
if (p->alertexit == AE_Exit_1_On_Estimate) {
if (p->alertexit == AE_Exit_1_On_Estimate || p->alertexit == AE_Exit_2_On_Estimate) {
printf("Error: Estimate conditions cannot be used in combination with exit parameter \"2\".\n");
}
showalerthelp();
Expand Down Expand Up @@ -844,7 +844,9 @@ void showalerthelp(void)
printf(" 0 - always use exit status 0\n");
printf(" 1 - always use exit status 1\n");
printf(" 2 - use exit status 1 if usage estimate exceeds limit\n");
printf(" 3 - use exit status 1 if limit is exceeded\n\n");
printf(" 3 - use exit status 1 if limit is exceeded\n");
printf(" 4 - use exit status 2 if usage estimate exceeds limit\n");
printf(" 5 - use exit status 2 if limit is exceeded\n\n");

printf(" <type>\n");
printf(" h, hour, hourly d, day, daily p, 95, 95%%\n");
Expand Down Expand Up @@ -904,11 +906,18 @@ void handleshowalert(PARAMS *p)

alert = showalert(p->interface, p->alertoutput, p->alertexit, p->alerttype, p->alertcondition, p->alertlimit);

if ((alert || p->alertexit == AE_Always_Exit_1) && p->alertexit != AE_Always_Exit_0) {
if (p->alertexit == AE_Always_Exit_0) {
exit(EXIT_SUCCESS);
} else if (p->alertexit == AE_Always_Exit_1) {
exit(EXIT_FAILURE);
}

exit(EXIT_SUCCESS);
if (alert >= 0 || alert <= 2) {
exit(alert);
}

printf("Error: Unexpected alert evaluation result: %d\n", alert);
exit(EXIT_FAILURE);
}

void handleremoveinterface(const PARAMS *p)
Expand Down
4 changes: 2 additions & 2 deletions tests/cli_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,7 @@ START_TEST(parsealertargs_can_validate_exit_range)
{
int ret;
PARAMS p;
char *argv[] = {"--alert", "1", "4", "y", "total", "5", "KiB", NULL};
char *argv[] = {"--alert", "1", "6", "y", "total", "5", "KiB", NULL};

defaultcfg();
initparams(&p);
Expand All @@ -1089,7 +1089,7 @@ START_TEST(parsealertargs_can_validate_exit_range)
ret = parsealertargs(&p, argv);
ck_assert_int_eq(ret, 0);
ck_assert_int_eq(p.alertoutput, 1);
ck_assert_int_eq(p.alertexit, 4);
ck_assert_int_eq(p.alertexit, 6);
ck_assert_int_eq(p.alerttype, 0);
ck_assert_int_eq(p.alertcondition, 0);
ck_assert_int_eq(p.alertlimit, 0);
Expand Down
153 changes: 153 additions & 0 deletions tests/database_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,51 @@ START_TEST(showalert_can_alert_on_limit_and_show_things)
}
END_TEST

START_TEST(showalert_can_alert_on_limit_and_show_things_with_correct_return_value)
{
int ret;

defaultcfg();
suppress_output();

ret = db_open_rw(1);
ck_assert_int_eq(ret, 1);

ret = db_addinterface("something");
ck_assert_int_eq(ret, 1);

ret = db_setalias("something", "anything");
ck_assert_int_eq(ret, 1);

ret = db_addtraffic("something", 1000, 2000);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Hour, AC_Total, 2500);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Day, AC_Total, 2500);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Month, AC_Total, 2500);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 2500);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Percentile, AC_RX, 2);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Percentile, AC_TX, 4);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Percentile, AC_Total, 5);
ck_assert_int_eq(ret, 2);

ret = db_close();
ck_assert_int_eq(ret, 1);
}
END_TEST

START_TEST(showalert_can_alert_on_limit_and_show_things_in_json)
{
int ret;
Expand Down Expand Up @@ -937,6 +982,52 @@ START_TEST(showalert_can_alert_on_limit_and_show_things_in_json)
}
END_TEST

START_TEST(showalert_can_alert_on_limit_and_show_things_in_json_with_correct_return_value)
{
int ret;

defaultcfg();
cfg.qmode = 10;
suppress_output();

ret = db_open_rw(1);
ck_assert_int_eq(ret, 1);

ret = db_addinterface("something");
ck_assert_int_eq(ret, 1);

ret = db_setalias("something", "anything");
ck_assert_int_eq(ret, 1);

ret = db_addtraffic("something", 1000, 2000);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Hour, AC_Total, 2500);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Day, AC_Total, 2500);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Month, AC_Total, 2500);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 2500);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Percentile, AC_RX, 2);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Percentile, AC_TX, 4);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Percentile, AC_Total, 5);
ck_assert_int_eq(ret, 2);

ret = db_close();
ck_assert_int_eq(ret, 1);
}
END_TEST

START_TEST(showalert_limit_and_conditions_matter)
{
int ret;
Expand All @@ -956,33 +1047,63 @@ START_TEST(showalert_limit_and_conditions_matter)
ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 100);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 100);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 280);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 280);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 350);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 350);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 300);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 300);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_RX, 80);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_RX, 80);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_RX, 150);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_RX, 150);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 180);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_TX, 180);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 250);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_TX, 250);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 350);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_TX, 350);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 200);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_TX, 200);
ck_assert_int_eq(ret, 0);

ret = db_close();
ck_assert_int_eq(ret, 1);
}
Expand All @@ -1008,33 +1129,63 @@ START_TEST(showalert_limit_and_conditions_matter_also_for_json_output)
ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 100);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 100);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 280);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 280);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 350);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 350);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 300);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_Total, 300);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_RX, 80);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_RX, 80);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_RX, 150);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_RX, 150);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 180);
ck_assert_int_eq(ret, 1);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_TX, 180);
ck_assert_int_eq(ret, 2);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 250);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_TX, 250);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 350);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_TX, 350);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 200);
ck_assert_int_eq(ret, 0);

ret = showalert("something", AO_Always_Output, AE_Exit_2_On_Limit, AT_Year, AC_TX, 200);
ck_assert_int_eq(ret, 0);

ret = db_close();
ck_assert_int_eq(ret, 1);
}
Expand Down Expand Up @@ -1079,7 +1230,9 @@ void add_database_tests(Suite *s)
tcase_add_test(tc_db, showalert_shows_nothing_with_none_type);
tcase_add_test(tc_db, showalert_shows_nothing_in_json_with_none_type);
tcase_add_test(tc_db, showalert_can_alert_on_limit_and_show_things);
tcase_add_test(tc_db, showalert_can_alert_on_limit_and_show_things_with_correct_return_value);
tcase_add_test(tc_db, showalert_can_alert_on_limit_and_show_things_in_json);
tcase_add_test(tc_db, showalert_can_alert_on_limit_and_show_things_in_json_with_correct_return_value);
tcase_add_test(tc_db, showalert_limit_and_conditions_matter);
tcase_add_test(tc_db, showalert_limit_and_conditions_matter_also_for_json_output);
suite_add_tcase(s, tc_db);
Expand Down

0 comments on commit faf76f3

Please sign in to comment.