#include "logger.h" #include #include #include #include #include #define WINDOW_SEC 1 #define MAX_TIMES 1000 #define ISO_TIME_BUF_SIZE 32 #define MICROSECONDS_IN_SECOND 1000000 #define MICROSECONDS_IN_MILLISECOND 1000 #define CSV_HEADER "timestamp,sent_ms,received_ms,rtt_ms,throughput_msg_per_s\n" #define CSV_LINE_FORMAT "%s,%lld,%lld,%lld,%d\n" static FILE *csv_file = NULL; static double msg_times[MAX_TIMES]; static int msg_count = 0; /** * @brief Returns the current time in milliseconds since the Epoch. * * @return Current time in milliseconds (int64). */ static long long current_time_ms(void); /** * @brief Returns the current time in seconds (with microsecond precision) since * the Epoch. * * @return Current time in seconds (double). */ static double current_time_sec(void); /** * @brief Updates the sliding window of message timestamps and returns the count * of messages within WINDOW_SEC. * * @param now Current timestamp in seconds. * @return Number of messages in the last WINDOW_SEC seconds. */ static int update_throughput_window(double now); static long long current_time_ms(void) { struct timeval tv; gettimeofday(&tv, NULL); return ((long long)tv.tv_sec * 1000) + (tv.tv_usec / MICROSECONDS_IN_MILLISECOND); } static double current_time_sec(void) { struct timeval tv; gettimeofday(&tv, NULL); return (double)tv.tv_sec + (tv.tv_usec / (double)MICROSECONDS_IN_SECOND); } static int update_throughput_window(double current_time) { int msg_index, window_count = 0; for (msg_index = 0; msg_index < msg_count; msg_index++) { if (current_time - msg_times[msg_index] < WINDOW_SEC) msg_times[window_count++] = msg_times[msg_index]; } msg_times[window_count++] = current_time; msg_count = window_count; return msg_count; } void logger_init(const char *filename) { csv_file = fopen(filename, "w"); if (!csv_file) { perror("Cannot open CSV file"); exit(EXIT_FAILURE); } fprintf(csv_file, CSV_HEADER); fflush(csv_file); } void logger_cleanup(void) { if (csv_file) { fclose(csv_file); csv_file = NULL; } } void logger_handle_message(const void *payload, int payloadlen) { if (payloadlen <= 0) return; char *payload_str = malloc(payloadlen + 1); if (!payload_str) return; memcpy(payload_str, payload, payloadlen); payload_str[payloadlen] = '\0'; long long sent_ms = atoll(payload_str); free(payload_str); long long received_ms = current_time_ms(); long long rtt = received_ms - sent_ms; double now_sec = current_time_sec(); int throughput = update_throughput_window(now_sec); time_t now = time(NULL); struct tm *tm_info = localtime(&now); char iso_time[ISO_TIME_BUF_SIZE]; strftime(iso_time, sizeof(iso_time), "%Y-%m-%dT%H:%M:%S", tm_info); if (csv_file) { fprintf(csv_file, CSV_LINE_FORMAT, iso_time, sent_ms, received_ms, rtt, throughput); fflush(csv_file); } printf("RTT: %lld ms | Throughput: %d msg/s\n", rtt, throughput); }