diff --git a/constants.h b/constants.h index 1c8ab1f..386d1c1 100644 --- a/constants.h +++ b/constants.h @@ -5,9 +5,10 @@ const char error_names[error_codes_count][error_name_max_length] = {"NOT_KNOWN_ #define not_known_error_code 3 // Error codes in same order const int error_codes[error_codes_count] = {not_known_error_code, 0, 64, 318767168, 134217792, 50331712, 117440576, 100663360, 67108928, 16908352, 128, 16777344, 192, 512, 50332160, 100663808, 16777728, 67109376, 117441024, 16908800, 576, 1088, 1152, 1408, 16778624, 1792, 16910080, 2048, 2688, 33557120, 2, 66, 130, 352845954, 17301634, 134217858, 33816706, 83886210, 301990018, 34078850, 84148354, 352583810, 67371138, 100925570, 369361026, 386138242, 134480002, 117440642, 151257218, 335544450, 84410498, 100794498, 262274, 50856066, 302252162, 654573698, 671350914, 403177602, 386400386, 150995074, 318767234, 385876098, 67108994, 33554562, 50331778, 402653314, 101187714, 16777346, 17039490, 117964930, 67633282, 369098882, 16908418, 33685634, 50462850, 67240066, 84017282, 469762178, 486539394, 503316610, 587202690, 603979906, 16777410, 33575106, 50352322, 83906754, 67391682, 16908482, 258, 322, 16777538, 33554754, 134218050, 50331970, 67109186, 83886402, 100663618, 117440834, 16908610, 33685826, 50463042, 386, 450, 514, 16908802, 1154, 16909442, 1282, 1410, 83887490, 33555842, 50333058, 67110274, 259, 515, 16777731, 33554947, 50332163, 67109379, 579, 16777795, 67109443, 16908867, 33686083, 50463299, 1155, 16778371, 1283, 1411, 4, 33554436, 16777220, 50331652, 16908292, 132, 16801924, 16797828, 101744772, 50364548, 655492, 151388292, 819332, 33579140, 34103428, 151818372, 67141764, 134611076, 17432708, 34209924, 151027844, 156008580, 50360452, 52461700, 16908420, 33685636, 67137668, 16806020, 50462852, 67240068, 50884740, 84017284, 100794500, 117571716, 33845380, 290948, 33583236, 84439172, 134348932, 151126148, 393348, 17064068, 17170564, 33947780, 50724996, 67502212, 84279428, 101056644, 117833860, 260, 197, 4293, 8389, 12485, 16581, 261, 16777477, 17039621, 50856197, 325, 100663621, 33685829, 50463045, 453, 67371461, 16908741, 33685957, 50463173, 67240389, 517, 786949, 16908805, 33686021, 135, 22, 16777238, 2456, 83888536, 33556888, 264600, 17303960, 67635608, 117442968, 134220184, 67111320, 100665752, 19138968, 301992344, 318769560, 335546776, 2361752, 285215128, 150997400, 67373464, 16779672, 536873368, 436210072, 452987288, 553650584, 570427800, 469764504, 486541720, 503318936, 32, 16777248, 33554464, 50331680, 67108896, 2600, 16779816, 33557032, 16847075, 33624291, 50401507, 67178723, 83955939, 16851171, 33628387, 50405603, 67182819, 83960035, 100737251, 117514467, 16888035, 33665251, 50442467, 16896227, 33673443, 50450659, 67227875, 84005091, 16859363, 33636579, 16941283, 33718499}; +#define max_length_of_error_code 9 +const int excluded_errcodes[] = {ERRCODE_CRASH_SHUTDOWN}; #define message_types_count 3 - const char message_type_names[message_types_count][10] = {"WARNING", "ERROR", "FATAL"}; const int message_types_codes[] = {WARNING, ERROR, FATAL}; diff --git a/logerrors.c b/logerrors.c index fea1ef8..3f415cb 100644 --- a/logerrors.c +++ b/logerrors.c @@ -50,6 +50,8 @@ static char *worker_name = "logerrors"; static emit_log_hook_type prev_emit_log_hook = NULL; static shmem_startup_hook_type prev_shmem_startup_hook = NULL; +char* excluded_errcodes_str= NULL; + typedef struct error_code { int num; } ErrorCode; @@ -90,6 +92,8 @@ typedef struct global_info { pg_atomic_uint32 total_count[3]; SlowLogInfo slow_log_info; MessagesBuffer messagesBuffer; + int excluded_errcodes[error_codes_count]; + int excluded_errcodes_count; } GlobalInfo; typedef struct counter_hashelem { @@ -118,10 +122,44 @@ void logerrors_main(Datum) pg_attribute_noreturn(); static void global_variables_init() { + long errcode; + char* end; + int errcodes_count; + char* excluded_errcode_str; + char excluded_errcodes_copy[error_codes_count * (max_length_of_error_code + 1)]; global_variables->intervals_count = intervals_count; /* +5 because we don't want take lock on MessagesBuffer while pg_log_errors_stats is running */ global_variables->actual_intervals_count = intervals_count + 5; global_variables->interval = interval; + + memset(&global_variables->excluded_errcodes, '\0', sizeof(global_variables->excluded_errcodes)); + + errcodes_count = sizeof(excluded_errcodes) / sizeof(excluded_errcodes[0]); + global_variables->excluded_errcodes_count = errcodes_count; + + memcpy(&global_variables->excluded_errcodes[0], excluded_errcodes, sizeof(excluded_errcodes)); + if (excluded_errcodes_str == NULL) + return; + memset(&excluded_errcodes_copy, '\0', sizeof(excluded_errcodes_copy)); + strlcpy(&excluded_errcodes_copy[0], excluded_errcodes_str, error_codes_count * max_length_of_error_code - 1); + + excluded_errcode_str = strtok(excluded_errcodes_copy, ","); + while (excluded_errcode_str != NULL) { + errno = 0; + errcode = strtol(excluded_errcode_str, &end, 10); + /* Ignore incorrect codes */ + if (errno != 0) { + excluded_errcode_str = strtok(NULL, " "); + elog(ERROR, "Invalid value of logerrors.excluded_errcodes"); + break; + } + global_variables->excluded_errcodes[global_variables->excluded_errcodes_count] = errcode; + global_variables->excluded_errcodes_count += 1; + if (global_variables->excluded_errcodes_count == error_codes_count - 1) + break; + + excluded_errcode_str = strtok(NULL, " "); + } } static void @@ -266,6 +304,8 @@ void logerrors_emit_log_hook(ErrorData *edata) { int lvl_i; + int err_code_index; + bool skip; /* Only if hashtable already inited */ if (global_variables != NULL && MyProc != NULL && !proc_exit_inprogress && !got_sigterm) { for (lvl_i = 0; lvl_i < message_types_count; ++lvl_i) @@ -273,8 +313,14 @@ logerrors_emit_log_hook(ErrorData *edata) /* Only current message type */ if (edata->elevel != message_types_codes[lvl_i]) continue; - /* Ignore ERRCODE_CRASH_SHUTDOWN because of lock problems */ - if (edata->sqlerrcode == ERRCODE_CRASH_SHUTDOWN) + skip = false; + for (err_code_index = 0; err_code_index < global_variables->excluded_errcodes_count; ++err_code_index) { + if (edata->sqlerrcode == global_variables->excluded_errcodes[err_code_index]) { + skip = true; + break; + } + } + if (skip) continue; add_message(edata->sqlerrcode, MyDatabaseId, GetUserId(), lvl_i); pg_atomic_fetch_add_u32(&global_variables->total_count[lvl_i], 1); @@ -317,6 +363,16 @@ logerrors_load_params(void) NULL, NULL, NULL); + DefineCustomStringVariable("logerrors.excluded_errcodes", + "Excluded error codes separated by ','", + NULL, + &excluded_errcodes_str, + NULL, + PGC_POSTMASTER, + GUC_NO_RESET_ALL, + NULL, + NULL, + NULL); } /* * Entry point for worker loading