#include "stats.h"
#include "util.h"
+struct fireperf_stats fireperf_stats_step(
+ const struct fireperf_stats* old, const struct fireperf_stats* new) {
+ 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,
+ };
+
+ return stats;
+}
+
int fireperf_stats_dump(struct fireperf_ctx* ctx,
struct fireperf_stats* old, struct fireperf_stats* new) {
// Compute the delta since the last dump
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,
-
- };
+ const struct fireperf_stats stats = fireperf_stats_step(old, new);
// Format timestamp
const char* timestamp = format_timespec(&stats.t);
#include "stats.h"
#include "tui.h"
-#define MAX_STATS 128
+#define MAX_STATS 1024
struct fireperf_tui {
struct fireperf_ctx* ctx;
// The frame around the screen
WINDOW* frame;
+ // The graph inside the frame
+ WINDOW* graph;
+
// The status bar
WINDOW* status;
};
+static int fireperf_tui_setup_graph(struct fireperf_tui* tui) {
+ int r;
+
+ // Create the graph
+ tui->graph = newwin(LINES - 3, COLS - 3, 1, 1);
+ if (!tui->graph)
+ return 1;
+
+ // Refresh
+ wrefresh(tui->graph);
+
+ return 0;
+}
+
static int fireperf_tui_setup_frame(struct fireperf_tui* tui) {
int r;
// Configure a few colours
init_pair(1, COLOR_RED, COLOR_BLACK);
- init_pair(2, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(2, COLOR_GREEN, COLOR_BLACK);
init_pair(3, COLOR_BLUE, COLOR_BLACK);
init_pair(4, COLOR_BLACK, COLOR_WHITE);
if (r)
return r;
+ // Setup the graph
+ r = fireperf_tui_setup_graph(tui);
+ if (r)
+ return r;
+
// Setup the status bar
r = fireperf_tui_setup_status(tui);
if (r)
return 0;
}
+static const struct fireperf_stats* fireperf_tui_get_stats(struct fireperf_tui* tui, int i) {
+ return &tui->stats[(tui->s - i) % MAX_STATS];
+}
+
+static size_t fireperf_tui_get_peak_bps(struct fireperf_tui* tui, int max) {
+ const struct fireperf_stats* stats = NULL;
+ size_t peak = 0;
+
+ for (unsigned int i = 0; i < max; i++) {
+ stats = fireperf_tui_get_stats(tui, i);
+
+ if (stats->bytes_sent > peak)
+ peak = stats->bytes_sent;
+
+ if (stats->bytes_received > peak)
+ peak = stats->bytes_received;
+ }
+
+ return peak;
+}
+
+/*
+ Draws the big graph
+*/
+static int fireperf_tui_draw_graph(struct fireperf_tui* tui) {
+ const struct fireperf_stats* stats = NULL;
+
+ int max_x = 0;
+ int max_y = 0;
+
+ // Clear any previous content
+ wclear(tui->graph);
+
+ // Fetch the dimensions of the frame
+ getmaxyx(tui->graph, max_y, max_x);
+
+ size_t peak_bps = fireperf_tui_get_peak_bps(tui, max_x);
+
+ // Figure out how many bps a step represents
+ double step = peak_bps / (max_y + 1);
+
+ // Make the brush red
+ wattron(tui->graph, COLOR_PAIR(1));
+
+ // Draw any sent traffic
+ for (unsigned int x = 0; x < max_x; x++) {
+ stats = fireperf_tui_get_stats(tui, x);
+
+ mvwaddch(tui->graph, max_y - (stats->bytes_sent / step), x, '#');
+ }
+
+ wattroff(tui->graph, COLOR_PAIR(1));
+
+ // Make the brush green
+ wattron(tui->graph, COLOR_PAIR(2));
+
+ // Draw any received traffic
+ for (unsigned int x = 0; x < max_x; x++) {
+ stats = fireperf_tui_get_stats(tui, x);
+
+ mvwaddch(tui->graph, max_y - (stats->bytes_received / step), x, '#');
+ }
+
+ wattroff(tui->graph, COLOR_PAIR(2));
+
+ wrefresh(tui->graph);
+
+ return 0;
+}
+
/*
Called when there is new data to update the UI
*/
int fireperf_tui_update(struct fireperf_tui* tui, struct fireperf_stats stats) {
int r;
+ // Fetch the previous stats
+ const struct fireperf_stats* prev_stats = fireperf_tui_get_stats(tui, 1);
+
// Store stats
- tui->stats[tui->s++] = stats;
+ tui->stats[tui->s++] = fireperf_stats_step(prev_stats, &stats);
// Wrap the pointer around
tui->s %= MAX_STATS;
- return 0;
+ // Draw the graph
+ return fireperf_tui_draw_graph(tui);
}