diff options
Diffstat (limited to 'analysis/rtt/src/logger.c')
| -rw-r--r-- | analysis/rtt/src/logger.c | 151 |
1 files changed, 96 insertions, 55 deletions
diff --git a/analysis/rtt/src/logger.c b/analysis/rtt/src/logger.c index ed5f6e5..e1dd2f3 100644 --- a/analysis/rtt/src/logger.c +++ b/analysis/rtt/src/logger.c | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | |||
| 2 | #include "logger.h" | 1 | #include "logger.h" |
| 3 | #include <stdio.h> | 2 | #include <stdio.h> |
| 4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
| @@ -9,78 +8,120 @@ | |||
| 9 | #define WINDOW_SEC 1 | 8 | #define WINDOW_SEC 1 |
| 10 | #define MAX_TIMES 1000 | 9 | #define MAX_TIMES 1000 |
| 11 | 10 | ||
| 11 | #define ISO_TIME_BUF_SIZE 32 | ||
| 12 | |||
| 13 | #define MICROSECONDS_IN_SECOND 1000000 | ||
| 14 | #define MICROSECONDS_IN_MILLISECOND 1000 | ||
| 15 | |||
| 16 | #define CSV_HEADER "timestamp,sent_ms,received_ms,rtt_ms,throughput_msg_per_s\n" | ||
| 17 | #define CSV_LINE_FORMAT "%s,%lld,%lld,%lld,%d\n" | ||
| 18 | |||
| 12 | static FILE *csv_file = NULL; | 19 | static FILE *csv_file = NULL; |
| 13 | static double msg_times[MAX_TIMES]; | 20 | static double msg_times[MAX_TIMES]; |
| 14 | static int msg_count = 0; | 21 | static int msg_count = 0; |
| 15 | 22 | ||
| 16 | static long long current_time_ms() { | 23 | /** |
| 17 | struct timeval tv; | 24 | * @brief Returns the current time in milliseconds since the Epoch. |
| 18 | gettimeofday(&tv, NULL); | 25 | * |
| 19 | return ((long long)tv.tv_sec * 1000) + (tv.tv_usec / 1000); | 26 | * @return Current time in milliseconds (int64). |
| 27 | */ | ||
| 28 | static long long current_time_ms(void); | ||
| 29 | |||
| 30 | /** | ||
| 31 | * @brief Returns the current time in seconds (with microsecond precision) since | ||
| 32 | * the Epoch. | ||
| 33 | * | ||
| 34 | * @return Current time in seconds (double). | ||
| 35 | */ | ||
| 36 | static double current_time_sec(void); | ||
| 37 | |||
| 38 | /** | ||
| 39 | * @brief Updates the sliding window of message timestamps and returns the count | ||
| 40 | * of messages within WINDOW_SEC. | ||
| 41 | * | ||
| 42 | * @param now Current timestamp in seconds. | ||
| 43 | * @return Number of messages in the last WINDOW_SEC seconds. | ||
| 44 | */ | ||
| 45 | static int update_throughput_window(double now); | ||
| 46 | |||
| 47 | static long long current_time_ms(void) | ||
| 48 | { | ||
| 49 | struct timeval tv; | ||
| 50 | gettimeofday(&tv, NULL); | ||
| 51 | return ((long long)tv.tv_sec * 1000) + | ||
| 52 | (tv.tv_usec / MICROSECONDS_IN_MILLISECOND); | ||
| 20 | } | 53 | } |
| 21 | 54 | ||
| 22 | static double current_time_sec() { | 55 | static double current_time_sec(void) |
| 23 | struct timeval tv; | 56 | { |
| 24 | gettimeofday(&tv, NULL); | 57 | struct timeval tv; |
| 25 | return (double)tv.tv_sec + (tv.tv_usec / 1e6); | 58 | gettimeofday(&tv, NULL); |
| 59 | return (double)tv.tv_sec + | ||
| 60 | (tv.tv_usec / (double)MICROSECONDS_IN_SECOND); | ||
| 26 | } | 61 | } |
| 27 | 62 | ||
| 28 | static int update_throughput_window(double now) { | 63 | static int update_throughput_window(double current_time) |
| 29 | int i, new_count = 0; | 64 | { |
| 30 | for (i = 0; i < msg_count; i++) { | 65 | int msg_index, window_count = 0; |
| 31 | if (now - msg_times[i] < WINDOW_SEC) { | 66 | for (msg_index = 0; msg_index < msg_count; msg_index++) { |
| 32 | msg_times[new_count++] = msg_times[i]; | 67 | if (current_time - msg_times[msg_index] < WINDOW_SEC) |
| 33 | } | 68 | msg_times[window_count++] = msg_times[msg_index]; |
| 34 | } | 69 | } |
| 35 | msg_times[new_count++] = now; | 70 | msg_times[window_count++] = current_time; |
| 36 | msg_count = new_count; | 71 | msg_count = window_count; |
| 37 | return msg_count; | 72 | return msg_count; |
| 38 | } | 73 | } |
| 39 | 74 | ||
| 40 | void logger_init(const char *filename) { | 75 | void logger_init(const char *filename) |
| 41 | csv_file = fopen(filename, "w"); | 76 | { |
| 42 | if (!csv_file) { | 77 | csv_file = fopen(filename, "w"); |
| 43 | perror("Cannot open CSV file"); | 78 | if (!csv_file) { |
| 44 | exit(EXIT_FAILURE); | 79 | perror("Cannot open CSV file"); |
| 45 | } | 80 | exit(EXIT_FAILURE); |
| 46 | fprintf(csv_file, | 81 | } |
| 47 | "timestamp,sent_ms,received_ms,rtt_ms,throughput_msg_per_s\n"); | 82 | fprintf(csv_file, CSV_HEADER); |
| 48 | fflush(csv_file); | 83 | fflush(csv_file); |
| 49 | } | 84 | } |
| 50 | 85 | ||
| 51 | void logger_cleanup() { | 86 | void logger_cleanup(void) |
| 52 | if (csv_file) { | 87 | { |
| 53 | fclose(csv_file); | 88 | if (csv_file) { |
| 54 | csv_file = NULL; | 89 | fclose(csv_file); |
| 55 | } | 90 | csv_file = NULL; |
| 91 | } | ||
| 56 | } | 92 | } |
| 57 | 93 | ||
| 58 | void logger_handle_message(const void *payload, int payloadlen) { | 94 | void logger_handle_message(const void *payload, int payloadlen) |
| 59 | char *payload_str = malloc(payloadlen + 1); | 95 | { |
| 60 | if (!payload_str) | 96 | if (payloadlen <= 0) |
| 61 | return; | 97 | return; |
| 62 | memcpy(payload_str, payload, payloadlen); | 98 | |
| 63 | payload_str[payloadlen] = '\0'; | 99 | char *payload_str = malloc(payloadlen + 1); |
| 100 | if (!payload_str) | ||
| 101 | return; | ||
| 102 | |||
| 103 | memcpy(payload_str, payload, payloadlen); | ||
| 104 | payload_str[payloadlen] = '\0'; | ||
| 64 | 105 | ||
| 65 | long long sent_ms = atoll(payload_str); | 106 | long long sent_ms = atoll(payload_str); |
| 66 | free(payload_str); | 107 | free(payload_str); |
| 67 | 108 | ||
| 68 | long long received_ms = current_time_ms(); | 109 | long long received_ms = current_time_ms(); |
| 69 | long long rtt = received_ms - sent_ms; | 110 | long long rtt = received_ms - sent_ms; |
| 70 | 111 | ||
| 71 | double now_sec = current_time_sec(); | 112 | double now_sec = current_time_sec(); |
| 72 | int throughput = update_throughput_window(now_sec); | 113 | int throughput = update_throughput_window(now_sec); |
| 73 | 114 | ||
| 74 | time_t now = time(NULL); | 115 | time_t now = time(NULL); |
| 75 | struct tm *tm_info = localtime(&now); | 116 | struct tm *tm_info = localtime(&now); |
| 76 | char iso_time[32]; | 117 | char iso_time[ISO_TIME_BUF_SIZE]; |
| 77 | strftime(iso_time, sizeof(iso_time), "%Y-%m-%dT%H:%M:%S", tm_info); | 118 | strftime(iso_time, sizeof(iso_time), "%Y-%m-%dT%H:%M:%S", tm_info); |
| 78 | 119 | ||
| 79 | if (csv_file) { | 120 | if (csv_file) { |
| 80 | fprintf(csv_file, "%s,%lld,%lld,%lld,%d\n", iso_time, sent_ms, received_ms, | 121 | fprintf(csv_file, CSV_LINE_FORMAT, iso_time, sent_ms, |
| 81 | rtt, throughput); | 122 | received_ms, rtt, throughput); |
| 82 | fflush(csv_file); | 123 | fflush(csv_file); |
| 83 | } | 124 | } |
| 84 | 125 | ||
| 85 | printf("RTT: %lld ms | Throughput: %d msg/s\n", rtt, throughput); | 126 | printf("RTT: %lld ms | Throughput: %d msg/s\n", rtt, throughput); |
| 86 | } | 127 | } |
