Add exponential backoff to logging

This commit is contained in:
Sheldon Lee 2024-11-12 19:22:55 +08:00
parent 351d600eba
commit 797689ae27
2 changed files with 47 additions and 11 deletions

56
log.c
View File

@ -1,5 +1,6 @@
#include "log.h" #include "log.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <time.h> #include <time.h>
@ -16,6 +17,10 @@ const char* get_current_time()
void log_message(LogLevel level, const char* format, ...) void log_message(LogLevel level, const char* format, ...)
{ {
const char* level_strings[] = { "INFO", "WARNING", "ERROR" }; 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 // Open the log file in append mode
FILE* log_file = fopen("logfile.txt", "a"); FILE* log_file = fopen("logfile.txt", "a");
@ -26,19 +31,48 @@ void log_message(LogLevel level, const char* format, ...)
va_list args; va_list args;
// Write the log message to the file
va_start(args, format); va_start(args, format);
fprintf(log_file, "[%s] [%s] ", get_current_time(), level_strings[level]); int message_size = vsnprintf(NULL, 0, format, args) + 1;
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");
va_end(args); 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); fclose(log_file);
} }

2
log.h
View File

@ -2,6 +2,8 @@
#ifndef LOG_H #ifndef LOG_H
#define LOG_H #define LOG_H
#define LOG_MAX_REPEAT 5
typedef enum { typedef enum {
LOG_INFO, LOG_INFO,
LOG_WARNING, LOG_WARNING,