From: Michael Tremer Date: Wed, 8 Oct 2025 20:30:24 +0000 (+0000) Subject: graphs: Add a memory graph X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2d99a3014b60779fdbddd2b6b75f4ef728d52ce;p=collecty.git graphs: Add a memory graph Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index ec242a0..fd81a59 100644 --- a/Makefile.am +++ b/Makefile.am @@ -119,6 +119,8 @@ dist_collectyd_SOURCES = \ src/daemon/graphs/graph.h \ src/daemon/graphs/loadavg.c \ src/daemon/graphs/loadavg.h \ + src/daemon/graphs/memory.c \ + src/daemon/graphs/memory.h \ src/daemon/graphs/processor.c \ src/daemon/graphs/processor.h \ src/daemon/graphs/uptime.c \ diff --git a/src/daemon/graphs.c b/src/daemon/graphs.c index 3248bfe..5da9e1d 100644 --- a/src/daemon/graphs.c +++ b/src/daemon/graphs.c @@ -31,6 +31,7 @@ #include "graphs/conntrack.h" #include "graphs/contextswitches.h" #include "graphs/loadavg.h" +#include "graphs/memory.h" #include "graphs/processor.h" #include "graphs/uptime.h" @@ -39,6 +40,7 @@ static const collecty_graph_impl* graph_impls[] = { &conntrack_graph, &contextswitches_graph, &loadavg_graph, + &memory_graph, &processor_graph, &uptime_graph, NULL, diff --git a/src/daemon/graphs/graph.h b/src/daemon/graphs/graph.h index b6b8364..3437d93 100644 --- a/src/daemon/graphs/graph.h +++ b/src/daemon/graphs/graph.h @@ -49,11 +49,11 @@ // A column is exactly 16 characters wide #define COLUMN "%16s" -#define PERCENTAGE "%%13.2lf%%%%" +#define PERCENTAGE "%%13.2lf %%%%" #define INTEGER "%%16.0lf" #define LARGE_INTEGER "%%14.0lf %%s" #define FLOAT "%%14.2lf" -#define LARGE_FLOAT "%%12.2lf %%s" +#define LARGE_FLOAT "%%14.2lf %%s" // Macro to terminate a line #define EOL "\\j" @@ -151,6 +151,12 @@ VALUE_ALL(args, sum); \ } while (0) +#define COMPUTE_DIFFERENCE(args, difference, term, subtrahend) \ + do { \ + COMPUTE_CDEF(args, difference "=" term "," subtrahend ",-"); \ + VALUE_ALL(args, difference); \ + } while (0) + #define COMPUTE_DIVIDE(args, fraction, dividend, divisor) \ do { \ COMPUTE_CDEF(args, fraction "=" dividend "," TOSTRING(divisor) ",/"); \ diff --git a/src/daemon/graphs/memory.c b/src/daemon/graphs/memory.c new file mode 100644 index 0000000..28c38d2 --- /dev/null +++ b/src/daemon/graphs/memory.c @@ -0,0 +1,131 @@ +/*############################################################################# +# # +# collecty - A system statistics collection daemon for IPFire # +# Copyright (C) 2025 IPFire Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include + +#include "../string.h" +#include "graph.h" +#include "memory.h" + +// Set some colors +#define COLOR_MEM_TOTAL RED +#define COLOR_MEM_USED BLUE +#define COLOR_BUFFERS GREEN +#define COLOR_CACHED GREY +#define COLOR_SWAP_USED RED +#define COLOR_SWAP_TOTAL BLACK + +static int memory_title(collecty_ctx* ctx, collecty_graph* graph, + const char* object, char* title, size_t length) { + return __collecty_string_set(title, length, _("Memory Usage")); +} + +static int memory_vlabel(collecty_ctx* ctx, collecty_graph* graph, + const char* object, char* vlabel, size_t length) { + return __collecty_string_set(vlabel, length, _("Bytes")); +} + +static int memory_render(collecty_ctx* ctx, + collecty_graph* graph, collecty_args* args, const char* object) { + int r; + + // This requires the loadavg source + r = collecty_graph_require_source(graph, args, "memory", object); + if (r < 0) + return r; + + // Header + PRINT_HEADER4(args, _("Current"), _("Average"), _("Minimum"), _("Maximum")); + + // Compute the used memory + COMPUTE_DIFFERENCE(args, "mem_used", "mem_total", "mem_available"); + COMPUTE_PERCENTAGE(args, "mem_used", "mem_total"); + + // Compute the used swap + COMPUTE_DIFFERENCE(args, "swap_used", "swap_total", "swap_free"); + COMPUTE_PERCENTAGE(args, "swap_used", "swap_total"); + + // Draw the stacked background first + DRAW_AREA_BACKGROUND(args, "mem_used", COLOR_MEM_USED); + DRAW_AREA_BACKGROUND(args, "buffers", COLOR_BUFFERS, STACK); + DRAW_AREA_BACKGROUND(args, "cached", COLOR_CACHED, STACK SKIPSCALE); + + // Draw the area outlines afterwards + DRAW_AREA_OUTLINE_WITH_LABEL(args, "mem_used", COLOR_MEM_USED, _("Used Memory")); + PRINT_LARGE_FLOAT(args, FIELD_CURRENT("mem_used")); + PRINT_LARGE_FLOAT(args, FIELD_AVERAGE("mem_used")); + PRINT_LARGE_FLOAT(args, FIELD_MINIMUM("mem_used")); + PRINT_LARGE_FLOAT(args, FIELD_MAXIMUM("mem_used"), EOL); + + PRINT_EMPTY_LABEL(args); + PRINT_PERCENTAGE(args, FIELD_CURRENT(FIELD_PERCENT("mem_used"))); + PRINT_PERCENTAGE(args, FIELD_AVERAGE(FIELD_PERCENT("mem_used"))); + PRINT_PERCENTAGE(args, FIELD_MINIMUM(FIELD_PERCENT("mem_used"))); + PRINT_PERCENTAGE(args, FIELD_MAXIMUM(FIELD_PERCENT("mem_used")), EOL); + + DRAW_AREA_OUTLINE_WITH_LABEL(args, "buffers", COLOR_BUFFERS, _("Buffers"), STACK); + PRINT_LARGE_FLOAT(args, FIELD_CURRENT("buffers")); + PRINT_LARGE_FLOAT(args, FIELD_AVERAGE("buffers")); + PRINT_LARGE_FLOAT(args, FIELD_MINIMUM("buffers")); + PRINT_LARGE_FLOAT(args, FIELD_MAXIMUM("buffers"), EOL); + + DRAW_AREA_OUTLINE_WITH_LABEL(args, "cached", COLOR_CACHED, _("Cached"), STACK); + PRINT_LARGE_FLOAT(args, FIELD_CURRENT("cached")); + PRINT_LARGE_FLOAT(args, FIELD_AVERAGE("cached")); + PRINT_LARGE_FLOAT(args, FIELD_MINIMUM("cached")); + PRINT_LARGE_FLOAT(args, FIELD_MAXIMUM("cached"), EOL); + + // Draw the total memory as a line + DRAW_LINE1(args, "mem_total", COLOR_MEM_TOTAL, SKIPSCALE); + + // Make some space for swap + PRINT_EMPTY_LINE(args); + + DRAW_LINE1_WITH_LABEL(args, "swap_used", COLOR_SWAP_USED, _("Used Swap"), DASHES); + PRINT_LARGE_FLOAT(args, FIELD_CURRENT("swap_used")); + PRINT_LARGE_FLOAT(args, FIELD_AVERAGE("swap_used")); + PRINT_LARGE_FLOAT(args, FIELD_MINIMUM("swap_used")); + PRINT_LARGE_FLOAT(args, FIELD_MAXIMUM("swap_used"), EOL); + + PRINT_EMPTY_LABEL(args); + PRINT_PERCENTAGE(args, FIELD_CURRENT(FIELD_PERCENT("swap_used"))); + PRINT_PERCENTAGE(args, FIELD_AVERAGE(FIELD_PERCENT("swap_used"))); + PRINT_PERCENTAGE(args, FIELD_MINIMUM(FIELD_PERCENT("swap_used"))); + PRINT_PERCENTAGE(args, FIELD_MAXIMUM(FIELD_PERCENT("swap_used")), EOL); + + DRAW_LINE1_WITH_LABEL(args, "swap_total", COLOR_SWAP_TOTAL, _("Total Swap"), DASHES SKIPSCALE); + PRINT_LARGE_FLOAT(args, FIELD_CURRENT("swap_used")); + PRINT_NOTHING(args); + PRINT_NOTHING(args); + PRINT_NOTHING(args); + + return 0; +} + +const collecty_graph_impl memory_graph = { + .name = "Memory", + .render = memory_render, + .title = memory_title, + .vlabel = memory_vlabel, + + // Limits + .lower_limit = 0, + .upper_limit = LONG_MAX, +}; diff --git a/src/daemon/graphs/memory.h b/src/daemon/graphs/memory.h new file mode 100644 index 0000000..f5a0bb3 --- /dev/null +++ b/src/daemon/graphs/memory.h @@ -0,0 +1,28 @@ +/*############################################################################# +# # +# collecty - A system statistics collection daemon for IPFire # +# Copyright (C) 2025 IPFire Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef COLLECTY_GRAPH_MEMORY_H +#define COLLECTY_GRAPH_MEMORY_H + +#include "../graph.h" + +extern const collecty_graph_impl memory_graph; + +#endif /* COLLECTY_GRAPH_MEMORY_H */