#include "log.h" #include #include #include #include #include const char* get_current_time() { static char buffer[20]; time_t now = time(NULL); struct tm* tm_info = localtime(&now); strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info); return buffer; } 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"); if (log_file == NULL) { fprintf(stderr, "Could not open log file for writing.\n"); return; } va_list args; va_start(args, format); int message_size = vsnprintf(NULL, 0, format, args) + 1; va_end(args); 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); }