]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: sample: add new sample fetch functions reporting current CPU usage
authorWilly Tarreau <w@1wt.eu>
Tue, 14 Apr 2026 15:42:36 +0000 (17:42 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 14 Apr 2026 15:47:18 +0000 (17:47 +0200)
Some features can automatically turn on or off depending on CPU usage,
but it's not easy to measure it. Let's provide 3 new sample fetch functions
reporting the CPU usage as measured inside haproxy during the previous
polling loop, and reported in "idle" stats header / "show info", or used
by tune.glitches.kill.cpu-usage, or maxcompcpuusage:

  - cpu_usage_thr: CPU usage between 0 and 100 of the current thread, used
    by functions above
  - cpu_usage_grp: CPU usage between 0 and 100, averaged over all threads of
    the same group as the current one.
  - cpu_usage_proc: CPU usage between 0 and 100, averaged over all threads
    of the current process

Note that the value will fluctuate since it only covers a few tens to
hundreds of requests of the last polling loop, but it reports what is
being used to take decisions.

It could also be used to disable some non-essential debugging/processing
under too high loads for example.

doc/configuration.txt
src/sample.c

index 43b6e6b5f01e0fcea316e0f65b196dc081297e41..b6277842359b086b208c64191c4aaecc5d8de7f4 100644 (file)
@@ -23672,6 +23672,30 @@ cpu_ns_tot : integer
   high cpu_calls count, for example when processing many HTTP chunks, and for
   this reason it is often preferred to log cpu_ns_avg instead.
 
+cpu_usage_grp : integer
+  Returns the measured CPU usage over the last polling loop, between 0 and 100,
+  averaged over all threads of the current thread group. This can be used for
+  troubleshooting and for logging. The measure is extremely volatile but will
+  remain accurate for sustained loads as each thread measures it over a few
+  tens to hundreds of requests.
+
+cpu_usage_proc : integer
+  Returns the measured CPU usage over the last polling loop, between 0 and 100,
+  averaged over all running threads. This can be used for troubleshooting and
+  for logging. The measure is extremely volatile but will remain accurate for
+  sustained loads as each thread measures it over a few tens to hundreds of
+  requests. This is 100 minus the value reported in the idle ratio in the stats
+  page and in "show info".
+
+cpu_usage_thr : integer
+  Returns the measured CPU usage over the last polling loop, between 0 and 100,
+  for the calling thread. This can be used for troubleshooting and for logging.
+  The measure is extremely volatile but will remain accurate for sustained
+  loads as it is measured over a few tens to hundreds of requests. This is the
+  same value as used to decide to enable connection killing on too high
+  glitches, or to disable compression. See also "tune.glitches.kill.cpu-usage"
+  and "maxcomcpuusage".
+
 date([<offset>[,<unit>]]) : integer
   Returns the current date as the epoch (number of seconds since 01/01/1970).
 
index 370c0156a1ca2891044e0c4ec5b945b2e1bfd3a8..a1e1c74aef6a25733f91e728fbb5e199d2530f6f 100644 (file)
@@ -5089,6 +5089,43 @@ smp_fetch_tgroup(const struct arg *args, struct sample *smp, const char *kw, voi
        return 1;
 }
 
+/* returns the last known CPU usage of the current thread */
+static int
+smp_fetch_cpu_usage_thr(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 100 - th_ctx->idle_pct;
+       return 1;
+}
+
+/* returns the last known CPU usage of the current thread group */
+static int
+smp_fetch_cpu_usage_grp(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       uint thr, tot = 0;
+
+       for (thr = 0; thr < ha_tgroup_info[tgid - 1].count; thr++)
+               tot += 100 - ha_thread_ctx[ha_tgroup_info[tgid - 1].base + thr].idle_pct;
+
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = (tot + thr / 2) / thr;
+       return 1;
+}
+
+/* returns the last known CPU usage of the whole process */
+static int
+smp_fetch_cpu_usage_proc(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       int thr, tot = 0;
+
+       for (thr = 0; thr < global.nbthread; thr++)
+               tot += 100 - ha_thread_ctx[thr].idle_pct;
+
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = (tot + thr / 2) / thr;
+       return 1;
+}
+
 /* generate a random 32-bit integer for whatever purpose, with an optional
  * range specified in argument.
  */
@@ -5677,6 +5714,9 @@ static struct sample_fetch_kw_list smp_kws = {ILH, {
        { "cpu_calls",    smp_fetch_cpu_calls,  0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
        { "cpu_ns_avg",   smp_fetch_cpu_ns_avg, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
        { "cpu_ns_tot",   smp_fetch_cpu_ns_tot, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
+       { "cpu_usage_grp", smp_fetch_cpu_usage_grp,  0,  NULL, SMP_T_SINT, SMP_USE_INTRN },
+       { "cpu_usage_proc",smp_fetch_cpu_usage_proc, 0,  NULL, SMP_T_SINT, SMP_USE_INTRN },
+       { "cpu_usage_thr", smp_fetch_cpu_usage_thr,  0,  NULL, SMP_T_SINT, SMP_USE_INTRN },
        { "lat_ns_avg",   smp_fetch_lat_ns_avg, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
        { "lat_ns_tot",   smp_fetch_lat_ns_tot, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },