From: Michael Tremer Date: Sun, 5 Oct 2025 14:03:24 +0000 (+0000) Subject: sources: Add softirqs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a578ebc50d24977888f73a112ecaf6a7581e1ae;p=telemetry.git sources: Add softirqs Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index c581e96..dbd32b5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -148,12 +148,15 @@ dist_collectyd_SOURCES = \ src/daemon/sources/pressure-memory.h \ src/daemon/sources/processor.c \ src/daemon/sources/processor.h \ + src/daemon/sources/softirq.c \ + src/daemon/sources/softirq.h \ src/daemon/sources/test-error.c \ src/daemon/sources/test-error.h \ src/daemon/sources/test-flapping.c \ src/daemon/sources/test-flapping.h \ src/daemon/sources/test-stall.c \ src/daemon/sources/test-stall.h \ + src/daemon/string.h \ src/daemon/time.h \ src/daemon/util.c \ src/daemon/util.h diff --git a/src/daemon/proc.c b/src/daemon/proc.c index 9fad49a..97fa1da 100644 --- a/src/daemon/proc.c +++ b/src/daemon/proc.c @@ -26,6 +26,7 @@ #include #include "proc.h" +#include "string.h" int collecty_proc_read_meminfo(collecty_ctx* ctx, collecty_proc_meminfo* meminfo) { unsigned long v; @@ -252,3 +253,96 @@ ERROR: return r; } + +int collecty_proc_read_softirq(collecty_ctx* ctx, + collecty_proc_softirq_callback callback, void* data) { + char* line = NULL; + size_t length = 0; + FILE* f = NULL; + char* e = NULL; + char* p = NULL; + char* t = NULL; + char key[16]; + uint64_t v; + int r; + + // Open /proc/softirqs + f = fopen("/proc/softirqs", "r"); + if (!f) { + r = -errno; + goto ERROR; + } + + // Count the lines + unsigned int lineno = 0; + + // Read all lines + for (;;) { + // Read the next line + r = getline(&line, &length, f); + if (r < 0) + break; + + // Skip the first line + if (!lineno++) + continue; + + // Fetch the key + t = strtok_r(line, ":", &p); + if (!t) { + r = -errno; + goto ERROR; + } + + // Store the key + r = snprintf(key, sizeof(key), "%s", t); + if (r < 0) { + r = -errno; + goto ERROR; + } + + // Strip any whitespace + collecty_string_strip(key); + + // Reset the value + v = 0; + + // Add up all values + for (;;) { + // Fetch the next token + t = strtok_r(NULL, " ", &p); + if (!t) + break; + + // Parse the token + v += strtoul(t, &e, 10); + + // Check if could parse the value + switch (*e) { + case '\0': + case '\n': + break; + + default: + r = -EINVAL; + goto ERROR; + } + } + + // Call the callback + r = callback(ctx, key, v, data); + if (r < 0) + goto ERROR; + } + + // Success + r = 0; + +ERROR: + if (line) + free(line); + if (f) + fclose(f); + + return r; +} diff --git a/src/daemon/proc.h b/src/daemon/proc.h index 2dfb62c..0630b45 100644 --- a/src/daemon/proc.h +++ b/src/daemon/proc.h @@ -66,6 +66,14 @@ typedef struct collecty_pressure_stats { } collecty_pressure_stats; int collecty_proc_read_pressure(collecty_ctx* ctx, - const char* what, collecty_pressure_stats* stats); + const char* what, collecty_pressure_stats* stats); + +// Soft IRQ + +typedef int (*collecty_proc_softirq_callback) + (collecty_ctx* ctx, const char* key, uint64_t value, void* data); + +int collecty_proc_read_softirq(collecty_ctx* ctx, + collecty_proc_softirq_callback callback, void* data); #endif /* COLLECTY_PROC_H */ diff --git a/src/daemon/sources.c b/src/daemon/sources.c index 423cda2..764bb13 100644 --- a/src/daemon/sources.c +++ b/src/daemon/sources.c @@ -38,6 +38,7 @@ #include "sources/pressure-io.h" #include "sources/pressure-memory.h" #include "sources/processor.h" +#include "sources/softirq.h" #include "sources/test-error.h" #include "sources/test-flapping.h" #include "sources/test-stall.h" @@ -54,6 +55,7 @@ static const collecty_source_impl* source_impls[] = { &pressure_io_source, &pressure_memory_source, &processor_source, + &softirq_source, // Tests &test_error_source, diff --git a/src/daemon/sources/softirq.c b/src/daemon/sources/softirq.c new file mode 100644 index 0000000..55cdff5 --- /dev/null +++ b/src/daemon/sources/softirq.c @@ -0,0 +1,48 @@ +/*############################################################################# +# # +# 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 "../ctx.h" +#include "../proc.h" +#include "../source.h" +#include "softirq.h" + +static int callback(collecty_ctx* ctx, const char* key, uint64_t value, void* data) { + collecty_source* source = data; + + // Submit the data + return collecty_source_submit(source, key, "%lu", value); +} + +static int softirq_collect(collecty_ctx* ctx, collecty_source* source) { + return collecty_proc_read_softirq(ctx, callback, source); +} + +const collecty_source_impl softirq_source = { + .name = "softirq", + + // RRD Data Sources + .rrd_dss = { + { "interrupts", "DERIVE", 0, -1, }, + { NULL }, + }, + + // Methods + .collect = softirq_collect, +}; diff --git a/src/daemon/sources/softirq.h b/src/daemon/sources/softirq.h new file mode 100644 index 0000000..ac1e586 --- /dev/null +++ b/src/daemon/sources/softirq.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_SOURCE_SOFTIRQS_H +#define COLLECTY_SOURCE_SOFTIRQS_H + +#include "../source.h" + +extern const collecty_source_impl softirq_source; + +#endif /* COLLECTY_SOURCE_SOFTIRQS_H */ diff --git a/src/daemon/string.h b/src/daemon/string.h new file mode 100644 index 0000000..2d05fa4 --- /dev/null +++ b/src/daemon/string.h @@ -0,0 +1,59 @@ +/*############################################################################# +# # +# 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_STRING_H +#define COLLECTY_STRING_H + +#include +#include + +inline void collecty_string_lstrip(char* s) { + if (!s) + return; + + size_t l = strlen(s); + if (!l) + return; + + // Remove leading space + while (isspace(s[0])) + memmove(s, s + 1, l--); +} + +inline void collecty_string_rstrip(char* s) { + if (!s) + return; + + size_t l = strlen(s); + + // Remove trailing space + while (l > 0 && isspace(s[l - 1])) + s[l-- - 1] = '\0'; +} + +inline void collecty_string_strip(char* s) { + // Strip everything on the left side + collecty_string_lstrip(s); + + // Strip everything on the right side + collecty_string_rstrip(s); +} + +#endif /* COLLECTY_STRING_H */