ST_I_INF_MAX
};
+/* Represent an exposed statistic. */
+struct stat_col {
+ const char *name; /* short name, used notably in CSV headers */
+ const char *desc; /* user-friendly description */
+
+ uint32_t type; /* combination of field_nature and field_format */
+ uint8_t cap; /* mask of stats_domain_px_cap to restrain metrics to an object types subset */
+
+ /* used only for generic metrics */
+ struct {
+ int offset[2]; /* offset in counters */
+ } metric;
+};
+
/* Stats columns for CSV output. For any column added here, please add the text
* representation in the metrics_px array. Please only append at the end,
/* functor used to generate the stats module using counters provided through data parameter */
int (*fill_stats)(void *data, struct field *, unsigned int *);
- struct name_desc *stats; /* name/description of stats provided by the module */
+ struct stat_col *stats; /* statistics provided by the module */
void *counters; /* initial values of allocated counters */
size_t counters_off[COUNTERS_OFF_END]; /* list of offsets of allocated counters in various objects */
size_t stats_count; /* count of stats provided */
#include <haproxy/uri_auth-t.h>
#include <haproxy/version.h>
+/* Define a new metric for both frontend and backend sides. */
+#define ME_NEW_PX(name_f, nature, format, offset_f, cap_f, desc_f) \
+ { .name = (name_f), .desc = (desc_f), .type = (nature)|(format), \
+ .metric.offset[0] = offsetof(struct fe_counters, offset_f), \
+ .metric.offset[1] = offsetof(struct be_counters, offset_f), \
+ .cap = (cap_f), \
+ }
+
+/* Define a new metric for frontend side only. */
+#define ME_NEW_FE(name_f, nature, format, offset_f, cap_f, desc_f) \
+ { .name = (name_f), .desc = (desc_f), .type = (nature)|(format), \
+ .metric.offset[0] = offsetof(struct fe_counters, offset_f), \
+ .cap = (cap_f), \
+ }
+
+/* Define a new metric for backend side only. */
+#define ME_NEW_BE(name_f, nature, format, offset_f, cap_f, desc_f) \
+ { .name = (name_f), .desc = (desc_f), .type = (nature)|(format), \
+ .metric.offset[1] = offsetof(struct be_counters, offset_f), \
+ .cap = (cap_f), \
+ }
+
+/* Convert stat_col <col> to old-style <name> as name_desc. */
+static void stcol2ndesc(struct name_desc *name, const struct stat_col *col)
+{
+ name->name = col->name;
+ name->desc = col->desc;
+}
+
/* status codes available for the stats admin page (strictly 4 chars length) */
const char *stat_status_codes[STAT_STATUS_SIZE] = {
/* one line of info */
THREAD_LOCAL struct field stat_line_info[ST_I_INF_MAX];
-const struct name_desc stat_cols_px[ST_I_PX_MAX] = {
+const struct stat_col stat_cols_px[ST_I_PX_MAX] = {
[ST_I_PX_PXNAME] = { .name = "pxname", .desc = "Proxy name" },
[ST_I_PX_SVNAME] = { .name = "svname", .desc = "Server name" },
[ST_I_PX_QCUR] = { .name = "qcur", .desc = "Number of current queued connections" },
static int allocate_stats_px_postcheck(void)
{
struct stats_module *mod;
- size_t i = ST_I_PX_MAX;
+ size_t i = ST_I_PX_MAX, offset;
int err_code = 0;
struct proxy *px;
return err_code;
}
- memcpy(stat_cols[STATS_DOMAIN_PROXY], stat_cols_px,
- ST_I_PX_MAX * sizeof(struct name_desc));
+ for (i = 0; i < ST_I_PX_MAX; ++i)
+ stcol2ndesc(&stat_cols[STATS_DOMAIN_PROXY][i], &stat_cols_px[i]);
list_for_each_entry(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
- memcpy(stat_cols[STATS_DOMAIN_PROXY] + i,
- mod->stats,
- mod->stats_count * sizeof(struct name_desc));
- i += mod->stats_count;
+ for (offset = i, i = 0; i < mod->stats_count; ++i) {
+ stcol2ndesc(&stat_cols[STATS_DOMAIN_PROXY][offset + i],
+ &mod->stats[i]);
+ }
+ i += offset;
}
for (px = proxies_list; px; px = px->next) {
static int allocate_stats_rslv_postcheck(void)
{
struct stats_module *mod;
- size_t i = 0;
+ size_t i = 0, offset;
int err_code = 0;
stat_cols[STATS_DOMAIN_RESOLVERS] = malloc(stat_cols_len[STATS_DOMAIN_RESOLVERS] * sizeof(struct name_desc));
}
list_for_each_entry(mod, &stats_module_list[STATS_DOMAIN_RESOLVERS], list) {
- memcpy(stat_cols[STATS_DOMAIN_RESOLVERS] + i,
- mod->stats,
- mod->stats_count * sizeof(struct name_desc));
- i += mod->stats_count;
+ for (offset = i, i = 0; i < mod->stats_count; ++i) {
+ stcol2ndesc(&stat_cols[STATS_DOMAIN_RESOLVERS][offset + i],
+ &mod->stats[i]);
+ }
+ i += offset;
}
if (!resolv_allocate_counters(&stats_module_list[STATS_DOMAIN_RESOLVERS])) {