From 797689ae27cb6d35e5911e6f2e9edd2e5201e877 Mon Sep 17 00:00:00 2001 From: Sheldon Lee Date: Tue, 12 Nov 2024 19:22:55 +0800 Subject: [PATCH] Add exponential backoff to logging --- log.c | 56 +++++++++++++++++++++++++++++++++++++++++++++----------- log.h | 2 ++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/log.c b/log.c index b2781c9..d08218b 100644 --- a/log.c +++ b/log.c @@ -1,5 +1,6 @@ #include "log.h" #include +#include #include #include #include @@ -16,6 +17,10 @@ const char* get_current_time() void log_message(LogLevel level, const char* format, ...) { const char* level_strings[] = { "INFO", "WARNING", "ERROR" }; + static char* last_message = NULL; + static unsigned int repeat_count = 0; + static unsigned int exp_count = 1; + char* message = NULL; // Open the log file in append mode FILE* log_file = fopen("logfile.txt", "a"); @@ -26,19 +31,48 @@ void log_message(LogLevel level, const char* format, ...) va_list args; - // Write the log message to the file va_start(args, format); - fprintf(log_file, "[%s] [%s] ", get_current_time(), level_strings[level]); - vfprintf(log_file, format, args); - fprintf(log_file, "\n"); - va_end(args); - // Write to stdout - va_start(args, format); - printf("[%s] ", level_strings[level]); - vprintf(format, args); - printf("\n"); + int message_size = vsnprintf(NULL, 0, format, args) + 1; va_end(args); - // Close the log file + va_start(args, format); + message = malloc(message_size); + vsnprintf(message, message_size, format, args); + va_end(args); + + if (!last_message) goto output; + // If current and last messages different + if (strcmp(message, last_message)) { + repeat_count = 0; + exp_count = 1; + goto output; + } + repeat_count++; + if (repeat_count < LOG_MAX_REPEAT) goto output; + + unsigned int bit_width = sizeof(exp_count) * 8; // Calculate the number of bits in an int + unsigned int leftmost_bit_mask = 1 << (bit_width - 1); // Create a mask with the + while (exp_count < repeat_count && exp_count < leftmost_bit_mask) exp_count = exp_count << 1; + if (repeat_count != exp_count && repeat_count != LOG_MAX_REPEAT) goto clean; + + fprintf(log_file, "[%s] [%s] %s !! x%u !!\n", get_current_time(), level_strings[level], last_message, repeat_count); + printf("[%s] %s !! x%u !!\n", level_strings[level], last_message, repeat_count); + + goto clean; +output: + // Write the log message to the file + fprintf(log_file, "[%s] [%s] ", get_current_time(), level_strings[level]); + fprintf(log_file, "%s", message); + fprintf(log_file, "\n"); + // Write to stdout + printf("[%s] ", level_strings[level]); + printf("%s", message); + printf("\n"); + // Record last message + if (last_message) free(last_message); + last_message = malloc(message_size); + strcpy(last_message, message); +clean: + free(message); fclose(log_file); } diff --git a/log.h b/log.h index 1a312fa..e2d33ab 100644 --- a/log.h +++ b/log.h @@ -2,6 +2,8 @@ #ifndef LOG_H #define LOG_H +#define LOG_MAX_REPEAT 5 + typedef enum { LOG_INFO, LOG_WARNING,