diff options
| author | Filip Wandzio <contact@philw.dev> | 2025-09-05 03:30:24 +0200 |
|---|---|---|
| committer | Filip Wandzio <contact@philw.dev> | 2025-09-05 03:30:24 +0200 |
| commit | 01713bbe20d2cf5aafbe5eb32721d3e4fc5823d8 (patch) | |
| tree | 33748d0019e3939bd0daf50940407e51d4325a8f /analysis/rtt/src/logger.c | |
| parent | 1ba21da6cbc63c0c549fb92731e25bedc482eb51 (diff) | |
| download | e1-01713bbe20d2cf5aafbe5eb32721d3e4fc5823d8.tar.gz e1-01713bbe20d2cf5aafbe5eb32721d3e4fc5823d8.zip | |
Standarize the project directory for monorepo-like developer experience
Move the clang formatter to the root of the three so all nested projects could use it
Provide README for all other projects
Refactor the code in rtt agregator
Signed-off-by: Filip Wandzio <contact@philw.dev>
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 | } |
