]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: promex/resolvers: Dump resolvers metrics via a promex module
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 31 Jan 2024 09:34:14 +0000 (10:34 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 2 Feb 2024 08:11:34 +0000 (09:11 +0100)
Just like for stick-tables, this patch adds a promex module to dump
resolvers metrics. It adds the "resolver" scope and for now, it dumps
folloowing metrics:

  * haproxy_resolver_sent
  * haproxy_resolver_send_error
  * haproxy_resolver_valid
  * haproxy_resolver_update
  * haproxy_resolver_cname
  * haproxy_resolver_cname_error
  * haproxy_resolver_any_err
  * haproxy_resolver_nx
  * haproxy_resolver_timeout
  * haproxy_resolver_refused
  * haproxy_resolver_other
  * haproxy_resolver_invalid
  * haproxy_resolver_too_big
  * haproxy_resolver_outdated

addons/promex/README
src/resolvers.c

index 39e50c1e49cac96171a8fb426fa3d14c1152aa2c..c4fbc65160d4e9f5fb5589c70a231ef1cb0caefd 100644 (file)
@@ -374,3 +374,24 @@ listed below. Metrics from extra counters are not listed.
 | haproxy_sticktable_size                            |
 | haproxy_sticktable_used                            |
 +----------------------------------------------------+
+
+* Resolvers metrics
+
++----------------------------------------------------+
+|    Metric name                                     |
++----------------------------------------------------+
+| haproxy_resolver_sent                              |
+| haproxy_resolver_send_error                        |
+| haproxy_resolver_valid                             |
+| haproxy_resolver_update                            |
+| haproxy_resolver_cname                             |
+| haproxy_resolver_cname_error                       |
+| haproxy_resolver_any_err                           |
+| haproxy_resolver_nx                                |
+| haproxy_resolver_timeout                           |
+| haproxy_resolver_refused                           |
+| haproxy_resolver_other                             |
+| haproxy_resolver_invalid                           |
+| haproxy_resolver_too_big                           |
+| haproxy_resolver_outdated                          |
++----------------------------------------------------+
index 9657156c10c3d9eaad0e236b97fa8d39dcb1086d..43cac2f56595bf2c3377f8b1b90c106bb1b8e013 100644 (file)
 #include <haproxy/vars.h>
 #include <haproxy/xxhash.h>
 
+#if defined(USE_PROMEX)
+#include <promex/promex.h>
+#endif
+
 
 struct list sec_resolvers  = LIST_HEAD_INIT(sec_resolvers);
 struct list resolv_srvrq_list = LIST_HEAD_INIT(resolv_srvrq_list);
@@ -3898,3 +3902,70 @@ REGISTER_CONFIG_SECTION("resolvers",      cfg_parse_resolvers, cfg_post_parse_re
 REGISTER_POST_DEINIT(resolvers_deinit);
 REGISTER_CONFIG_POSTPARSER("dns runtime resolver", resolvers_finalize_config);
 REGISTER_PRE_CHECK(resolvers_create_default);
+
+#if defined(USE_PROMEX)
+
+static int rslv_promex_metric_info(unsigned int id, struct promex_metric *metric, struct ist *desc)
+{
+       if (id >= RSLV_STAT_END)
+               return -1;
+       if (id == RSLV_STAT_ID  || id == RSLV_STAT_PID)
+               return 0;
+
+       *metric = (struct promex_metric){ .n = ist(resolv_stats[id].name), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_MODULE_METRIC };
+       *desc = ist(resolv_stats[id].desc);
+       return 1;
+}
+
+static void *rslv_promex_start_ts(void *unused, unsigned int id)
+{
+       struct resolvers *resolver = LIST_NEXT(&sec_resolvers, struct resolvers *, list);
+
+       return LIST_NEXT(&resolver->nameservers, struct dns_nameserver *, list);
+}
+
+static void *rslv_promex_next_ts(void *unsued, void *metric_ctx, unsigned int id)
+{
+       struct dns_nameserver *ns = metric_ctx;
+       struct resolvers *resolver = ns->parent;
+
+       ns = LIST_NEXT(&ns->list, struct dns_nameserver *, list);
+       if (&ns->list == &resolver->nameservers) {
+               resolver = LIST_NEXT(&resolver->list, struct resolvers *, list);
+               ns = ((&resolver->list == &sec_resolvers)
+                     ? NULL
+                     : LIST_NEXT(&resolver->nameservers, struct dns_nameserver *, list));
+       }
+       return ns;
+}
+
+static int rslv_promex_fill_ts(void *unused, void *metric_ctx, unsigned int id, struct promex_label *labels, struct field *field)
+{
+       struct dns_nameserver *ns = metric_ctx;
+       struct resolvers *resolver = ns->parent;
+       struct field stats[RSLV_STAT_END];
+       int ret;
+
+       labels[0].name  = ist("resolver");
+       labels[0].value = ist2(resolver->id, strlen(resolver->id));
+       labels[1].name  = ist("nameserver");
+       labels[1].value = ist2(ns->id, strlen(ns->id));
+
+       ret = resolv_fill_stats(ns->counters, stats, &id);
+       if (ret == 1)
+               *field = stats[id];
+       return ret;
+}
+
+static struct promex_module promex_resolver_module = {
+       .name        = IST("resolver"),
+       .metric_info = rslv_promex_metric_info,
+       .start_ts    = rslv_promex_start_ts,
+       .next_ts     = rslv_promex_next_ts,
+       .fill_ts     = rslv_promex_fill_ts,
+       .nb_metrics  = RSLV_STAT_END,
+};
+
+INITCALL1(STG_REGISTER, promex_register_module, &promex_resolver_module);
+
+#endif