Add misc.normalizeCPU

Signed-off-by: Dominik <dl6er@dl6er.de>
This commit is contained in:
Dominik
2025-10-06 10:01:28 +02:00
parent fcee389467
commit 649b3f51ca
6 changed files with 44 additions and 23 deletions

View File

@@ -551,6 +551,8 @@ components:
type: boolean
readOnly:
type: boolean
normalizeCPU:
type: boolean
check:
type: object
properties:
@@ -834,6 +836,7 @@ components:
dnsmasq_lines: [ ]
extraLogging: false
readOnly: false
normalizeCPU: false
check:
load: true
shmem: 90

View File

@@ -1416,6 +1416,12 @@ void initConfig(struct config *conf)
conf->misc.readOnly.d.b = false;
conf->misc.readOnly.c = validate_stub; // Only type-based checking
conf->misc.normalizeCPU.k = "misc.normalizeCPU";
conf->misc.normalizeCPU.h = "Should FTL normalize reported CPU usage?\n\n On multi-core systems, a high workload can lead to CPU usage numbers exceeding 100% (e.g., 200% on a quad-core system if two out of four cores are fully utilized). This may look alarming at first glance even though the system is not actually overloaded. Enabling this setting will divide the CPU usage by the number of cores, leading to more intuitive numbers (e.g., 50% for the same load on a quad-core system).\n Note that this setting only affects how CPU usage is *reported*, it does not change the actual CPU usage.";
conf->misc.normalizeCPU.t = CONF_BOOL;
conf->misc.normalizeCPU.d.b = true;
conf->misc.normalizeCPU.c = validate_stub; // Only type-based checking
// sub-struct misc.check
conf->misc.check.load.k = "misc.check.load";
conf->misc.check.load.h = "Pi-hole is very lightweight on resources. Nevertheless, this does not mean that you should run Pi-hole on a server that is otherwise extremely busy as queuing on the system can lead to unnecessary delays in DNS operation as the system becomes less and less usable as the system load increases because all resources are permanently in use. To account for this, FTL regularly checks the system load. To bring this to your attention, FTL warns about excessive load when the 15 minute system load average exceeds the number of cores.\n\n This check can be disabled with this setting.";

View File

@@ -316,6 +316,7 @@ struct config {
struct conf_item dnsmasq_lines;
struct conf_item extraLogging;
struct conf_item readOnly;
struct conf_item normalizeCPU;
struct {
struct conf_item load;
struct conf_item shmem;

View File

@@ -472,30 +472,27 @@ static float ftl_cpu_usage = 0.0f;
static float total_cpu_usage = 0.0f;
void calc_cpu_usage(const unsigned int interval)
{
// Get number of cores if we are normalizing CPU usage below
const unsigned int norm_factor = config.misc.normalizeCPU.v.b ? get_nprocs_conf() : 1;
// Get the current FTL CPU time
const double ftl_cpu_time = parse_proc_self_stat();
// Calculate the CPU usage in this interval
static double last_ftl_cpu_time = 0.0f;
ftl_cpu_usage = 100.0 * (ftl_cpu_time - last_ftl_cpu_time) / interval;
log_info("FTL CPU time since last call: %.2f seconds", ftl_cpu_time - last_ftl_cpu_time);
// Store the current time for the next call to this function
ftl_cpu_usage = 100.0 * (ftl_cpu_time - last_ftl_cpu_time) / interval / norm_factor;
last_ftl_cpu_time = ftl_cpu_time;
// Calculate the total CPU usage
static double last_cpu_time = 0.0f;
const double cpu_time = parse_proc_stat();
// Calculate the CPU usage since the last call to this function
total_cpu_usage = 100.0 * (cpu_time - last_cpu_time) / interval;
log_info("Total CPU time since last call: %.2f seconds", cpu_time - last_cpu_time);
static double last_cpu_time = 0.0f;
total_cpu_usage = 100.0 * (cpu_time - last_cpu_time) / interval / norm_factor;
last_cpu_time = cpu_time;
log_debug(DEBUG_EXTRA, "CPU usage in the last %u seconds: FTL %.4f%%, total %.4f%%",
interval, ftl_cpu_usage, total_cpu_usage);
log_debug(DEBUG_EXTRA, "CPU usage in the last %u seconds: FTL %.4f%%, total %.4f%% (normalized by factor %ux)",
interval, ftl_cpu_usage, total_cpu_usage, norm_factor);
}
float __attribute__((pure)) get_ftl_cpu_percentage(void)

View File

@@ -320,6 +320,7 @@ double parse_proc_stat(void)
// Read the file until we find the first line starting with "cpu "
char line[256];
bool found = false;
while(fgets(line, sizeof(line), statfile))
{
if(strncmp(line, "cpu ", 4) == 0)
@@ -331,12 +332,12 @@ double parse_proc_stat(void)
fclose(statfile);
return -1.0;
}
found = true;
break;
}
}
if (feof(statfile)) {
if(!found) {
log_warn("No CPU line found in /proc/stat");
fclose(statfile);
return -1.0;
@@ -370,13 +371,12 @@ double parse_proc_self_stat(void)
// Read utime and stime
unsigned long utime = 0, stime = 0;
if(fscanf(file, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu",
&utime, &stime) != 2)
{
const bool parsed = fscanf(file, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu", &utime, &stime) == 2;
fclose(file);
// If we could not parse the file, return -1.0
if(!parsed)
return -1.0;
}
fclose(file);
// Convert clock ticks to seconds
const long ticks = sysconf(_SC_CLK_TCK);

View File

@@ -1,7 +1,7 @@
# Pi-hole configuration file (v6.2.3-274-g68959ed0) on branch new/dns_domainLocal
# Pi-hole configuration file (v6.2.3-301-gfcee3894-dirty) on branch tweak/api_info_system_ftl
# Encoding: UTF-8
# This file is managed by pihole-FTL
# Last updated on 2025-09-28 20:09:54 UTC
# Last updated on 2025-10-06 08:00:17 UTC
[dns]
# Upstream DNS Servers to be used by Pi-hole. If this is not set, Pi-hole will not
@@ -1399,6 +1399,20 @@
# true or false
readOnly = false
# Should FTL normalize reported CPU usage?
#
# On multi-core systems, a high workload can lead to CPU usage numbers exceeding 100%
# (e.g., 200% on a quad-core system if two out of four cores are fully utilized). This
# may look alarming at first glance even though the system is not actually overloaded.
# Enabling this setting will divide the CPU usage by the number of cores, leading to
# more intuitive numbers (e.g., 50% for the same load on a quad-core system).
# Note that this setting only affects how CPU usage is *reported*, it does not change
# the actual CPU usage.
#
# Allowed values are:
# true or false
normalizeCPU = true
[misc.check]
# Pi-hole is very lightweight on resources. Nevertheless, this does not mean that you
# should run Pi-hole on a server that is otherwise extremely busy as queuing on the
@@ -1648,7 +1662,7 @@
all = true ### CHANGED, default = false
# Configuration statistics:
# 159 total entries out of which 106 entries are default
# 160 total entries out of which 107 entries are default
# --> 53 entries are modified
# 3 entries are forced through environment:
# - misc.nice