From ae0f631dc51bb04e9d692666190035658062a9c9 Mon Sep 17 00:00:00 2001 From: Agnieszka Baumann Date: Tue, 8 Sep 2020 12:24:29 +0200 Subject: [PATCH] Warn when log is duplicated X times Change-Id: I9302cd761a7de0f090a35940f47ef38de19ba9fa --- Makefile.am | 2 +- include/deduplicate.h | 9 +- src/libdlog/deduplicate.c | 94 +++++++++--- src/libdlog/log.c | 5 +- src/tests/deduplicate_test.c | 342 ++++++++++++++++++++++++++++++++++--------- tests/dlog_test.in | 44 ++++++ 6 files changed, 403 insertions(+), 93 deletions(-) diff --git a/Makefile.am b/Makefile.am index e6d4bd6..238987d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -619,7 +619,7 @@ src_tests_metrics_LDFLAGS = $(AM_LDFLAGS) -lpthread -Wl,--wrap=dlogutil_entry_ge src_tests_deduplicate_test_SOURCES = src/tests/deduplicate_test.c src/libdlog/log.c src/libdlog/deduplicate.c src/shared/hash.c src/shared/logcommon.c src/shared/loglimiter.c src/libdlog/dynamic_config.c src/shared/logconfig.c src/shared/parsers.c src/shared/ptrs_list.c src_tests_deduplicate_test_CFLAGS = $(check_CFLAGS) -pthread -src_tests_deduplicate_test_LDFLAGS = $(AM_LDFLAGS) -lpthread -Wl,--wrap=clock_gettime,--wrap=log_config_read +src_tests_deduplicate_test_LDFLAGS = $(AM_LDFLAGS) -lpthread -Wl,--wrap=clock_gettime,--wrap=log_config_read,--wrap=deduplicate_warn # conf file usrlibtmpfilesddir = /usr/lib/tmpfiles.d diff --git a/include/deduplicate.h b/include/deduplicate.h index 8e875a0..a4b3b8a 100644 --- a/include/deduplicate.h +++ b/include/deduplicate.h @@ -31,8 +31,15 @@ // Dlog #include "logconfig.h" +typedef enum dlog_deduplicate_e { + DLOG_DO_NOT_DEDUPLICATE = 0, + DLOG_DEDUPLICATE, + DLOG_DO_NOT_DEDUPLICATE_BUT_WARN, +} dlog_deduplicate_e; + +void deduplicate_warn(char *buf, size_t size, size_t len); void __configure_deduplicate(struct log_config *config); void __deduplicate_destroy(); -extern bool (*deduplicate_func)(const char *, size_t, struct timespec *); +extern dlog_deduplicate_e (*deduplicate_func)(const char *, size_t, struct timespec *); #endif /* _DEDUPLICATE_H_ */ diff --git a/src/libdlog/deduplicate.c b/src/libdlog/deduplicate.c index 651392c..5feda7f 100644 --- a/src/libdlog/deduplicate.c +++ b/src/libdlog/deduplicate.c @@ -26,29 +26,42 @@ // Dlog #include "deduplicate.h" #include "hash.h" +#include "logcommon.h" +#include "parsers.h" -bool (*deduplicate_func)(const char *, size_t, struct timespec *); +#define WARNING_STRING " LOG DUPLICATED %d TIMES" +#define WARNING_MAX sizeof(" LOG DUPLICATED " STRINGIFY(INT32_MAX) " TIMES") + +typedef struct deduplicate_log { + uint32_t hash; + size_t quantity; +} deduplicate_log; + +dlog_deduplicate_e (*deduplicate_func)(const char *, size_t, struct timespec *); -static uint32_t basic_hash; static long last_millisec; static long interval_millisec; static int known_hashes_capacity; -static uint32_t *known_hashes_vector; +static deduplicate_log *known_hashes_vector; static int known_hashes_size = 0; static pthread_mutex_t deduplication_lock = PTHREAD_MUTEX_INITIALIZER; +static int warn_quantity; +static int warning_size; +static char warning_content[WARNING_MAX]; +static deduplicate_log basic_log; static void refresh_deduplication_limits() { known_hashes_size = 0; } -static bool is_hash_known(const uint32_t new_hash) +static size_t *known_hash_count(const uint32_t new_hash) { for (size_t i = 0; i < known_hashes_size; i++) - if (known_hashes_vector[i] == new_hash) - return true; + if (known_hashes_vector[i].hash == new_hash) + return &known_hashes_vector[i].quantity; - return false; + return NULL; } static bool compare_milli(struct timespec *tp) @@ -62,14 +75,23 @@ static bool compare_milli(struct timespec *tp) return false; } -static bool basic_deduplicate(const char *msg, size_t len, struct timespec *tp) +static dlog_deduplicate_e basic_deduplicate(const char *msg, size_t len, struct timespec *tp) { const uint32_t new_hash = create_hash(msg, len); - bool compare_hash = (basic_hash == new_hash); - basic_hash = new_hash; + bool compare_hash = (basic_log.hash == new_hash); bool compare_milisec = compare_milli(tp); - return compare_hash && compare_milisec; + if (compare_hash && compare_milisec) { + basic_log.quantity++; + if (warn_quantity != 0 && (basic_log.quantity % warn_quantity == 0)) + return DLOG_DO_NOT_DEDUPLICATE_BUT_WARN; + return DLOG_DEDUPLICATE; + } else { + basic_log.quantity = 1; + basic_log.hash = new_hash; + } + + return DLOG_DO_NOT_DEDUPLICATE; } static bool add_known_hash(uint32_t new_hash) @@ -82,30 +104,49 @@ static bool add_known_hash(uint32_t new_hash) known_hashes_capacity *= 2; known_hashes_vector = temp; } - known_hashes_vector[known_hashes_size] = new_hash; + known_hashes_vector[known_hashes_size].hash = new_hash; + known_hashes_vector[known_hashes_size].quantity = 1; known_hashes_size++; return true; } -static bool advanced_deduplicate(const char *msg, size_t len, struct timespec *tp) +static dlog_deduplicate_e advanced_deduplicate(const char *msg, size_t len, struct timespec *tp) { pthread_mutex_lock(&deduplication_lock); bool compare_milisec = compare_milli(tp); uint32_t new_hash = create_hash(msg, len); - int ret = false; - - if (compare_milisec) - ret = is_hash_known(new_hash); - else + size_t *quantity_ptr = NULL; + dlog_deduplicate_e output = DLOG_DO_NOT_DEDUPLICATE; + + if (compare_milisec) { + quantity_ptr = known_hash_count(new_hash); + if (quantity_ptr != NULL) { + *quantity_ptr += 1; + output = DLOG_DEDUPLICATE; + if (warn_quantity != 0 && (*quantity_ptr % warn_quantity == 0)) + output = DLOG_DO_NOT_DEDUPLICATE_BUT_WARN; + } + } else { refresh_deduplication_limits(); + } - if (ret == false) + if (quantity_ptr == NULL) add_known_hash(new_hash); pthread_mutex_unlock(&deduplication_lock); - return ret; + return output; +} + +void deduplicate_warn(char *buf, size_t size, size_t len) +{ + assert(size > warning_size); + + if (len + warning_size < size) + strncpy(buf + len, warning_content, size - len); + else + strncpy(buf + size - warning_size - 1, warning_content, warning_size + 1); } void __configure_deduplicate(struct log_config *config) @@ -114,13 +155,24 @@ void __configure_deduplicate(struct log_config *config) const char *const value = log_config_get(config, "deduplicate_method"); interval_millisec = log_config_get_int(config, "deduplicate_interval_ms", 1); + const char *warn_quant_str = log_config_get(config, "deduplicate_warn_quantity"); + if (!warn_quant_str) + warn_quantity = 10; + else if (parse_number(&warn_quant_str, &warn_quantity) < 0 || (warn_quantity < 0)) + warn_quantity = 0; + + warning_size = snprintf(warning_content, sizeof warning_content, WARNING_STRING, warn_quantity); + assert(warning_size < (sizeof warning_content)); + if (warning_size < 0) + return; + if (!value) { return; } else if (strcmp(value, "only_identical_neighbours") == 0) { deduplicate_func = basic_deduplicate; } else if (strcmp(value, "all_identical_logs") == 0) { known_hashes_capacity = 4; - known_hashes_vector = (uint32_t *) calloc(known_hashes_capacity, sizeof *known_hashes_vector); + known_hashes_vector = (deduplicate_log *) calloc(known_hashes_capacity, sizeof *known_hashes_vector); if (!known_hashes_vector) return; deduplicate_func = advanced_deduplicate; diff --git a/src/libdlog/log.c b/src/libdlog/log.c index e356dd8..d66af3d 100644 --- a/src/libdlog/log.c +++ b/src/libdlog/log.c @@ -371,8 +371,11 @@ static int __write_to_log_critical_section(log_id_t log_id, int prio, const char struct timespec tp; int r; if (deduplicate_func && !clock_gettime(CLOCK_MONOTONIC, &tp)) { - if (deduplicate_func(buf, len, &tp)) + dlog_deduplicate_e ret = deduplicate_func(buf, len, &tp); + if (ret == DLOG_DEDUPLICATE) return DLOG_ERROR_NONE; + else if (ret == DLOG_DO_NOT_DEDUPLICATE_BUT_WARN) + deduplicate_warn(buf, sizeof buf, len); r = write_to_log(log_id, prio, tag, buf, &tp); } else r = write_to_log(log_id, prio, tag, buf, NULL); diff --git a/src/tests/deduplicate_test.c b/src/tests/deduplicate_test.c index 2e3591b..2c2a5cd 100644 --- a/src/tests/deduplicate_test.c +++ b/src/tests/deduplicate_test.c @@ -30,9 +30,25 @@ #include "libdlog.h" #include "logconfig.h" +#define DEDUPLICATE 0 +#define WARN 0xBA5EBALL +#define PRINT 0xC0FFEE + long milliseconds; const char *local_advanced; const char *local_time_ms; +const char *local_warn_quantity; +bool deduplicate_warning = false; + +static int use_real_deduplicate_warn = false; +void __real_deduplicate_warn(char *buf, size_t size, size_t len); +void __wrap_deduplicate_warn(char *buf, size_t size, size_t len) +{ + if (use_real_deduplicate_warn) + __real_deduplicate_warn(buf, size, len); + else + deduplicate_warning = true; +} int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) { @@ -43,7 +59,12 @@ int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) int log_handler(log_id_t buf_id, log_priority pri, const char *tag, const char *msg, struct timespec *tp) { - return 0xC0FFEE; + if (deduplicate_warning) { + deduplicate_warning = false; + return WARN; + } + + return PRINT; } void __dlog_init_pipe(const struct log_config *conf) @@ -64,6 +85,7 @@ int __wrap_log_config_read(struct log_config *config) log_config_set(config, "debugmode", "1"); log_config_set(config, "deduplicate_method", local_advanced); log_config_set(config, "deduplicate_interval_ms", local_time_ms); + log_config_set(config, "deduplicate_warn_quantity", local_warn_quantity); return 0; } @@ -76,21 +98,22 @@ void test_basic_1ms_interval() { local_advanced = "only_identical_neighbours"; local_time_ms = "1"; + local_warn_quantity = "0"; milliseconds = 123; - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("B", 0); - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("C", 0xC0FFEE); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("B", DEDUPLICATE); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("C", PRINT); milliseconds = 124; - check_assertion("C", 0xC0FFEE); - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("C", 0xC0FFEE); - check_assertion("C", 0); - check_assertion("C", 0); + check_assertion("C", PRINT); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("C", PRINT); + check_assertion("C", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); __dlog_fini(); } @@ -99,29 +122,52 @@ void test_basic_10ms_interval() { local_advanced = "only_identical_neighbours"; local_time_ms = "10"; + local_warn_quantity = "0"; milliseconds = 123; - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("B", 0); - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("C", 0xC0FFEE); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("B", DEDUPLICATE); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("C", PRINT); milliseconds = 124; - check_assertion("C", 0); - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("C", 0xC0FFEE); - check_assertion("C", 0); - check_assertion("C", 0); + check_assertion("C", DEDUPLICATE); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("C", PRINT); + check_assertion("C", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); milliseconds = 133; - check_assertion("C", 0xC0FFEE); - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("C", 0xC0FFEE); - check_assertion("C", 0); - check_assertion("C", 0); + check_assertion("C", PRINT); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("C", PRINT); + check_assertion("C", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); + + __dlog_fini(); +} + +void test_basic_1ms_interval_warning() +{ + local_advanced = "only_identical_neighbours"; + local_time_ms = "10"; + local_warn_quantity = "10"; + milliseconds = 123; + check_assertion("A", PRINT); + for (int i = 0; i < 29; ++i) { + if (i == 0) + check_assertion("B", PRINT); + else if ((i + 1) % atoi(local_warn_quantity) == 0) + check_assertion("B", WARN); + else + check_assertion("B", DEDUPLICATE); + } + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("C", PRINT); __dlog_fini(); } @@ -130,21 +176,22 @@ void test_advanced_1ms_interval() { local_advanced = "all_identical_logs"; local_time_ms = "1"; + local_warn_quantity = "0"; milliseconds = 123; - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("B", 0); - check_assertion("A", 0); - check_assertion("B", 0); - check_assertion("C", 0xC0FFEE); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("C", PRINT); milliseconds = 124; - check_assertion("C", 0xC0FFEE); - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("A", 0); - check_assertion("C", 0); - check_assertion("C", 0); + check_assertion("C", PRINT); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("A", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); __dlog_fini(); } @@ -153,37 +200,96 @@ void test_advanced_10ms_interval() { local_advanced = "all_identical_logs"; local_time_ms = "10"; + local_warn_quantity = "0"; + milliseconds = 123; + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("C", PRINT); + + milliseconds = 124; + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); + + milliseconds = 132; + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); + + milliseconds = 133; + check_assertion("C", PRINT); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("A", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); + + __dlog_fini(); +} + +void test_advanced_10ms_interval_warning() +{ + local_advanced = "all_identical_logs"; + local_time_ms = "10"; + local_warn_quantity = "5"; milliseconds = 123; - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("B", 0); - check_assertion("A", 0); - check_assertion("B", 0); - check_assertion("C", 0xC0FFEE); + check_assertion("A", PRINT); + check_assertion("B", PRINT); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("C", PRINT); milliseconds = 124; - check_assertion("A", 0); - check_assertion("B", 0); - check_assertion("B", 0); - check_assertion("A", 0); - check_assertion("B", 0); - check_assertion("C", 0); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", WARN); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); milliseconds = 132; - check_assertion("A", 0); - check_assertion("B", 0); - check_assertion("B", 0); - check_assertion("A", 0); - check_assertion("B", 0); - check_assertion("C", 0); + check_assertion("A", WARN); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", WARN); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", WARN); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); milliseconds = 133; - check_assertion("C", 0xC0FFEE); - check_assertion("A", 0xC0FFEE); - check_assertion("B", 0xC0FFEE); - check_assertion("A", 0); - check_assertion("C", 0); - check_assertion("C", 0); + check_assertion("B", PRINT); + check_assertion("A", PRINT); + check_assertion("C", PRINT); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", WARN); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("B", DEDUPLICATE); + check_assertion("A", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); + check_assertion("C", DEDUPLICATE); __dlog_fini(); } @@ -192,13 +298,14 @@ void test_advanced_many_hashes() { local_advanced = "all_identical_logs"; local_time_ms = "1"; + local_warn_quantity = "0"; milliseconds = 123; char word[3] = {'\0'}; for (char first = 'A'; first <= 'Z'; ++first) { word[0] = first; for (char second = 'A'; second <= 'Z'; ++second) { word[1] = second; - check_assertion(word, 0xC0FFEE); + check_assertion(word, PRINT); } } @@ -210,6 +317,7 @@ void test_advanced_many_millisec() { local_advanced = "all_identical_logs"; local_time_ms = "1"; + local_warn_quantity = "0"; char msg[4]; for (milliseconds = 500; milliseconds < 900; milliseconds += 50) { @@ -217,21 +325,117 @@ void test_advanced_many_millisec() for (int i = 0; i < 1500; ++i) { int index = random() % 1000; snprintf(msg, sizeof msg, "%d", index); - check_assertion(msg, already_used[index] ? 0 : 0xC0FFEE); + check_assertion(msg, already_used[index] ? 0 : PRINT); already_used[index] = true; } } __dlog_fini(); } +void test_deduplicate_warn() +{ + use_real_deduplicate_warn = true; + local_warn_quantity = "11"; + __configure(); + char basic_log[25] = "This is a log,"; + deduplicate_warn(basic_log, sizeof basic_log, strlen(basic_log)); + assert(strcmp(basic_log, " LOG DUPLICATED 11 TIMES") == 0); + __dlog_fini(); + + local_warn_quantity = "17"; + __configure(); + char basic_log2[37] = "A completely different message,"; + deduplicate_warn(basic_log2, sizeof basic_log2, strlen(basic_log2)); + assert(strcmp(basic_log2, "A completely LOG DUPLICATED 17 TIMES") == 0); + __dlog_fini(); + + local_warn_quantity = "7"; + __configure(); + char basic_log3[31] = "This is a very long log,"; + deduplicate_warn(basic_log3, sizeof basic_log3, strlen(basic_log3)); + assert(strcmp(basic_log3, "This is LOG DUPLICATED 7 TIMES") == 0); + __dlog_fini(); + + local_warn_quantity = "14"; + __configure(); + char basic_log4[100] = "This is a log,"; + deduplicate_warn(basic_log4, sizeof basic_log4, strlen(basic_log4)); + assert(strcmp(basic_log4, "This is a log, LOG DUPLICATED 14 TIMES") == 0); + + local_warn_quantity = "xyz"; + __configure(); + for (int i = 0; i < 12; ++i) { + if (i == 0) + check_assertion("B", PRINT); + else + check_assertion("B", DEDUPLICATE); + } + + local_warn_quantity = "-1"; + __configure(); + for (int i = 0; i < 12; ++i) { + if (i == 0) + check_assertion("B", PRINT); + else + check_assertion("B", DEDUPLICATE); + } + + local_warn_quantity = ""; + __configure(); + for (int i = 0; i < 12; ++i) { + if (i == 0) + check_assertion("B", PRINT); + else + check_assertion("B", DEDUPLICATE); + } + + use_real_deduplicate_warn = false; + __dlog_fini(); +} + +void test_deduplicate_warn_random() +{ + use_real_deduplicate_warn = false; + local_advanced = "only_identical_neighbours"; + local_time_ms = "10"; + local_warn_quantity = "10"; + milliseconds = 123; + + srand(time(NULL)); + + for (int i = 0; i < 10; ++i) { + milliseconds++; + for (char c = 'A'; c <= 'Z'; ++c) { + int limit = rand() % 34 + 2; + for (int j = 0; j < limit; ++j) { + char log_text[2]; + log_text[0] = c; + log_text[1] = '\0'; + if (j == 0) + check_assertion(log_text, PRINT); + else if ((j + 1) % atoi(local_warn_quantity) == 0) + check_assertion(log_text, WARN); + else + check_assertion(log_text, DEDUPLICATE); + } + } + } + + __dlog_fini(); +} + int main() { test_basic_1ms_interval(); test_basic_10ms_interval(); + test_basic_1ms_interval_warning(); test_advanced_1ms_interval(); test_advanced_10ms_interval(); + test_advanced_10ms_interval_warning(); test_advanced_many_hashes(); test_advanced_many_millisec(); + test_deduplicate_warn(); + test_deduplicate_warn_random(); return 0; } diff --git a/tests/dlog_test.in b/tests/dlog_test.in index c5f8f10..9da1a17 100644 --- a/tests/dlog_test.in +++ b/tests/dlog_test.in @@ -882,6 +882,50 @@ if [ "$TEST_DYNAMIC_FILTERS" = "true" ]; then fi fi +dlogutil -c +echo "deduplicate_method=only_identical_neighbours" > "$RUNTIME_FILTERS_DIR/30-deduplicate.conf" +echo "deduplicate_interval_ms=10" >> "$RUNTIME_FILTERS_DIR/30-deduplicate.conf" + +dlogsend -p Info -b main -c 9 -t DLOG_DEDUP_TEST "Basic deduplication, default warn_quantity" +LOG_DETAILS="testing if deduplication with warnings works properly (1/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'Basic deduplication, default warn_quantity')" -eq 1 ] && ok || fail +LOG_DETAILS="testing if deduplication with warnings works properly (2/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'Basic deduplication, default warn_quantity LOG DUPLICATED')" -eq 0 ] && ok || fail + +dlogsend -p Info -b main -c 12 -t DLOG_DEDUP_TEST "Basic deduplication, default warn_quantity" +LOG_DETAILS="testing if deduplication with warnings works properly (3/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'Basic deduplication, default warn_quantity')" -eq 3 ] && ok || fail +LOG_DETAILS="testing if deduplication with warnings works properly (4/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'Basic deduplication, default warn_quantity LOG DUPLICATED')" -eq 1 ] && ok || fail + +echo "deduplicate_warn_quantity=8" >> "$RUNTIME_FILTERS_DIR/30-deduplicate.conf" + +dlogsend -p Info -b main -c 24 -t DLOG_DEDUP_TEST Message +LOG_DETAILS="testing if deduplication with warnings works properly (5/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c Message)" -eq 4 ] && ok || fail +LOG_DETAILS="testing if deduplication with warnings works properly (6/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'Message LOG DUPLICATED')" -eq 3 ] && ok || fail + +dlogsend -p Info -b main -c 8 -t DLOG_DEDUP_TEST longerMessage +LOG_DETAILS="testing if deduplication with warnings works properly (7/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c longerMessage)" -eq 2 ] && ok || fail +LOG_DETAILS="testing if deduplication with warnings works properly (8/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c Message)" -eq 6 ] && ok || fail +LOG_DETAILS="testing if deduplication with warnings works properly (9/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'longerMessage LOG DUPLICATED')" -eq 1 ] && ok || fail + +echo "deduplicate_warn_quantity=-1" >> "$RUNTIME_FILTERS_DIR/30-deduplicate.conf" + +dlogsend -p Info -b main -c 12 -t DLOG_DEDUP_TEST "Basic deduplication, no warning" +LOG_DETAILS="testing if deduplication with warnings works properly (10/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'Basic deduplication, no warning')" -eq 1 ] && ok || fail +LOG_DETAILS="testing if deduplication with warnings works properly (11/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'Basic deduplication')" -eq 4 ] && ok || fail +LOG_DETAILS="testing if deduplication with warnings works properly (12/12)" +[ "$(dlogutil -d DLOG_DEDUP_TEST | grep -c 'Basic deduplication, no warning LOG DUPLICATED')" -eq 0 ] && ok || fail + +rm "$RUNTIME_FILTERS_DIR/30-deduplicate.conf" + LOG_DETAILS="testing if libdlogutil clears the buffer correctly" test_libdlogutil clear $LIBDLOGUTIL_CORRECT_PID $type && ok || fail -- 2.7.4