diff options
Diffstat (limited to 'plugins/check_dbi.c')
| -rw-r--r-- | plugins/check_dbi.c | 168 |
1 files changed, 51 insertions, 117 deletions
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index 035e30cd..ddd0b328 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c | |||
| @@ -358,7 +358,7 @@ int main(int argc, char **argv) { | |||
| 358 | // so we expected a number | 358 | // so we expected a number |
| 359 | // this is a CRITICAL | 359 | // this is a CRITICAL |
| 360 | xasprintf(&sc_query.output, "Query '%s' result is not numeric", | 360 | xasprintf(&sc_query.output, "Query '%s' result is not numeric", |
| 361 | config.dbi_query, query_res.result_string); | 361 | config.dbi_query); |
| 362 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | 362 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); |
| 363 | 363 | ||
| 364 | } else { | 364 | } else { |
| @@ -490,7 +490,6 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 490 | } | 490 | } |
| 491 | break; | 491 | break; |
| 492 | } | 492 | } |
| 493 | |||
| 494 | case 'm': | 493 | case 'm': |
| 495 | if (!strcasecmp(optarg, "CONN_TIME")) { | 494 | if (!strcasecmp(optarg, "CONN_TIME")) { |
| 496 | result.config.metric = METRIC_CONN_TIME; | 495 | result.config.metric = METRIC_CONN_TIME; |
| @@ -510,7 +509,6 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 510 | } else { | 509 | } else { |
| 511 | timeout_interval = atoi(optarg); | 510 | timeout_interval = atoi(optarg); |
| 512 | } | 511 | } |
| 513 | |||
| 514 | break; | 512 | break; |
| 515 | case 'H': /* host */ | 513 | case 'H': /* host */ |
| 516 | if (!is_host(optarg)) { | 514 | if (!is_host(optarg)) { |
| @@ -522,7 +520,6 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 522 | case 'v': | 520 | case 'v': |
| 523 | verbose++; | 521 | verbose++; |
| 524 | break; | 522 | break; |
| 525 | |||
| 526 | case 'd': | 523 | case 'd': |
| 527 | result.config.dbi_driver = optarg; | 524 | result.config.dbi_driver = optarg; |
| 528 | break; | 525 | break; |
| @@ -718,21 +715,12 @@ void print_usage(void) { | |||
| 718 | printf(" [-e <string>] [-r|-R <regex>]\n"); | 715 | printf(" [-e <string>] [-r|-R <regex>]\n"); |
| 719 | } | 716 | } |
| 720 | 717 | ||
| 721 | const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_type, | 718 | const char *get_field_str(dbi_result res, mp_dbi_metric metric, mp_dbi_type type) { |
| 722 | mp_dbi_metric metric, mp_dbi_type type) { | 719 | const char *str = dbi_result_get_string_idx(res, 1); |
| 723 | const char *str; | ||
| 724 | |||
| 725 | if (field_type != DBI_TYPE_STRING) { | ||
| 726 | printf("CRITICAL - result value is not a string\n"); | ||
| 727 | return NULL; | ||
| 728 | } | ||
| 729 | |||
| 730 | str = dbi_result_get_string_idx(res, 1); | ||
| 731 | if ((!str) || (strcmp(str, "ERROR") == 0)) { | 720 | if ((!str) || (strcmp(str, "ERROR") == 0)) { |
| 732 | if (metric != METRIC_QUERY_RESULT) { | 721 | if (metric != METRIC_QUERY_RESULT) { |
| 733 | return NULL; | 722 | return NULL; |
| 734 | } | 723 | } |
| 735 | np_dbi_print_error(conn, "CRITICAL - failed to fetch string value"); | ||
| 736 | return NULL; | 724 | return NULL; |
| 737 | } | 725 | } |
| 738 | 726 | ||
| @@ -742,36 +730,50 @@ const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_ty | |||
| 742 | return str; | 730 | return str; |
| 743 | } | 731 | } |
| 744 | 732 | ||
| 745 | double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type, mp_dbi_metric metric, | 733 | typedef struct { |
| 746 | mp_dbi_type type) { | 734 | double value; |
| 747 | double val = NAN; | 735 | int error_code; |
| 736 | int dbi_error_code; // not sure if useful | ||
| 737 | } get_field_wrapper; | ||
| 738 | get_field_wrapper get_field(dbi_result res, mp_dbi_metric metric, mp_dbi_type type) { | ||
| 739 | |||
| 740 | unsigned short field_type = dbi_result_get_field_type_idx(res, 1); | ||
| 741 | get_field_wrapper result = { | ||
| 742 | .value = NAN, | ||
| 743 | .error_code = OK, | ||
| 744 | }; | ||
| 748 | 745 | ||
| 749 | if (*field_type == DBI_TYPE_INTEGER) { | 746 | if (field_type == DBI_TYPE_INTEGER) { |
| 750 | val = (double)dbi_result_get_longlong_idx(res, 1); | 747 | result.value = (double)dbi_result_get_longlong_idx(res, 1); |
| 751 | } else if (*field_type == DBI_TYPE_DECIMAL) { | 748 | } else if (field_type == DBI_TYPE_DECIMAL) { |
| 752 | val = dbi_result_get_double_idx(res, 1); | 749 | result.value = dbi_result_get_double_idx(res, 1); |
| 753 | } else if (*field_type == DBI_TYPE_STRING) { | 750 | } else if (field_type == DBI_TYPE_STRING) { |
| 754 | const char *val_str; | 751 | const char *val_str; |
| 755 | char *endptr = NULL; | 752 | char *endptr = NULL; |
| 756 | 753 | ||
| 757 | val_str = get_field_str(conn, res, *field_type, metric, type); | 754 | val_str = get_field_str(res, metric, type); |
| 758 | if (!val_str) { | 755 | if (!val_str) { |
| 759 | if (metric != METRIC_QUERY_RESULT) { | 756 | result.error_code = ERROR; |
| 760 | return NAN; | 757 | field_type = DBI_TYPE_ERROR; |
| 761 | } | 758 | return result; |
| 762 | *field_type = DBI_TYPE_ERROR; | ||
| 763 | return NAN; | ||
| 764 | } | 759 | } |
| 765 | 760 | ||
| 766 | val = strtod(val_str, &endptr); | 761 | result.value = strtod(val_str, &endptr); |
| 767 | if (endptr == val_str) { | 762 | if (endptr == val_str) { |
| 768 | if (metric != METRIC_QUERY_RESULT) { | 763 | if (metric != METRIC_QUERY_RESULT) { |
| 769 | return NAN; | 764 | result.error_code = ERROR; |
| 765 | return result; | ||
| 770 | } | 766 | } |
| 771 | printf("CRITICAL - result value is not a numeric: %s\n", val_str); | 767 | |
| 772 | *field_type = DBI_TYPE_ERROR; | 768 | if (verbose) { |
| 773 | return NAN; | 769 | printf("CRITICAL - result value is not a numeric: %s\n", val_str); |
| 770 | } | ||
| 771 | |||
| 772 | field_type = DBI_TYPE_ERROR; | ||
| 773 | result.error_code = ERROR; | ||
| 774 | return result; | ||
| 774 | } | 775 | } |
| 776 | |||
| 775 | if ((endptr != NULL) && (*endptr != '\0')) { | 777 | if ((endptr != NULL) && (*endptr != '\0')) { |
| 776 | if (verbose) { | 778 | if (verbose) { |
| 777 | printf("Garbage after value: %s\n", endptr); | 779 | printf("Garbage after value: %s\n", endptr); |
| @@ -779,86 +781,18 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type, mp_d | |||
| 779 | } | 781 | } |
| 780 | } else { | 782 | } else { |
| 781 | if (metric != METRIC_QUERY_RESULT) { | 783 | if (metric != METRIC_QUERY_RESULT) { |
| 782 | return NAN; | 784 | result.error_code = ERROR; |
| 785 | return result; | ||
| 783 | } | 786 | } |
| 784 | printf("CRITICAL - cannot parse value of type %s (%i)\n", | 787 | // printf("CRITICAL - cannot parse value of type %s (%i)\n", |
| 785 | (*field_type == DBI_TYPE_BINARY) ? "BINARY" | 788 | // (*field_type == DBI_TYPE_BINARY) ? "BINARY" |
| 786 | : (*field_type == DBI_TYPE_DATETIME) ? "DATETIME" | 789 | // : (*field_type == DBI_TYPE_DATETIME) ? "DATETIME" |
| 787 | : "<unknown>", | 790 | // : "<unknown>", |
| 788 | *field_type); | 791 | // *field_type); |
| 789 | *field_type = DBI_TYPE_ERROR; | 792 | field_type = DBI_TYPE_ERROR; |
| 790 | return NAN; | 793 | result.error_code = ERROR; |
| 791 | } | ||
| 792 | return val; | ||
| 793 | } | ||
| 794 | |||
| 795 | mp_state_enum get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, | ||
| 796 | double *res_val, mp_dbi_metric metric, mp_dbi_type type) { | ||
| 797 | unsigned short field_type; | ||
| 798 | double val = NAN; | ||
| 799 | |||
| 800 | if (dbi_result_get_numrows(res) == DBI_ROW_ERROR) { | ||
| 801 | if (metric != METRIC_QUERY_RESULT) { | ||
| 802 | return STATE_OK; | ||
| 803 | } | ||
| 804 | np_dbi_print_error(conn, "CRITICAL - failed to fetch rows"); | ||
| 805 | return STATE_CRITICAL; | ||
| 806 | } | 794 | } |
| 807 | 795 | return result; | |
| 808 | if (dbi_result_get_numrows(res) < 1) { | ||
| 809 | if (metric != METRIC_QUERY_RESULT) { | ||
| 810 | return STATE_OK; | ||
| 811 | } | ||
| 812 | printf("WARNING - no rows returned\n"); | ||
| 813 | return STATE_WARNING; | ||
| 814 | } | ||
| 815 | |||
| 816 | if (dbi_result_get_numfields(res) == DBI_FIELD_ERROR) { | ||
| 817 | if (metric != METRIC_QUERY_RESULT) { | ||
| 818 | return STATE_OK; | ||
| 819 | } | ||
| 820 | np_dbi_print_error(conn, "CRITICAL - failed to fetch fields"); | ||
| 821 | return STATE_CRITICAL; | ||
| 822 | } | ||
| 823 | |||
| 824 | if (dbi_result_get_numfields(res) < 1) { | ||
| 825 | if (metric != METRIC_QUERY_RESULT) { | ||
| 826 | return STATE_OK; | ||
| 827 | } | ||
| 828 | printf("WARNING - no fields returned\n"); | ||
| 829 | return STATE_WARNING; | ||
| 830 | } | ||
| 831 | |||
| 832 | if (dbi_result_first_row(res) != 1) { | ||
| 833 | if (metric != METRIC_QUERY_RESULT) { | ||
| 834 | return STATE_OK; | ||
| 835 | } | ||
| 836 | np_dbi_print_error(conn, "CRITICAL - failed to fetch first row"); | ||
| 837 | return STATE_CRITICAL; | ||
| 838 | } | ||
| 839 | |||
| 840 | field_type = dbi_result_get_field_type_idx(res, 1); | ||
| 841 | if (field_type != DBI_TYPE_ERROR) { | ||
| 842 | if (type == TYPE_STRING) { | ||
| 843 | /* the value will be freed in dbi_result_free */ | ||
| 844 | *res_val_str = strdup(get_field_str(conn, res, field_type, metric, type)); | ||
| 845 | } else { | ||
| 846 | val = get_field(conn, res, &field_type, metric, type); | ||
| 847 | } | ||
| 848 | } | ||
| 849 | |||
| 850 | *res_val = val; | ||
| 851 | |||
| 852 | if (field_type == DBI_TYPE_ERROR) { | ||
| 853 | if (metric != METRIC_QUERY_RESULT) { | ||
| 854 | return STATE_OK; | ||
| 855 | } | ||
| 856 | np_dbi_print_error(conn, "CRITICAL - failed to fetch data"); | ||
| 857 | return STATE_CRITICAL; | ||
| 858 | } | ||
| 859 | |||
| 860 | dbi_result_free(res); | ||
| 861 | return STATE_OK; | ||
| 862 | } | 796 | } |
| 863 | 797 | ||
| 864 | static do_query_result do_query(dbi_conn conn, mp_dbi_metric metric, mp_dbi_type type, | 798 | static do_query_result do_query(dbi_conn conn, mp_dbi_metric metric, mp_dbi_type type, |
| @@ -942,10 +876,10 @@ static do_query_result do_query(dbi_conn conn, mp_dbi_metric metric, mp_dbi_type | |||
| 942 | unsigned short field_type = dbi_result_get_field_type_idx(res, 1); | 876 | unsigned short field_type = dbi_result_get_field_type_idx(res, 1); |
| 943 | if (field_type != DBI_TYPE_ERROR) { | 877 | if (field_type != DBI_TYPE_ERROR) { |
| 944 | if (type == TYPE_STRING) { | 878 | if (type == TYPE_STRING) { |
| 945 | result.result_string = | 879 | result.result_string = strdup(get_field_str(res, metric, type)); |
| 946 | strdup(get_field_str(conn, res, field_type, metric, type)); | ||
| 947 | } else { | 880 | } else { |
| 948 | result.result_number = get_field(conn, res, &field_type, metric, type); | 881 | get_field_wrapper gfw = get_field(res, metric, type); |
| 882 | result.result_number = gfw.value; | ||
| 949 | } | 883 | } |
| 950 | } else { | 884 | } else { |
| 951 | // Error when retrieving the field, that is OK if the Query result is not of | 885 | // Error when retrieving the field, that is OK if the Query result is not of |
| @@ -967,7 +901,7 @@ static do_query_result do_query(dbi_conn conn, mp_dbi_metric metric, mp_dbi_type | |||
| 967 | return result; | 901 | return result; |
| 968 | } | 902 | } |
| 969 | 903 | ||
| 970 | double timediff(struct timeval start, struct timeval end) { | 904 | static double timediff(struct timeval start, struct timeval end) { |
| 971 | double diff; | 905 | double diff; |
| 972 | 906 | ||
| 973 | while (start.tv_usec > end.tv_usec) { | 907 | while (start.tv_usec > end.tv_usec) { |
| @@ -978,7 +912,7 @@ double timediff(struct timeval start, struct timeval end) { | |||
| 978 | return diff; | 912 | return diff; |
| 979 | } | 913 | } |
| 980 | 914 | ||
| 981 | void np_dbi_print_error(dbi_conn conn, char *fmt, ...) { | 915 | static void np_dbi_print_error(dbi_conn conn, char *fmt, ...) { |
| 982 | const char *errmsg = NULL; | 916 | const char *errmsg = NULL; |
| 983 | va_list ap; | 917 | va_list ap; |
| 984 | 918 | ||
