From 234ad49ef120703c5404bcfeca3a8d6ca940afd8 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 3 Oct 2025 16:23:15 +0000 Subject: [PATCH] sources: Add source for processor usage Signed-off-by: Michael Tremer --- Makefile.am | 4 ++ src/daemon/proc.c | 119 +++++++++++++++++++++++++++++++++ src/daemon/proc.h | 31 +++++++++ src/daemon/sources.c | 2 + src/daemon/sources/processor.c | 65 ++++++++++++++++++ src/daemon/sources/processor.h | 28 ++++++++ 6 files changed, 249 insertions(+) create mode 100644 src/daemon/proc.c create mode 100644 src/daemon/proc.h create mode 100644 src/daemon/sources/processor.c create mode 100644 src/daemon/sources/processor.h diff --git a/Makefile.am b/Makefile.am index 6a0c586..68e7f2c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -116,6 +116,8 @@ dist_collectyd_SOURCES = \ src/daemon/logging.c \ src/daemon/logging.h \ src/daemon/main.c \ + src/daemon/proc.c \ + src/daemon/proc.h \ src/daemon/queue.c \ src/daemon/queue.h \ src/daemon/source.c \ @@ -128,6 +130,8 @@ dist_collectyd_SOURCES = \ src/daemon/sources/contextswitches.h \ src/daemon/sources/loadavg.c \ src/daemon/sources/loadavg.h \ + src/daemon/sources/processor.c \ + src/daemon/sources/processor.h \ src/daemon/util.c \ src/daemon/util.h diff --git a/src/daemon/proc.c b/src/daemon/proc.c new file mode 100644 index 0000000..cf27c0e --- /dev/null +++ b/src/daemon/proc.c @@ -0,0 +1,119 @@ +/*############################################################################# +# # +# 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 +#include +#include +#include +#include + +#include "proc.h" + +static int collecty_proc_read_stat_line(collecty_ctx* ctx, + const char* tag, char* line, unsigned long* fields, size_t max_fields) { + char* p = NULL; + char* e = NULL; + char* t = NULL; + + // Count the number of fields parsed + unsigned int field = 0; + + // The parsed values + unsigned long value = 0; + + // Split the line + t = strtok_r(line, " ", &p); + + // If the first token does not match the tag, we skip the line + if (strcmp(tag, t) != 0) + return 0; + + // Read all tokens + for (;;) { + // Find the next token + t = strtok_r(NULL, " ", &p); + if (!t) + break; + + // Parse the token + value = strtoul(t, &e, 10); + + // If there was a remainder that could not be parsed we must abort + switch (*e) { + case '\0': + case '\n': + break; + + default: + return -EBADMSG; + } + + // Store the value + fields[field++] = value; + + // Abort if we have read all tokens we can + if (field >= max_fields) + break; + } + + // Return the number of parsed fields + return field; +} + +int collecty_proc_read_stat(collecty_ctx* ctx, + const char* tag, unsigned long* fields, size_t max_fields) { + char* line = NULL; + size_t length = 0; + FILE* f = NULL; + int r; + + // Check inputs + if (!tag || !fields || !max_fields) + return -EINVAL; + + // Open /proc/stat + f = fopen("/proc/stat", "r"); + if (!f) { + ERROR(ctx, "Failed to open /proc/stat: %m\n"); + r = -errno; + goto ERROR; + } + + // Walk through all lines + for (;;) { + r = getline(&line, &length, f); + if (r < 0) + break; + + // Process the line + r = collecty_proc_read_stat_line(ctx, tag, line, fields, max_fields); + if (r) + break; + } + +ERROR: + if (line) + free(line); + if (f) + fclose(f); + + return r; +} diff --git a/src/daemon/proc.h b/src/daemon/proc.h new file mode 100644 index 0000000..8d08f87 --- /dev/null +++ b/src/daemon/proc.h @@ -0,0 +1,31 @@ +/*############################################################################# +# # +# 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_PROC_H +#define COLLECTY_PROC_H + +#include + +#include "ctx.h" + +int collecty_proc_read_stat(collecty_ctx* ctx, + const char* tag, unsigned long* fields, size_t max_fields); + +#endif /* COLLECTY_PROC_H */ diff --git a/src/daemon/sources.c b/src/daemon/sources.c index 8e5287c..4f6631c 100644 --- a/src/daemon/sources.c +++ b/src/daemon/sources.c @@ -31,12 +31,14 @@ #include "sources/conntrack.h" #include "sources/contextswitches.h" #include "sources/loadavg.h" +#include "sources/processor.h" // Register all sources static const collecty_source_impl* source_impls[] = { &conntrack_source, &contextswitches_source, &loadavg_source, + &processor_source, NULL, }; diff --git a/src/daemon/sources/processor.c b/src/daemon/sources/processor.c new file mode 100644 index 0000000..1617870 --- /dev/null +++ b/src/daemon/sources/processor.c @@ -0,0 +1,65 @@ +/*############################################################################# +# # +# 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 "processor.h" + +// /proc/stat currently carries 10 fields +#define MAX_FIELDS 10 + +static int processor_collect(collecty_ctx* ctx, collecty_source* source) { + unsigned long usage[MAX_FIELDS] = {}; + int r; + + // Read all values from /proc/stat + r = collecty_proc_read_stat(ctx, "cpu", usage, MAX_FIELDS); + if (r < MAX_FIELDS) + return r; + + // Submit the values + return collecty_source_submit(source, NULL, + "%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu", + usage[0], usage[1], usage[2], usage[3], usage[4], + usage[5], usage[6], usage[7], usage[8], usage[9]); +} + +const collecty_source_impl processor_source = { + .name = "processor", + + // RRD Data Sources + .rrd_dss = { + { "user", "DERIVE", 0, -1, }, + { "nice", "DERIVE", 0, -1, }, + { "sys", "DERIVE", 0, -1, }, + { "idle", "DERIVE", 0, -1, }, + { "wait", "DERIVE", 0, -1, }, + { "irq", "DERIVE", 0, -1, }, + { "softirq", "DERIVE", 0, -1, }, + { "steal", "DERIVE", 0, -1, }, + { "guest", "DERIVE", 0, -1, }, + { "guest_nice", "DERIVE", 0, -1, }, + { NULL }, + }, + + // Methods + .collect = processor_collect, +}; diff --git a/src/daemon/sources/processor.h b/src/daemon/sources/processor.h new file mode 100644 index 0000000..90e7fbb --- /dev/null +++ b/src/daemon/sources/processor.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_PROCESSOR_H +#define COLLECTY_SOURCE_PROCESSOR_H + +#include "../source.h" + +extern const collecty_source_impl processor_source; + +#endif /* COLLECTY_SOURCE_PROCESSOR_H */ -- 2.47.3