]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tasks/stats: report the number of niced tasks in "show info"
authorWilly Tarreau <w@1wt.eu>
Wed, 6 Sep 2023 09:33:53 +0000 (11:33 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 6 Sep 2023 15:44:44 +0000 (17:44 +0200)
We currently know the number of tasks in the run queue that are niced,
and we don't expose it. It's too bad because it can give a hint about
what share of the load is relevant. For example if one runs a Lua
script that was purposely reniced, or if a stats page or the CLI is
hammered with slow operations, seeing them appear there can help
identify what part of the load is not caused by the traffic, and
improve monitoring systems or autoscalers.

include/haproxy/stats-t.h
include/haproxy/task.h
src/stats.c

index ca2b78d0365426eccead83ef6d52c901e4d36e68..b6feabd158cca9d5fd85bab0f1c10b1a6a9abcdc 100644 (file)
@@ -346,6 +346,7 @@ enum info_field {
        INF_WARNINGS,
        INF_MAXCONN_REACHED,
        INF_BOOTTIME_MS,
+       INF_NICED_TASKS,
 
        /* must always be the last one */
        INF_TOTAL_FIELDS
index 390db0f8c720a7984fcf5bf448fec6eae92408ea..1f544be1704e15343fa6c86f3bb88816f46eb294 100644 (file)
@@ -155,6 +155,20 @@ static inline int total_allocated_tasks()
        return ret;
 }
 
+/* returns the number of running niced tasks+tasklets on the whole process.
+ * Note that this *is* racy since a task may move from the global to a local
+ * queue for example and be counted twice. This is only for statistics
+ * reporting.
+ */
+static inline int total_niced_running_tasks()
+{
+       int tgrp, ret = 0;
+
+       for (tgrp = 0; tgrp < global.nbtgroups; tgrp++)
+               ret += _HA_ATOMIC_LOAD(&ha_tgroup_ctx[tgrp].niced_tasks);
+       return ret;
+}
+
 /* return 0 if task is in run queue, otherwise non-zero */
 static inline int task_in_rq(struct task *t)
 {
index 1d071e2c132d27ab848b2ef086d4431e20418ad7..acd3e7e16f962a4d369604b65724b598d1ea797d 100644 (file)
@@ -159,6 +159,7 @@ const struct name_desc info_fields[INF_TOTAL_FIELDS] = {
        [INF_WARNINGS]                       = { .name = "TotalWarnings",               .desc = "Total warnings issued" },
        [INF_MAXCONN_REACHED]                = { .name = "MaxconnReached",              .desc = "Number of times an accepted connection resulted in Maxconn being reached" },
        [INF_BOOTTIME_MS]                    = { .name = "BootTime_ms",                 .desc = "How long ago it took to parse and process the config before being ready (milliseconds)" },
+       [INF_NICED_TASKS]                    = { .name = "Niced_tasks",                 .desc = "Total number of active tasks+tasklets in the current worker process (Run_queue) that are niced" },
 };
 
 const struct name_desc stat_fields[ST_F_TOTAL_FIELDS] = {
@@ -3613,7 +3614,7 @@ static void stats_dump_html_info(struct stconn *sc, struct uri_auth *uri)
                      "<b>system limits:</b> memmax = %s%s; ulimit-n = %d<br>\n"
                      "<b>maxsock = </b> %d; <b>maxconn = </b> %d; <b>reached = </b> %llu; <b>maxpipes = </b> %d<br>\n"
                      "current conns = %d; current pipes = %d/%d; conn rate = %d/sec; bit rate = %.3f %cbps<br>\n"
-                     "Running tasks: %d/%d; idle = %d %%<br>\n"
+                     "Running tasks: %d/%d (%d niced); idle = %d %%<br>\n"
                      "</td><td align=\"center\" nowrap>\n"
                      "<table class=\"lgd\"><tr>\n"
                      "<td class=\"active_up\">&nbsp;</td><td class=\"noborder\">active UP </td>"
@@ -3653,8 +3654,7 @@ static void stats_dump_html_info(struct stconn *sc, struct uri_auth *uri)
                      actconn, pipes_used, pipes_used+pipes_free, read_freq_ctr(&global.conn_per_sec),
                      bps >= 1000000000UL ? (bps / 1000000000.0) : bps >= 1000000UL ? (bps / 1000000.0) : (bps / 1000.0),
                      bps >= 1000000000UL ? 'G' : bps >= 1000000UL ? 'M' : 'k',
-                     total_run_queues(), total_allocated_tasks(), clock_report_idle()
-                     );
+                     total_run_queues(), total_allocated_tasks(), total_niced_running_tasks(), clock_report_idle());
 
        /* scope_txt = search query, ctx->scope_len is always <= STAT_SCOPE_TXT_MAXLEN */
        memcpy(scope_txt, scope_ptr, ctx->scope_len);
@@ -4754,6 +4754,7 @@ int stats_fill_info(struct field *info, int len, uint flags)
        info[INF_WARNINGS]                       = mkf_u32(FN_COUNTER, HA_ATOMIC_LOAD(&tot_warnings));
        info[INF_MAXCONN_REACHED]                = mkf_u32(FN_COUNTER, HA_ATOMIC_LOAD(&maxconn_reached));
        info[INF_BOOTTIME_MS]                    = mkf_u32(FN_DURATION, boot);
+       info[INF_NICED_TASKS]                    = mkf_u32(0, total_niced_running_tasks());
 
        return 1;
 }