CLEANUP: promex: make the applet use its own context
The prometheus applet used to map to the stats context since it was not convenient to have one's own context, and to reuse the fields with its own values and enums. The obj1 pointer was used both for proxies and stick-tables; obj2 was used both for servers and listeners. This change makes use of the generic command context allocation so that the there's now a properly typed context for prometheus, defined in the code itself and independent on the stats or appctx ones. For clarity, the types are correctly set and there's one proxy, one table, one server and one listener. Some could be compacted using unions but that's not necessary since the context is reasonably compact. The stats' st_code field was used as the object state so the new field name is obj_state. An attempt was made to change the types to const for what us only visited but some calls pass through the stats code to retrieve info and that code uses non-const variables due to internal API limitations (read_freq_ctr() being used and requiring variable). That could change in the future, though.
This commit is contained in:
parent
7bf20caacc
commit
ae1747db85
@ -60,7 +60,7 @@ enum {
|
||||
PROMEX_DUMPER_DONE, /* finished */
|
||||
};
|
||||
|
||||
/* Prometheus exporter flags (appctx->ctx.stats.flags) */
|
||||
/* Prometheus exporter flags (ctx->flags) */
|
||||
#define PROMEX_FL_METRIC_HDR 0x00000001
|
||||
#define PROMEX_FL_INFO_METRIC 0x00000002
|
||||
#define PROMEX_FL_FRONT_METRIC 0x00000004
|
||||
@ -80,6 +80,16 @@ enum {
|
||||
PROMEX_FL_SCOPE_LI | PROMEX_FL_SCOPE_BACK | \
|
||||
PROMEX_FL_SCOPE_SERVER | PROMEX_FL_SCOPE_STICKTABLE)
|
||||
|
||||
/* the context of the applet */
|
||||
struct promex_ctx {
|
||||
struct proxy *px; /* current proxy */
|
||||
struct stktable *st; /* current table */
|
||||
struct listener *li; /* current listener */
|
||||
struct server *sv; /* current server */
|
||||
unsigned int flags; /* PROMEX_FL_* */
|
||||
int obj_state; /* current state among PROMEX_{FRONT|BACK|SRV|LI}_STATE_* */
|
||||
};
|
||||
|
||||
/* Promtheus metric type (gauge or counter) */
|
||||
enum promex_mt_type {
|
||||
PROMEX_MT_GAUGE = 1,
|
||||
@ -480,6 +490,7 @@ static int promex_dump_metric(struct appctx *appctx, struct htx *htx, struct ist
|
||||
struct promex_label *labels, struct ist *out, size_t max)
|
||||
{
|
||||
struct ist name = { .ptr = (char[PROMEX_MAX_NAME_LEN]){ 0 }, .len = 0 };
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
size_t len = out->len;
|
||||
|
||||
if (out->len + PROMEX_MAX_METRIC_LENGTH > max)
|
||||
@ -490,7 +501,7 @@ static int promex_dump_metric(struct appctx *appctx, struct htx *htx, struct ist
|
||||
istcat(&name, metric->n, PROMEX_MAX_NAME_LEN);
|
||||
|
||||
|
||||
if ((appctx->ctx.stats.flags & PROMEX_FL_METRIC_HDR) &&
|
||||
if ((ctx->flags & PROMEX_FL_METRIC_HDR) &&
|
||||
!promex_dump_metric_header(appctx, htx, metric, name, out, max))
|
||||
goto full;
|
||||
|
||||
@ -528,7 +539,7 @@ static int promex_dump_metric(struct appctx *appctx, struct htx *htx, struct ist
|
||||
goto full;
|
||||
out->len = trash.data;
|
||||
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_METRIC_HDR;
|
||||
ctx->flags &= ~PROMEX_FL_METRIC_HDR;
|
||||
return 1;
|
||||
full:
|
||||
// Restore previous length
|
||||
@ -543,6 +554,7 @@ static int promex_dump_metric(struct appctx *appctx, struct htx *htx, struct ist
|
||||
static int promex_dump_global_metrics(struct appctx *appctx, struct htx *htx)
|
||||
{
|
||||
static struct ist prefix = IST("haproxy_process_");
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
struct field val;
|
||||
struct channel *chn = cs_ic(appctx->owner);
|
||||
struct ist out = ist2(trash.area, 0);
|
||||
@ -555,7 +567,7 @@ static int promex_dump_global_metrics(struct appctx *appctx, struct htx *htx)
|
||||
for (; appctx->st2 < INF_TOTAL_FIELDS; appctx->st2++) {
|
||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||
|
||||
if (!(promex_global_metrics[appctx->st2].flags & appctx->ctx.stats.flags))
|
||||
if (!(promex_global_metrics[appctx->st2].flags & ctx->flags))
|
||||
continue;
|
||||
|
||||
switch (appctx->st2) {
|
||||
@ -573,7 +585,7 @@ static int promex_dump_global_metrics(struct appctx *appctx, struct htx *htx)
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_METRIC_HDR;
|
||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||
}
|
||||
|
||||
end:
|
||||
@ -593,6 +605,7 @@ static int promex_dump_global_metrics(struct appctx *appctx, struct htx *htx)
|
||||
static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
||||
{
|
||||
static struct ist prefix = IST("haproxy_frontend_");
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
struct proxy *px;
|
||||
struct field val;
|
||||
struct channel *chn = cs_ic(appctx->owner);
|
||||
@ -603,13 +616,13 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
||||
enum promex_front_state state;
|
||||
|
||||
for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
|
||||
if (!(promex_st_metrics[appctx->st2].flags & appctx->ctx.stats.flags))
|
||||
if (!(promex_st_metrics[appctx->st2].flags & ctx->flags))
|
||||
continue;
|
||||
|
||||
while (appctx->ctx.stats.obj1) {
|
||||
while (ctx->px) {
|
||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||
|
||||
px = appctx->ctx.stats.obj1;
|
||||
px = ctx->px;
|
||||
|
||||
labels[0].name = ist("proxy");
|
||||
labels[0].value = ist2(px->id, strlen(px->id));
|
||||
@ -624,15 +637,15 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
||||
switch (appctx->st2) {
|
||||
case ST_F_STATUS:
|
||||
state = !(px->flags & PR_FL_STOPPED);
|
||||
for (; appctx->ctx.stats.st_code < PROMEX_FRONT_STATE_COUNT; appctx->ctx.stats.st_code++) {
|
||||
for (; ctx->obj_state < PROMEX_FRONT_STATE_COUNT; ctx->obj_state++) {
|
||||
labels[1].name = ist("state");
|
||||
labels[1].value = promex_front_st[appctx->ctx.stats.st_code];
|
||||
val = mkf_u32(FO_STATUS, state == appctx->ctx.stats.st_code);
|
||||
labels[1].value = promex_front_st[ctx->obj_state];
|
||||
val = mkf_u32(FO_STATUS, state == ctx->obj_state);
|
||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
}
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->obj_state = 0;
|
||||
goto next_px;
|
||||
case ST_F_REQ_RATE_MAX:
|
||||
case ST_F_REQ_TOT:
|
||||
@ -656,7 +669,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
||||
if (px->mode != PR_MODE_HTTP)
|
||||
goto next_px;
|
||||
if (appctx->st2 != ST_F_HRSP_1XX)
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_METRIC_HDR;
|
||||
ctx->flags &= ~PROMEX_FL_METRIC_HDR;
|
||||
labels[1].name = ist("code");
|
||||
labels[1].value = promex_hrsp_code[appctx->st2 - ST_F_HRSP_1XX];
|
||||
val = stats[appctx->st2];
|
||||
@ -670,10 +683,10 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
next_px:
|
||||
appctx->ctx.stats.obj1 = px->next;
|
||||
ctx->px = px->next;
|
||||
}
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_METRIC_HDR;
|
||||
appctx->ctx.stats.obj1 = proxies_list;
|
||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||
ctx->px = proxies_list;
|
||||
}
|
||||
|
||||
end:
|
||||
@ -693,6 +706,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
||||
static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
||||
{
|
||||
static struct ist prefix = IST("haproxy_listener_");
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
struct proxy *px;
|
||||
struct field val;
|
||||
struct channel *chn = cs_ic(appctx->owner);
|
||||
@ -704,13 +718,13 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
||||
enum li_status status;
|
||||
|
||||
for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
|
||||
if (!(promex_st_metrics[appctx->st2].flags & appctx->ctx.stats.flags))
|
||||
if (!(promex_st_metrics[appctx->st2].flags & ctx->flags))
|
||||
continue;
|
||||
|
||||
while (appctx->ctx.stats.obj1) {
|
||||
while (ctx->px) {
|
||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||
|
||||
px = appctx->ctx.stats.obj1;
|
||||
px = ctx->px;
|
||||
|
||||
labels[0].name = ist("proxy");
|
||||
labels[0].value = ist2(px->id, strlen(px->id));
|
||||
@ -719,7 +733,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
||||
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
|
||||
goto next_px;
|
||||
|
||||
li = appctx->ctx.stats.obj2;
|
||||
li = ctx->li;
|
||||
list_for_each_entry_from(li, &px->conf.listeners, by_fe) {
|
||||
|
||||
if (!li->counters)
|
||||
@ -735,15 +749,15 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
||||
switch (appctx->st2) {
|
||||
case ST_F_STATUS:
|
||||
status = get_li_status(li);
|
||||
for (; appctx->ctx.stats.st_code < LI_STATE_COUNT; appctx->ctx.stats.st_code++) {
|
||||
val = mkf_u32(FO_STATUS, status == appctx->ctx.stats.st_code);
|
||||
for (; ctx->obj_state < LI_STATE_COUNT; ctx->obj_state++) {
|
||||
val = mkf_u32(FO_STATUS, status == ctx->obj_state);
|
||||
labels[2].name = ist("state");
|
||||
labels[2].value = ist(li_status_st[appctx->ctx.stats.st_code]);
|
||||
labels[2].value = ist(li_status_st[ctx->obj_state]);
|
||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
}
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->obj_state = 0;
|
||||
continue;
|
||||
default:
|
||||
val = stats[appctx->st2];
|
||||
@ -757,12 +771,12 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
||||
|
||||
next_px:
|
||||
px = px->next;
|
||||
appctx->ctx.stats.obj1 = px;
|
||||
appctx->ctx.stats.obj2 = (px ? LIST_NEXT(&px->conf.listeners, struct listener *, by_fe) : NULL);
|
||||
ctx->px = px;
|
||||
ctx->li = (px ? LIST_NEXT(&px->conf.listeners, struct listener *, by_fe) : NULL);
|
||||
}
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_METRIC_HDR;
|
||||
appctx->ctx.stats.obj1 = proxies_list;
|
||||
appctx->ctx.stats.obj2 = LIST_NEXT(&proxies_list->conf.listeners, struct listener *, by_fe);
|
||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||
ctx->px = proxies_list;
|
||||
ctx->li = LIST_NEXT(&proxies_list->conf.listeners, struct listener *, by_fe);
|
||||
}
|
||||
|
||||
end:
|
||||
@ -773,7 +787,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
||||
}
|
||||
return ret;
|
||||
full:
|
||||
appctx->ctx.stats.obj2 = li;
|
||||
ctx->li = li;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
@ -783,6 +797,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
||||
static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
||||
{
|
||||
static struct ist prefix = IST("haproxy_backend_");
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
struct proxy *px;
|
||||
struct server *sv;
|
||||
struct field val;
|
||||
@ -796,14 +811,14 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
||||
enum promex_srv_state srv_state;
|
||||
|
||||
for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
|
||||
if (!(promex_st_metrics[appctx->st2].flags & appctx->ctx.stats.flags))
|
||||
if (!(promex_st_metrics[appctx->st2].flags & ctx->flags))
|
||||
continue;
|
||||
|
||||
while (appctx->ctx.stats.obj1) {
|
||||
while (ctx->px) {
|
||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||
unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 };
|
||||
|
||||
px = appctx->ctx.stats.obj1;
|
||||
px = ctx->px;
|
||||
|
||||
labels[0].name = ist("proxy");
|
||||
labels[0].value = ist2(px->id, strlen(px->id));
|
||||
@ -825,27 +840,27 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
||||
srv_state_count[srv_state] += 1;
|
||||
sv = sv->next;
|
||||
}
|
||||
for (; appctx->ctx.stats.st_code < PROMEX_SRV_STATE_COUNT; appctx->ctx.stats.st_code++) {
|
||||
val = mkf_u32(FN_GAUGE, srv_state_count[appctx->ctx.stats.st_code]);
|
||||
for (; ctx->obj_state < PROMEX_SRV_STATE_COUNT; ctx->obj_state++) {
|
||||
val = mkf_u32(FN_GAUGE, srv_state_count[ctx->obj_state]);
|
||||
labels[1].name = ist("state");
|
||||
labels[1].value = promex_srv_st[appctx->ctx.stats.st_code];
|
||||
labels[1].value = promex_srv_st[ctx->obj_state];
|
||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
}
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->obj_state = 0;
|
||||
goto next_px;
|
||||
case ST_F_STATUS:
|
||||
bkd_state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0);
|
||||
for (; appctx->ctx.stats.st_code < PROMEX_BACK_STATE_COUNT; appctx->ctx.stats.st_code++) {
|
||||
for (; ctx->obj_state < PROMEX_BACK_STATE_COUNT; ctx->obj_state++) {
|
||||
labels[1].name = ist("state");
|
||||
labels[1].value = promex_back_st[appctx->ctx.stats.st_code];
|
||||
val = mkf_u32(FO_STATUS, bkd_state == appctx->ctx.stats.st_code);
|
||||
labels[1].value = promex_back_st[ctx->obj_state];
|
||||
val = mkf_u32(FO_STATUS, bkd_state == ctx->obj_state);
|
||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
}
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->obj_state = 0;
|
||||
goto next_px;
|
||||
case ST_F_QTIME:
|
||||
secs = (double)swrate_avg(px->be_counters.q_time, TIME_STATS_SAMPLES) / 1000.0;
|
||||
@ -899,7 +914,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
||||
if (px->mode != PR_MODE_HTTP)
|
||||
goto next_px;
|
||||
if (appctx->st2 != ST_F_HRSP_1XX)
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_METRIC_HDR;
|
||||
ctx->flags &= ~PROMEX_FL_METRIC_HDR;
|
||||
labels[1].name = ist("code");
|
||||
labels[1].value = promex_hrsp_code[appctx->st2 - ST_F_HRSP_1XX];
|
||||
val = stats[appctx->st2];
|
||||
@ -913,10 +928,10 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
next_px:
|
||||
appctx->ctx.stats.obj1 = px->next;
|
||||
ctx->px = px->next;
|
||||
}
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_METRIC_HDR;
|
||||
appctx->ctx.stats.obj1 = proxies_list;
|
||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||
ctx->px = proxies_list;
|
||||
}
|
||||
|
||||
end:
|
||||
@ -936,6 +951,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
||||
static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
{
|
||||
static struct ist prefix = IST("haproxy_server_");
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
struct proxy *px;
|
||||
struct server *sv;
|
||||
struct field val;
|
||||
@ -949,13 +965,13 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
const char *check_state;
|
||||
|
||||
for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
|
||||
if (!(promex_st_metrics[appctx->st2].flags & appctx->ctx.stats.flags))
|
||||
if (!(promex_st_metrics[appctx->st2].flags & ctx->flags))
|
||||
continue;
|
||||
|
||||
while (appctx->ctx.stats.obj1) {
|
||||
while (ctx->px) {
|
||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||
|
||||
px = appctx->ctx.stats.obj1;
|
||||
px = ctx->px;
|
||||
|
||||
labels[0].name = ist("proxy");
|
||||
labels[0].value = ist2(px->id, strlen(px->id));
|
||||
@ -964,8 +980,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
|
||||
goto next_px;
|
||||
|
||||
while (appctx->ctx.stats.obj2) {
|
||||
sv = appctx->ctx.stats.obj2;
|
||||
while (ctx->sv) {
|
||||
sv = ctx->sv;
|
||||
|
||||
labels[1].name = ist("server");
|
||||
labels[1].value = ist2(sv->id, strlen(sv->id));
|
||||
@ -973,21 +989,21 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
if (!stats_fill_sv_stats(px, sv, 0, stats, ST_F_TOTAL_FIELDS, &(appctx->st2)))
|
||||
return -1;
|
||||
|
||||
if ((appctx->ctx.stats.flags & PROMEX_FL_NO_MAINT_SRV) && (sv->cur_admin & SRV_ADMF_MAINT))
|
||||
if ((ctx->flags & PROMEX_FL_NO_MAINT_SRV) && (sv->cur_admin & SRV_ADMF_MAINT))
|
||||
goto next_sv;
|
||||
|
||||
switch (appctx->st2) {
|
||||
case ST_F_STATUS:
|
||||
state = promex_srv_status(sv);
|
||||
for (; appctx->ctx.stats.st_code < PROMEX_SRV_STATE_COUNT; appctx->ctx.stats.st_code++) {
|
||||
val = mkf_u32(FO_STATUS, state == appctx->ctx.stats.st_code);
|
||||
for (; ctx->obj_state < PROMEX_SRV_STATE_COUNT; ctx->obj_state++) {
|
||||
val = mkf_u32(FO_STATUS, state == ctx->obj_state);
|
||||
labels[2].name = ist("state");
|
||||
labels[2].value = promex_srv_st[appctx->ctx.stats.st_code];
|
||||
labels[2].value = promex_srv_st[ctx->obj_state];
|
||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
}
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->obj_state = 0;
|
||||
goto next_sv;
|
||||
case ST_F_QTIME:
|
||||
secs = (double)swrate_avg(sv->counters.q_time, TIME_STATS_SAMPLES) / 1000.0;
|
||||
@ -1025,18 +1041,18 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
if ((sv->check.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED)
|
||||
goto next_sv;
|
||||
|
||||
for (; appctx->ctx.stats.st_code < HCHK_STATUS_SIZE; appctx->ctx.stats.st_code++) {
|
||||
if (get_check_status_result(appctx->ctx.stats.st_code) < CHK_RES_FAILED)
|
||||
for (; ctx->obj_state < HCHK_STATUS_SIZE; ctx->obj_state++) {
|
||||
if (get_check_status_result(ctx->obj_state) < CHK_RES_FAILED)
|
||||
continue;
|
||||
val = mkf_u32(FO_STATUS, sv->check.status == appctx->ctx.stats.st_code);
|
||||
check_state = get_check_status_info(appctx->ctx.stats.st_code);
|
||||
val = mkf_u32(FO_STATUS, sv->check.status == ctx->obj_state);
|
||||
check_state = get_check_status_info(ctx->obj_state);
|
||||
labels[2].name = ist("state");
|
||||
labels[2].value = ist(check_state);
|
||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
}
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->obj_state = 0;
|
||||
goto next_sv;
|
||||
case ST_F_CHECK_CODE:
|
||||
if ((sv->check.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED)
|
||||
@ -1063,7 +1079,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
if (px->mode != PR_MODE_HTTP)
|
||||
goto next_px;
|
||||
if (appctx->st2 != ST_F_HRSP_1XX)
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_METRIC_HDR;
|
||||
ctx->flags &= ~PROMEX_FL_METRIC_HDR;
|
||||
labels[2].name = ist("code");
|
||||
labels[2].value = promex_hrsp_code[appctx->st2 - ST_F_HRSP_1XX];
|
||||
val = stats[appctx->st2];
|
||||
@ -1077,16 +1093,16 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
next_sv:
|
||||
appctx->ctx.stats.obj2 = sv->next;
|
||||
ctx->sv = sv->next;
|
||||
}
|
||||
|
||||
next_px:
|
||||
appctx->ctx.stats.obj1 = px->next;
|
||||
appctx->ctx.stats.obj2 = (appctx->ctx.stats.obj1 ? ((struct proxy *)appctx->ctx.stats.obj1)->srv : NULL);
|
||||
ctx->px = px->next;
|
||||
ctx->sv = (ctx->px ? ctx->px->srv : NULL);
|
||||
}
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_METRIC_HDR;
|
||||
appctx->ctx.stats.obj1 = proxies_list;
|
||||
appctx->ctx.stats.obj2 = (appctx->ctx.stats.obj1 ? ((struct proxy *)appctx->ctx.stats.obj1)->srv : NULL);
|
||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||
ctx->px = proxies_list;
|
||||
ctx->sv = (ctx->px ? ctx->px->srv : NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -1107,6 +1123,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
static int promex_dump_sticktable_metrics(struct appctx *appctx, struct htx *htx)
|
||||
{
|
||||
static struct ist prefix = IST("haproxy_sticktable_");
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
struct field val;
|
||||
struct channel *chn = cs_ic(appctx->owner);
|
||||
struct ist out = ist2(trash.area, 0);
|
||||
@ -1115,13 +1132,13 @@ static int promex_dump_sticktable_metrics(struct appctx *appctx, struct htx *htx
|
||||
struct stktable *t;
|
||||
|
||||
for (; appctx->st2 < STICKTABLE_TOTAL_FIELDS; appctx->st2++) {
|
||||
if (!(promex_sticktable_metrics[appctx->st2].flags & appctx->ctx.stats.flags))
|
||||
if (!(promex_sticktable_metrics[appctx->st2].flags & ctx->flags))
|
||||
continue;
|
||||
|
||||
while (appctx->ctx.stats.obj1) {
|
||||
while (ctx->st) {
|
||||
struct promex_label labels[PROMEX_MAX_LABELS - 1] = {};
|
||||
|
||||
t = appctx->ctx.stats.obj1;
|
||||
t = ctx->st;
|
||||
if (!t->size)
|
||||
goto next_px;
|
||||
|
||||
@ -1146,10 +1163,10 @@ static int promex_dump_sticktable_metrics(struct appctx *appctx, struct htx *htx
|
||||
goto full;
|
||||
|
||||
next_px:
|
||||
appctx->ctx.stats.obj1 = t->next;
|
||||
ctx->st = t->next;
|
||||
}
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_METRIC_HDR;
|
||||
appctx->ctx.stats.obj1 = stktables_list;
|
||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||
ctx->st = stktables_list;
|
||||
}
|
||||
|
||||
end:
|
||||
@ -1167,24 +1184,28 @@ static int promex_dump_sticktable_metrics(struct appctx *appctx, struct htx *htx
|
||||
/* Dump all metrics (global, frontends, backends and servers) depending on the
|
||||
* dumper state (appctx->st1). It returns 1 on success, 0 if <htx> is full and
|
||||
* -1 in case of any error.
|
||||
* Uses <appctx.ctx.stats.obj1> as a pointer to the current proxy and <obj2> as
|
||||
* a pointer to the current server/listener. */
|
||||
* Uses <appctx.ctx.stats.px> as a pointer to the current proxy and <sv>/<li>
|
||||
* as pointers to the current server/listener respectively.
|
||||
*/
|
||||
static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, struct htx *htx)
|
||||
{
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
int ret;
|
||||
|
||||
switch (appctx->st1) {
|
||||
case PROMEX_DUMPER_INIT:
|
||||
appctx->ctx.stats.obj1 = NULL;
|
||||
appctx->ctx.stats.obj2 = NULL;
|
||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC);
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->px = NULL;
|
||||
ctx->st = NULL;
|
||||
ctx->li = NULL;
|
||||
ctx->sv = NULL;
|
||||
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC);
|
||||
ctx->obj_state = 0;
|
||||
appctx->st2 = INF_NAME;
|
||||
appctx->st1 = PROMEX_DUMPER_GLOBAL;
|
||||
/* fall through */
|
||||
|
||||
case PROMEX_DUMPER_GLOBAL:
|
||||
if (appctx->ctx.stats.flags & PROMEX_FL_SCOPE_GLOBAL) {
|
||||
if (ctx->flags & PROMEX_FL_SCOPE_GLOBAL) {
|
||||
ret = promex_dump_global_metrics(appctx, htx);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
@ -1193,17 +1214,19 @@ static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, st
|
||||
}
|
||||
}
|
||||
|
||||
appctx->ctx.stats.obj1 = proxies_list;
|
||||
appctx->ctx.stats.obj2 = NULL;
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_INFO_METRIC;
|
||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_FRONT_METRIC);
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->px = proxies_list;
|
||||
ctx->st = NULL;
|
||||
ctx->li = NULL;
|
||||
ctx->sv = NULL;
|
||||
ctx->flags &= ~PROMEX_FL_INFO_METRIC;
|
||||
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_FRONT_METRIC);
|
||||
ctx->obj_state = 0;
|
||||
appctx->st2 = ST_F_PXNAME;
|
||||
appctx->st1 = PROMEX_DUMPER_FRONT;
|
||||
/* fall through */
|
||||
|
||||
case PROMEX_DUMPER_FRONT:
|
||||
if (appctx->ctx.stats.flags & PROMEX_FL_SCOPE_FRONT) {
|
||||
if (ctx->flags & PROMEX_FL_SCOPE_FRONT) {
|
||||
ret = promex_dump_front_metrics(appctx, htx);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
@ -1212,17 +1235,19 @@ static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, st
|
||||
}
|
||||
}
|
||||
|
||||
appctx->ctx.stats.obj1 = proxies_list;
|
||||
appctx->ctx.stats.obj2 = LIST_NEXT(&proxies_list->conf.listeners, struct listener *, by_fe);
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_FRONT_METRIC;
|
||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_LI_METRIC);
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->px = proxies_list;
|
||||
ctx->st = NULL;
|
||||
ctx->li = LIST_NEXT(&proxies_list->conf.listeners, struct listener *, by_fe);
|
||||
ctx->sv = NULL;
|
||||
ctx->flags &= ~PROMEX_FL_FRONT_METRIC;
|
||||
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_LI_METRIC);
|
||||
ctx->obj_state = 0;
|
||||
appctx->st2 = ST_F_PXNAME;
|
||||
appctx->st1 = PROMEX_DUMPER_LI;
|
||||
/* fall through */
|
||||
|
||||
case PROMEX_DUMPER_LI:
|
||||
if (appctx->ctx.stats.flags & PROMEX_FL_SCOPE_LI) {
|
||||
if (ctx->flags & PROMEX_FL_SCOPE_LI) {
|
||||
ret = promex_dump_listener_metrics(appctx, htx);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
@ -1231,17 +1256,19 @@ static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, st
|
||||
}
|
||||
}
|
||||
|
||||
appctx->ctx.stats.obj1 = proxies_list;
|
||||
appctx->ctx.stats.obj2 = NULL;
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_LI_METRIC;
|
||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_BACK_METRIC);
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->px = proxies_list;
|
||||
ctx->st = NULL;
|
||||
ctx->li = NULL;
|
||||
ctx->sv = NULL;
|
||||
ctx->flags &= ~PROMEX_FL_LI_METRIC;
|
||||
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_BACK_METRIC);
|
||||
ctx->obj_state = 0;
|
||||
appctx->st2 = ST_F_PXNAME;
|
||||
appctx->st1 = PROMEX_DUMPER_BACK;
|
||||
/* fall through */
|
||||
|
||||
case PROMEX_DUMPER_BACK:
|
||||
if (appctx->ctx.stats.flags & PROMEX_FL_SCOPE_BACK) {
|
||||
if (ctx->flags & PROMEX_FL_SCOPE_BACK) {
|
||||
ret = promex_dump_back_metrics(appctx, htx);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
@ -1250,17 +1277,19 @@ static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, st
|
||||
}
|
||||
}
|
||||
|
||||
appctx->ctx.stats.obj1 = proxies_list;
|
||||
appctx->ctx.stats.obj2 = (appctx->ctx.stats.obj1 ? ((struct proxy *)appctx->ctx.stats.obj1)->srv : NULL);
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_BACK_METRIC;
|
||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC);
|
||||
appctx->ctx.stats.st_code = 0;
|
||||
ctx->px = proxies_list;
|
||||
ctx->st = NULL;
|
||||
ctx->li = NULL;
|
||||
ctx->sv = ctx->px ? ctx->px->srv : NULL;
|
||||
ctx->flags &= ~PROMEX_FL_BACK_METRIC;
|
||||
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC);
|
||||
ctx->obj_state = 0;
|
||||
appctx->st2 = ST_F_PXNAME;
|
||||
appctx->st1 = PROMEX_DUMPER_SRV;
|
||||
/* fall through */
|
||||
|
||||
case PROMEX_DUMPER_SRV:
|
||||
if (appctx->ctx.stats.flags & PROMEX_FL_SCOPE_SERVER) {
|
||||
if (ctx->flags & PROMEX_FL_SCOPE_SERVER) {
|
||||
ret = promex_dump_srv_metrics(appctx, htx);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
@ -1269,16 +1298,18 @@ static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, st
|
||||
}
|
||||
}
|
||||
|
||||
appctx->ctx.stats.obj1 = stktables_list;
|
||||
appctx->ctx.stats.obj2 = NULL;
|
||||
appctx->ctx.stats.flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC);
|
||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_STICKTABLE_METRIC);
|
||||
ctx->px = NULL;
|
||||
ctx->st = stktables_list;
|
||||
ctx->li = NULL;
|
||||
ctx->sv = NULL;
|
||||
ctx->flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC);
|
||||
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_STICKTABLE_METRIC);
|
||||
appctx->st2 = STICKTABLE_SIZE;
|
||||
appctx->st1 = PROMEX_DUMPER_STICKTABLE;
|
||||
/* fall through */
|
||||
|
||||
case PROMEX_DUMPER_STICKTABLE:
|
||||
if (appctx->ctx.stats.flags & PROMEX_FL_SCOPE_STICKTABLE) {
|
||||
if (ctx->flags & PROMEX_FL_SCOPE_STICKTABLE) {
|
||||
ret = promex_dump_sticktable_metrics(appctx, htx);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
@ -1287,9 +1318,11 @@ static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, st
|
||||
}
|
||||
}
|
||||
|
||||
appctx->ctx.stats.obj1 = NULL;
|
||||
appctx->ctx.stats.obj2 = NULL;
|
||||
appctx->ctx.stats.flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_STICKTABLE_METRIC);
|
||||
ctx->px = NULL;
|
||||
ctx->st = NULL;
|
||||
ctx->li = NULL;
|
||||
ctx->sv = NULL;
|
||||
ctx->flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_STICKTABLE_METRIC);
|
||||
appctx->st2 = 0;
|
||||
appctx->st1 = PROMEX_DUMPER_DONE;
|
||||
/* fall through */
|
||||
@ -1306,9 +1339,11 @@ static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, st
|
||||
return 0;
|
||||
error:
|
||||
/* unrecoverable error */
|
||||
appctx->ctx.stats.obj1 = NULL;
|
||||
appctx->ctx.stats.obj2 = NULL;
|
||||
appctx->ctx.stats.flags = 0;
|
||||
ctx->px = NULL;
|
||||
ctx->st = NULL;
|
||||
ctx->li = NULL;
|
||||
ctx->sv = NULL;
|
||||
ctx->flags = 0;
|
||||
appctx->st2 = 0;
|
||||
appctx->st1 = PROMEX_DUMPER_DONE;
|
||||
return -1;
|
||||
@ -1318,6 +1353,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct conn_stream *cs, st
|
||||
* success and -1 on error. */
|
||||
static int promex_parse_uri(struct appctx *appctx, struct conn_stream *cs)
|
||||
{
|
||||
struct promex_ctx *ctx = appctx->svcctx;
|
||||
struct channel *req = cs_oc(cs);
|
||||
struct channel *res = cs_ic(cs);
|
||||
struct htx *req_htx, *res_htx;
|
||||
@ -1387,30 +1423,30 @@ static int promex_parse_uri(struct appctx *appctx, struct conn_stream *cs)
|
||||
if (!value)
|
||||
goto error;
|
||||
else if (*value == 0)
|
||||
appctx->ctx.stats.flags &= ~PROMEX_FL_SCOPE_ALL;
|
||||
ctx->flags &= ~PROMEX_FL_SCOPE_ALL;
|
||||
else if (*value == '*')
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_ALL;
|
||||
ctx->flags |= PROMEX_FL_SCOPE_ALL;
|
||||
else if (strcmp(value, "global") == 0)
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_GLOBAL;
|
||||
ctx->flags |= PROMEX_FL_SCOPE_GLOBAL;
|
||||
else if (strcmp(value, "server") == 0)
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_SERVER;
|
||||
ctx->flags |= PROMEX_FL_SCOPE_SERVER;
|
||||
else if (strcmp(value, "backend") == 0)
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_BACK;
|
||||
ctx->flags |= PROMEX_FL_SCOPE_BACK;
|
||||
else if (strcmp(value, "frontend") == 0)
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_FRONT;
|
||||
ctx->flags |= PROMEX_FL_SCOPE_FRONT;
|
||||
else if (strcmp(value, "listener") == 0)
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_LI;
|
||||
ctx->flags |= PROMEX_FL_SCOPE_LI;
|
||||
else if (strcmp(value, "sticktable") == 0)
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_STICKTABLE;
|
||||
ctx->flags |= PROMEX_FL_SCOPE_STICKTABLE;
|
||||
else
|
||||
goto error;
|
||||
}
|
||||
else if (strcmp(key, "no-maint") == 0)
|
||||
appctx->ctx.stats.flags |= PROMEX_FL_NO_MAINT_SRV;
|
||||
ctx->flags |= PROMEX_FL_NO_MAINT_SRV;
|
||||
}
|
||||
|
||||
end:
|
||||
appctx->ctx.stats.flags |= default_scopes;
|
||||
ctx->flags |= default_scopes;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
@ -1457,6 +1493,7 @@ static int promex_send_headers(struct appctx *appctx, struct conn_stream *cs, st
|
||||
*/
|
||||
static int promex_appctx_init(struct appctx *appctx)
|
||||
{
|
||||
applet_reserve_svcctx(appctx, sizeof(struct promex_ctx));
|
||||
appctx->st0 = PROMEX_ST_INIT;
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user