From: Michael Tremer Date: Thu, 30 Oct 2025 23:52:53 +0000 (+0000) Subject: graphs: disks: Add IO X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8f443ffa41811c890de49e35e9e6a9ca5f44c7db;p=oddments%2Fcollecty.git graphs: disks: Add IO Signed-off-by: Michael Tremer --- diff --git a/src/daemon/graph.c b/src/daemon/graph.c index 5f2ba64..1c400ef 100644 --- a/src/daemon/graph.c +++ b/src/daemon/graph.c @@ -550,6 +550,11 @@ int td_graph_vlabel_bps(td_ctx* ctx, td_graph* graph, return __td_string_set(vlabel, length, _("Bits Per Second")); } +int td_graph_vlabel_bytes(td_ctx* ctx, td_graph* graph, + const td_graph_render_options* options, const char* object, char* vlabel, size_t length) { + return __td_string_set(vlabel, length, _("Bytes")); +} + int td_graph_vlabel_days(td_ctx* ctx, td_graph* graph, const td_graph_render_options* options, const char* object, char* vlabel, size_t length) { return __td_string_set(vlabel, length, _("Days")); diff --git a/src/daemon/graph.h b/src/daemon/graph.h index 99d6bb4..5269f23 100644 --- a/src/daemon/graph.h +++ b/src/daemon/graph.h @@ -120,6 +120,9 @@ td_graph_temps td_graph_temperature(const td_graph_render_options* options); int td_graph_vlabel_bps(td_ctx* ctx, td_graph* graph, const td_graph_render_options* options, const char* object, char* vlabel, size_t length); +int td_graph_vlabel_bytes(td_ctx* ctx, td_graph* graph, + const td_graph_render_options* options, const char* object, char* vlabel, size_t length); + int td_graph_vlabel_days(td_ctx* ctx, td_graph* graph, const td_graph_render_options* options, const char* object, char* vlabel, size_t length); diff --git a/src/daemon/graphs.c b/src/daemon/graphs.c index e3f0c46..51b7ab6 100644 --- a/src/daemon/graphs.c +++ b/src/daemon/graphs.c @@ -50,7 +50,6 @@ static const td_graph_impl* graph_impls[] = { &conntrack_graph, &contextswitches_graph, &cpufreq_graph, - &disk_temp_graph, &hostapd_station_bandwidth_graph, &hostapd_station_rate_info_graph, &hostapd_station_signal_graph, @@ -59,6 +58,10 @@ static const td_graph_impl* graph_impls[] = { &processor_graph, &uptime_graph, + // Disk + &disk_io_graph, + &disk_temp_graph, + // Pressure (PSI) &pressure_cpu_graph, &pressure_io_graph, diff --git a/src/daemon/graphs/disk.c b/src/daemon/graphs/disk.c index 2d36421..2bfeb18 100644 --- a/src/daemon/graphs/disk.c +++ b/src/daemon/graphs/disk.c @@ -23,6 +23,43 @@ #include "graph.h" #include "disk.h" +static int disk_io_title(td_ctx* ctx, td_graph* graph, + const char* object, char* title, size_t length) { + return __td_string_set(title, length, _("Disk Input/Output")); +} + +static int disk_io_render(td_ctx* ctx, td_graph* graph, + const td_graph_render_options* options, td_args* args, const char* object) { + int r; + + // Load all sources + r = td_graph_require_source(graph, args, "disk", object); + if (r < 0) + return r; + + // Header + PRINT_HEADER4(args, _("Current"), _("Average"), _("Minimum"), _("Maximum")); + + // Draw the temperature + DRAW_IO_SECTORS(args, object, "read_sectors", "write_sectors"); + + // XXX TODO Add discarded bytes + + return 0; +} + +const td_graph_impl disk_io_graph = { + .name = "DiskIO", + .render = disk_io_render, + .title = disk_io_title, + .vlabel = td_graph_vlabel_bytes, + + // Limits + .lower_limit = 0, + .upper_limit = LONG_MAX, +}; + + static int disk_temp_title(td_ctx* ctx, td_graph* graph, const char* object, char* title, size_t length) { return __td_string_set(title, length, _("Disk Temperature")); diff --git a/src/daemon/graphs/disk.h b/src/daemon/graphs/disk.h index 26c45b3..5215ada 100644 --- a/src/daemon/graphs/disk.h +++ b/src/daemon/graphs/disk.h @@ -23,6 +23,7 @@ #include "../graph.h" +extern const td_graph_impl disk_io_graph; extern const td_graph_impl disk_temp_graph; #endif /* TELEMETRY_GRAPH_DISK_H */ diff --git a/src/daemon/graphs/graph.h b/src/daemon/graphs/graph.h index 0875b5b..7246f1a 100644 --- a/src/daemon/graphs/graph.h +++ b/src/daemon/graphs/graph.h @@ -74,6 +74,8 @@ typedef enum flags { #define SECONDS_HIGHRES "%%12.2lf%%ss" #define SECONDS "%%13.2lfs" +#define BYTES "%%12.2lf%%s%s", _("B") + // Temperatures #define KELVIN "%%12.2lf K" #define CELSIUS "%%11.2lf °C" @@ -235,6 +237,7 @@ static inline int __DRAW(td_args* args, const char* what, const char* field, #define FIELD_INF(field) field "_inf" #define FIELD_NEGINF(field) field "_neginf" #define FIELD_BITS(field) field "_bits" +#define FIELD_BYTES(field) field "_bytes" #define FIELD_CELSIUS(field) field "_c" #define FIELD_FAHRENHEIT(field) field "_f" @@ -338,6 +341,44 @@ static inline int __DRAW(td_args* args, const char* what, const char* field, ); \ } while (0) +#define COMPUTE_BYTES_FROM_SECTORS(args, field, object) \ + do { \ + COMPUTE_CDEF(args, FIELD "=" FIELD ",512,*", \ + FIELD_AND_OBJECT(FIELD_BYTES(field), object), \ + FIELD_AND_OBJECT(field, object) \ + ); \ + VALUE_ALL(args, FIELD_BYTES(field), object); \ + } while (0) + +/* + This draws an I/O graph +*/ +#define DRAW_IO_SECTORS(args, object, read_sectors, write_sectors) \ + do { \ + COMPUTE_BYTES_FROM_SECTORS(args, read_sectors, object); \ + COMPUTE_BYTES_FROM_SECTORS(args, write_sectors, object); \ + DRAW_IO_BYTES(args, object, \ + FIELD_BYTES(read_sectors), FIELD_BYTES(write_sectors)); \ + } while (0) + +#define DRAW_IO_BYTES(args, object, read_bytes, write_bytes) \ + do { \ + DRAW_IO_BYTES_READ(args, object, read_bytes); \ + DRAW_IO_BYTES_WRITTEN(args, object, write_bytes); \ + } while (0) + +#define DRAW_IO_BYTES_READ(args, object, read_bytes) \ + __DRAW_IO_BYTES(args, object, read_bytes, COLOR_RX, "%s", _("Bytes Read")) + +#define DRAW_IO_BYTES_WRITTEN(args, object, read_bytes) \ + __DRAW_IO_BYTES(args, object, read_bytes, COLOR_TX, "%s", _("Bytes Written")) + +#define __DRAW_IO_BYTES(args, object, bytes, color, label, ...) \ + do { \ + DRAW_AREA_WITH_LABEL(args, bytes, object, color, 0, label, __VA_ARGS__); \ + PRINT_CAMM(args, bytes, object, BYTES); \ + } while (0) + /* This draws a bandwidth graph */