From a44b17fcf1b04a8cabbd217c8c5e149b887e7a74 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 19 Sep 2024 11:39:59 +0000 Subject: [PATCH] stats: Refactor stats calculation Signed-off-by: Michael Tremer --- src/ctx.c | 33 ++++++++++++++++++++++++++++++--- src/ctx.h | 6 ++++++ src/main.c | 6 +----- src/stats.c | 49 +++++++++++++++++++++++-------------------------- src/stats.h | 8 +++++--- 5 files changed, 65 insertions(+), 37 deletions(-) diff --git a/src/ctx.c b/src/ctx.c index f7a24af..501d750 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -270,6 +270,9 @@ int fireperf_ctx_create(struct fireperf_ctx** ctx, int argc, char* argv[]) { goto ERROR; } + // Initialize the stats + c->stats = fireperf_ctx_get_stats(c); + // Return the context *ctx = c; @@ -298,8 +301,6 @@ static struct fireperf_worker* fireperf_ctx_find_idle_worker(struct fireperf_ctx if (!stats) continue; - printf("C %lu\n", stats->open_connections); - // If the worker has no open connections, we can use it if (stats->open_connections == 0) return ctx->workers[i]; @@ -385,11 +386,19 @@ ERROR: struct fireperf_stats fireperf_ctx_get_stats(struct fireperf_ctx* ctx) { const struct fireperf_stats* s = NULL; + int r; struct fireperf_stats stats = {}; + // Fetch the time + r = clock_gettime(CLOCK_REALTIME, &stats.t); + if (r) { + ERROR(ctx, "Could not fetch the time: %m\n"); + return stats; + } + // Add up everything from all workers - for (unsigned int i = 0; i < MAX_WORKERS; i++) { + for (unsigned int i = 0; i < ctx->num_workers; i++) { if (!ctx->workers[i]) continue; @@ -410,3 +419,21 @@ struct fireperf_stats fireperf_ctx_get_stats(struct fireperf_ctx* ctx) { return stats; } + +int fireperf_ctx_dump_stats(struct fireperf_ctx* ctx) { + struct fireperf_stats stats = {}; + int r; + + // Fetch the current stats + stats = fireperf_ctx_get_stats(ctx); + + // Dump the stats + r = fireperf_stats_dump(ctx, &ctx->stats, &stats); + if (r) + return r; + + // Replace the stats for the next iteration + ctx->stats = stats; + + return 0; +} diff --git a/src/ctx.h b/src/ctx.h index 23a8d13..e8fceb1 100644 --- a/src/ctx.h +++ b/src/ctx.h @@ -24,6 +24,7 @@ #include #include "constants.h" +#include "stats.h" // Forward declarations struct fireperf_worker; @@ -55,6 +56,9 @@ struct fireperf_ctx { struct fireperf_worker* workers[MAX_WORKERS]; unsigned int num_workers; unsigned int max_workers; + + // Stats + struct fireperf_stats stats; }; #include "main.h" @@ -66,4 +70,6 @@ void fireperf_ctx_free(struct fireperf_ctx* ctx); struct fireperf_worker* fireperf_ctx_fetch_worker(struct fireperf_ctx* ctx); struct fireperf_stats fireperf_ctx_get_stats(struct fireperf_ctx* ctx); +int fireperf_ctx_dump_stats(struct fireperf_ctx* ctx); + #endif /* FIREPERF_CTX_H */ diff --git a/src/main.c b/src/main.c index a8ba570..d03017b 100644 --- a/src/main.c +++ b/src/main.c @@ -94,7 +94,6 @@ static int set_limits(struct fireperf_ctx* ctx) { int main(int argc, char* argv[]) { struct fireperf_ctx* ctx = NULL; - struct fireperf_stats stats = { 0 }; uint64_t expirations = 0; void* data = NULL; int epollfd = -1; @@ -183,11 +182,8 @@ int main(int argc, char* argv[]) { goto ERROR; } - // Cumulate stats - stats = fireperf_ctx_get_stats(ctx); - // Print the stats - r = fireperf_dump_stats(ctx, &stats, ctx->mode); + r = fireperf_ctx_dump_stats(ctx); if (r) goto ERROR; diff --git a/src/stats.c b/src/stats.c index d7a80f5..f9629d3 100644 --- a/src/stats.c +++ b/src/stats.c @@ -28,33 +28,38 @@ #include "stats.h" #include "util.h" -int fireperf_dump_stats(struct fireperf_ctx* ctx, struct fireperf_stats* stats, int mode) { - struct timespec now; - - // Fetch the time - int r = clock_gettime(CLOCK_REALTIME, &now); - if (r) { - ERROR(ctx, "Could not fetch the time: %s\n", strerror(errno)); - return 1; - } - - double delta = timespec_delta(&now, &stats->last_printed); +int fireperf_stats_dump(struct fireperf_ctx* ctx, + struct fireperf_stats* old, struct fireperf_stats* new) { + // Compute the delta since the last dump + double delta = timespec_delta(&new->t, &old->t); // Called too soon again? if (delta < 0.1) return 0; + // Compute the changes + const struct fireperf_stats stats = { + .t = new->t, + .open_connections = new->open_connections, + .connections = new->connections - old->connections, + .total_bytes_received = new->total_bytes_received, + .bytes_received = new->total_bytes_received - old->total_bytes_received, + .total_bytes_sent = new->total_bytes_sent, + .bytes_sent = new->total_bytes_sent - old->total_bytes_sent, + + }; + // Format timestamp - const char* timestamp = format_timespec(&now); + const char* timestamp = format_timespec(&stats.t); INFO(ctx, "--- %s -------------------------\n", timestamp); INFO(ctx, " : %12s %12s\n", "RX", "TX"); - INFO(ctx, " %-20s: %25u\n", "Open Connection(s)", stats->open_connections); - INFO(ctx, " %-20s: %23.2f/s\n", "New Connections", stats->connections / delta); + INFO(ctx, " %-20s: %25u\n", "Open Connection(s)", stats.open_connections); + INFO(ctx, " %-20s: %23.2f/s\n", "New Connections", stats.connections / delta); // Show current bandwidth - char* bps_received = format_size(stats->bytes_received * 8 / delta, FIREPERF_FORMAT_BITS); - char* bps_sent = format_size(stats->bytes_sent * 8 / delta, FIREPERF_FORMAT_BITS); + char* bps_received = format_size(stats.bytes_received * 8 / delta, FIREPERF_FORMAT_BITS); + char* bps_sent = format_size(stats.bytes_sent * 8 / delta, FIREPERF_FORMAT_BITS); if (bps_received || bps_sent) { INFO(ctx, " %-20s: %10s/s %10s/s\n", "Current Bandwidth", bps_received, bps_sent); @@ -66,8 +71,8 @@ int fireperf_dump_stats(struct fireperf_ctx* ctx, struct fireperf_stats* stats, } // Total bytes - char* total_bytes_received = format_size(stats->total_bytes_received, FIREPERF_FORMAT_BYTES); - char* total_bytes_sent = format_size(stats->total_bytes_sent, FIREPERF_FORMAT_BYTES); + char* total_bytes_received = format_size(stats.total_bytes_received, FIREPERF_FORMAT_BYTES); + char* total_bytes_sent = format_size(stats.total_bytes_sent, FIREPERF_FORMAT_BYTES); if (total_bytes_received || total_bytes_sent) { INFO(ctx, " %-20s: %12s %12s\n", "Total Bytes", total_bytes_received, total_bytes_sent); @@ -81,13 +86,5 @@ int fireperf_dump_stats(struct fireperf_ctx* ctx, struct fireperf_stats* stats, // Empty line INFO(ctx, "\n"); - // Remember when this was printed last - stats->last_printed = now; - - // Reset statistics - stats->connections = 0; - stats->bytes_received = 0; - stats->bytes_sent = 0; - return 0; } diff --git a/src/stats.h b/src/stats.h index 21c2449..273fbde 100644 --- a/src/stats.h +++ b/src/stats.h @@ -25,7 +25,7 @@ // Struct to collect statistics struct fireperf_stats { - struct timespec last_printed; + struct timespec t; // Total number of open connections unsigned int open_connections; @@ -40,8 +40,10 @@ struct fireperf_stats { size_t total_bytes_sent; }; -#include "ctx.h" +// Forward declararion +struct fireperf_ctx; -int fireperf_dump_stats(struct fireperf_ctx* ctx, struct fireperf_stats* stats, int mode); +int fireperf_stats_dump(struct fireperf_ctx* ctx, + struct fireperf_stats* old, struct fireperf_stats* new); #endif /* FIREPERF_STATS_H */ -- 2.47.2