mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 05:41:26 +02:00
BUG/MINOR: contrib/prometheus-exporter: Restart labels dump at the right pos
For some metrics, several lines are produced per entity, one per label value. For instance, the health-check status (ST_F_CHECK_STATUS) or the entity status (ST_F_STATUS). The dump may be stopped in the middle of the labels processing if the output buffer is full. This means the next time, we must take care to restart on the right label value. For now, this part is buggy and we always restart to dump all the label values again from the beginning. To be sure to restart at the right position, the field <ctx.stats.st_code> in the applet context is used to save the last position. Of course, we take care to reset this value when necessary. This fix is specific for 2.4. No backport needed.
This commit is contained in:
parent
32ef48e984
commit
040b1195f7
@ -604,7 +604,6 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
struct field *stats = stat_l[STATS_DOMAIN_PROXY];
|
struct field *stats = stat_l[STATS_DOMAIN_PROXY];
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
enum promex_front_state state;
|
enum promex_front_state state;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
|
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 & appctx->ctx.stats.flags))
|
||||||
@ -628,14 +627,15 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
switch (appctx->st2) {
|
switch (appctx->st2) {
|
||||||
case ST_F_STATUS:
|
case ST_F_STATUS:
|
||||||
state = !px->disabled;
|
state = !px->disabled;
|
||||||
for (i = 0; i < PROMEX_FRONT_STATE_COUNT; i++) {
|
for (; appctx->ctx.stats.st_code < PROMEX_FRONT_STATE_COUNT; appctx->ctx.stats.st_code++) {
|
||||||
labels[1].name = ist("state");
|
labels[1].name = ist("state");
|
||||||
labels[1].value = promex_front_st[i];
|
labels[1].value = promex_front_st[appctx->ctx.stats.st_code];
|
||||||
val = mkf_u32(FO_STATUS, state == i);
|
val = mkf_u32(FO_STATUS, state == appctx->ctx.stats.st_code);
|
||||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||||
&val, labels, &out, max))
|
&val, labels, &out, max))
|
||||||
goto full;
|
goto full;
|
||||||
}
|
}
|
||||||
|
appctx->ctx.stats.st_code = 0;
|
||||||
goto next_px;
|
goto next_px;
|
||||||
case ST_F_REQ_RATE_MAX:
|
case ST_F_REQ_RATE_MAX:
|
||||||
case ST_F_REQ_TOT:
|
case ST_F_REQ_TOT:
|
||||||
@ -705,7 +705,6 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
int ret = 1;
|
int ret = 1;
|
||||||
double secs;
|
double secs;
|
||||||
enum promex_back_state state;
|
enum promex_back_state state;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
|
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 & appctx->ctx.stats.flags))
|
||||||
@ -729,14 +728,15 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
switch (appctx->st2) {
|
switch (appctx->st2) {
|
||||||
case ST_F_STATUS:
|
case ST_F_STATUS:
|
||||||
state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0);
|
state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0);
|
||||||
for (i = 0; i < PROMEX_BACK_STATE_COUNT; i++) {
|
for (; appctx->ctx.stats.st_code < PROMEX_BACK_STATE_COUNT; appctx->ctx.stats.st_code++) {
|
||||||
labels[1].name = ist("state");
|
labels[1].name = ist("state");
|
||||||
labels[1].value = promex_back_st[i];
|
labels[1].value = promex_back_st[appctx->ctx.stats.st_code];
|
||||||
val = mkf_u32(FO_STATUS, state == i);
|
val = mkf_u32(FO_STATUS, state == appctx->ctx.stats.st_code);
|
||||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||||
&val, labels, &out, max))
|
&val, labels, &out, max))
|
||||||
goto full;
|
goto full;
|
||||||
}
|
}
|
||||||
|
appctx->ctx.stats.st_code = 0;
|
||||||
goto next_px;
|
goto next_px;
|
||||||
case ST_F_QTIME:
|
case ST_F_QTIME:
|
||||||
secs = (double)swrate_avg(px->be_counters.q_time, TIME_STATS_SAMPLES) / 1000.0;
|
secs = (double)swrate_avg(px->be_counters.q_time, TIME_STATS_SAMPLES) / 1000.0;
|
||||||
@ -838,7 +838,6 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
double secs;
|
double secs;
|
||||||
enum promex_srv_state state;
|
enum promex_srv_state state;
|
||||||
const char *check_state;
|
const char *check_state;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
|
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 & appctx->ctx.stats.flags))
|
||||||
@ -871,14 +870,15 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
switch (appctx->st2) {
|
switch (appctx->st2) {
|
||||||
case ST_F_STATUS:
|
case ST_F_STATUS:
|
||||||
state = promex_srv_status(sv);
|
state = promex_srv_status(sv);
|
||||||
for (i = 0; i < PROMEX_SRV_STATE_COUNT; i++) {
|
for (; appctx->ctx.stats.st_code < PROMEX_SRV_STATE_COUNT; appctx->ctx.stats.st_code++) {
|
||||||
val = mkf_u32(FO_STATUS, state == i);
|
val = mkf_u32(FO_STATUS, state == appctx->ctx.stats.st_code);
|
||||||
labels[2].name = ist("state");
|
labels[2].name = ist("state");
|
||||||
labels[2].value = promex_srv_st[i];
|
labels[2].value = promex_srv_st[appctx->ctx.stats.st_code];
|
||||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||||
&val, labels, &out, max))
|
&val, labels, &out, max))
|
||||||
goto full;
|
goto full;
|
||||||
}
|
}
|
||||||
|
appctx->ctx.stats.st_code = 0;
|
||||||
goto next_sv;
|
goto next_sv;
|
||||||
case ST_F_QTIME:
|
case ST_F_QTIME:
|
||||||
secs = (double)swrate_avg(sv->counters.q_time, TIME_STATS_SAMPLES) / 1000.0;
|
secs = (double)swrate_avg(sv->counters.q_time, TIME_STATS_SAMPLES) / 1000.0;
|
||||||
@ -916,17 +916,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)
|
if ((sv->check.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED)
|
||||||
goto next_sv;
|
goto next_sv;
|
||||||
|
|
||||||
for (i = 0; i < HCHK_STATUS_SIZE; i++) {
|
for (; appctx->ctx.stats.st_code < HCHK_STATUS_SIZE; appctx->ctx.stats.st_code++) {
|
||||||
if (get_check_status_result(i) < CHK_RES_FAILED)
|
if (get_check_status_result(appctx->ctx.stats.st_code) < CHK_RES_FAILED)
|
||||||
continue;
|
continue;
|
||||||
val = mkf_u32(FO_STATUS, sv->check.status == i);
|
val = mkf_u32(FO_STATUS, sv->check.status == appctx->ctx.stats.st_code);
|
||||||
check_state = get_check_status_info(i);
|
check_state = get_check_status_info(appctx->ctx.stats.st_code);
|
||||||
labels[2].name = ist("state");
|
labels[2].name = ist("state");
|
||||||
labels[2].value = ist2(check_state, strlen(check_state));
|
labels[2].value = ist2(check_state, strlen(check_state));
|
||||||
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
|
||||||
&val, labels, &out, max))
|
&val, labels, &out, max))
|
||||||
goto full;
|
goto full;
|
||||||
}
|
}
|
||||||
|
appctx->ctx.stats.st_code = 0;
|
||||||
goto next_sv;
|
goto next_sv;
|
||||||
case ST_F_CHECK_CODE:
|
case ST_F_CHECK_CODE:
|
||||||
if ((sv->check.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED)
|
if ((sv->check.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED)
|
||||||
@ -1006,6 +1007,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *s
|
|||||||
appctx->ctx.stats.obj1 = NULL;
|
appctx->ctx.stats.obj1 = NULL;
|
||||||
appctx->ctx.stats.obj2 = NULL;
|
appctx->ctx.stats.obj2 = NULL;
|
||||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC);
|
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC);
|
||||||
|
appctx->ctx.stats.st_code = 0;
|
||||||
appctx->st2 = INF_NAME;
|
appctx->st2 = INF_NAME;
|
||||||
appctx->st1 = PROMEX_DUMPER_GLOBAL;
|
appctx->st1 = PROMEX_DUMPER_GLOBAL;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
@ -1024,6 +1026,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *s
|
|||||||
appctx->ctx.stats.obj2 = NULL;
|
appctx->ctx.stats.obj2 = NULL;
|
||||||
appctx->ctx.stats.flags &= ~PROMEX_FL_INFO_METRIC;
|
appctx->ctx.stats.flags &= ~PROMEX_FL_INFO_METRIC;
|
||||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_FRONT_METRIC);
|
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_FRONT_METRIC);
|
||||||
|
appctx->ctx.stats.st_code = 0;
|
||||||
appctx->st2 = ST_F_PXNAME;
|
appctx->st2 = ST_F_PXNAME;
|
||||||
appctx->st1 = PROMEX_DUMPER_FRONT;
|
appctx->st1 = PROMEX_DUMPER_FRONT;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
@ -1042,6 +1045,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *s
|
|||||||
appctx->ctx.stats.obj2 = NULL;
|
appctx->ctx.stats.obj2 = NULL;
|
||||||
appctx->ctx.stats.flags &= ~PROMEX_FL_FRONT_METRIC;
|
appctx->ctx.stats.flags &= ~PROMEX_FL_FRONT_METRIC;
|
||||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_BACK_METRIC);
|
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_BACK_METRIC);
|
||||||
|
appctx->ctx.stats.st_code = 0;
|
||||||
appctx->st2 = ST_F_PXNAME;
|
appctx->st2 = ST_F_PXNAME;
|
||||||
appctx->st1 = PROMEX_DUMPER_BACK;
|
appctx->st1 = PROMEX_DUMPER_BACK;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
@ -1060,6 +1064,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *s
|
|||||||
appctx->ctx.stats.obj2 = (appctx->ctx.stats.obj1 ? ((struct proxy *)appctx->ctx.stats.obj1)->srv : NULL);
|
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_BACK_METRIC;
|
||||||
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC);
|
appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC);
|
||||||
|
appctx->ctx.stats.st_code = 0;
|
||||||
appctx->st2 = ST_F_PXNAME;
|
appctx->st2 = ST_F_PXNAME;
|
||||||
appctx->st1 = PROMEX_DUMPER_SRV;
|
appctx->st1 = PROMEX_DUMPER_SRV;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user