MEDIUM: stats: define an API to register stat modules

A stat module can be registered to quickly add new statistics on
haproxy. It must be attached to one of the available stats domain. The
register must be done using INITCALL on STG_REGISTER.

The stat module has a name which should be unique for each new module in
a domain. It also contains a statistics list with their name/desc and a
pointer to a function used to fill the stats from the module counters.

The module also provides the initial counters values used on
automatically allocated counters. The offset for these counters
are stored in the module structure.
This commit is contained in:
Amaury Denoyelle 2020-10-05 11:49:40 +02:00 committed by Christopher Faulet
parent 50660a894d
commit 58d395e0d6
3 changed files with 40 additions and 0 deletions

View File

@ -453,6 +453,32 @@ struct field {
} u;
};
enum counters_type {
COUNTERS_FE = 0,
COUNTERS_BE,
COUNTERS_SV,
COUNTERS_LI,
COUNTERS_OFF_END
};
/* Entity used to generate statistics on an HAProxy component */
struct stats_module {
struct list list;
const char *name;
/* functor used to generate the stats module using counters provided through data parameter */
void (*fill_stats)(void *data, struct field *);
struct name_desc *stats; /* name/description of stats 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 */
size_t counters_size; /* sizeof counters */
uint32_t domain_flags; /* stats application domain for this module */
};
/* stats_domain is used in a flag as a 1 byte field */
enum stats_domain {
STATS_DOMAIN_PROXY = 0,

View File

@ -123,6 +123,8 @@ static inline struct field mkf_flt(uint32_t type, double value)
#define MK_STATS_PROXY_DOMAIN(px_cap) \
((px_cap) << STATS_PX_CAP | STATS_DOMAIN_PROXY)
void stats_register_module(struct stats_module *m);
#endif /* _HAPROXY_STATS_H */
/*

View File

@ -257,6 +257,11 @@ static THREAD_LOCAL struct field info[INF_TOTAL_FIELDS];
/* one line of stats */
static THREAD_LOCAL struct field stats[ST_F_TOTAL_FIELDS];
/* list of all registered stats module */
static struct list stats_module_list[STATS_DOMAIN_COUNT] = {
LIST_HEAD_INIT(stats_module_list[STATS_DOMAIN_PROXY]),
};
static inline uint8_t stats_get_domain(uint32_t domain)
{
return domain >> STATS_DOMAIN & STATS_DOMAIN_MASK;
@ -4035,6 +4040,13 @@ static int cli_io_handler_dump_json_schema(struct appctx *appctx)
return stats_dump_json_schema_to_buffer(appctx->owner);
}
void stats_register_module(struct stats_module *m)
{
const uint8_t domain = stats_get_domain(m->domain_flags);
LIST_ADDQ(&stats_module_list[domain], &m->list);
}
/* register cli keywords */
static struct cli_kw_list cli_kws = {{ },{
{ { "clear", "counters", NULL }, "clear counters : clear max statistics counters (add 'all' for all counters)", cli_parse_clear_counters, NULL, NULL },