From: Simon Horman Date: Thu, 23 Apr 2015 05:51:27 +0000 (+0900) Subject: MEDIUM: stats: Separate server state and colour in stats X-Git-Tag: v1.6-dev2~202 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=837bfa74dba61914b44c120d6a2ce731f8138b3e;p=thirdparty%2Fhaproxy.git MEDIUM: stats: Separate server state and colour in stats There is a relationship between the state and colour of a server in stats, however, it is not a one-to-one relationship and the current implementation has proved fragile. This patch attempts to address that problem by clearly separating state and colour. A follow-up patch will further distinguish between DRAIN states and DRAINING colours. Signed-off-by: Simon Horman --- diff --git a/src/dumpstats.c b/src/dumpstats.c index 402fb0ae98..b505d4e2e1 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -2934,13 +2934,35 @@ enum srv_stats_state { SRV_STATS_STATE_COUNT, /* Must be last */ }; +enum srv_stats_colour { + SRV_STATS_COLOUR_DOWN = 0, + SRV_STATS_COLOUR_GOING_UP, + SRV_STATS_COLOUR_GOING_DOWN, + SRV_STATS_COLOUR_UP, + SRV_STATS_COLOUR_NOLB, + SRV_STATS_COLOUR_DRAINING, + SRV_STATS_COLOUR_NO_CHECK, + + SRV_STATS_COLOUR_COUNT, /* Must be last */ +}; + +static const char *srv_stats_colour_st[SRV_STATS_COLOUR_COUNT] = { + [SRV_STATS_COLOUR_DOWN] = "down", + [SRV_STATS_COLOUR_GOING_UP] = "going_up", + [SRV_STATS_COLOUR_GOING_DOWN] = "going_down", + [SRV_STATS_COLOUR_UP] = "up", + [SRV_STATS_COLOUR_NOLB] = "nolb", + [SRV_STATS_COLOUR_DRAINING] = "draining", + [SRV_STATS_COLOUR_NO_CHECK] = "no_check", +}; + /* Dumps a line for server and proxy to the trash and uses the state * from stream interface , stats flags , and server state . * The caller is responsible for clearing the trash if needed. Returns non-zero * if it emits anything, zero otherwise. */ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, int flags, struct server *sv, - enum srv_stats_state state) + enum srv_stats_state state, enum srv_stats_colour colour) { struct appctx *appctx = __objt_appctx(si->end); struct server *via, *ref; @@ -2974,8 +2996,8 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in chunk_appendf(&trash, ""); else chunk_appendf(&trash, - "", - (sv->flags & SRV_F_BACKUP) ? "backup" : "active", state); + "", + (sv->flags & SRV_F_BACKUP) ? "backup" : "active", srv_stats_colour_st[colour]); if ((px->cap & PR_CAP_BE) && px->srv && (appctx->ctx.stats.flags & STAT_ADMIN)) chunk_appendf(&trash, @@ -3853,6 +3875,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy /* stats.sv has been initialized above */ for (; appctx->ctx.stats.sv != NULL; appctx->ctx.stats.sv = sv->next) { enum srv_stats_state sv_state; + enum srv_stats_colour sv_colour; if (buffer_almost_full(rep->buf)) { si->flags |= SI_FL_WAIT_ROOM; @@ -3875,37 +3898,52 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy if (sv->state == SRV_ST_RUNNING || sv->state == SRV_ST_STARTING) { if ((svs->check.state & CHK_ST_ENABLED) && - (svs->check.health < svs->check.rise + svs->check.fall - 1)) + (svs->check.health < svs->check.rise + svs->check.fall - 1)) { sv_state = SRV_STATS_STATE_UP_GOING_DOWN; - else + sv_colour = SRV_STATS_COLOUR_GOING_DOWN; + } else { sv_state = SRV_STATS_STATE_UP; + sv_colour = SRV_STATS_COLOUR_UP; + } if (server_is_draining(sv)) { - if (sv_state == SRV_STATS_STATE_UP_GOING_DOWN) + if (sv_state == SRV_STATS_STATE_UP_GOING_DOWN) { sv_state = SRV_STATS_STATE_DRAIN_GOING_DOWN; - else + } else { sv_state = SRV_STATS_STATE_DRAIN; + sv_colour = SRV_STATS_COLOUR_DRAINING; + } } - if (sv_state == SRV_STATS_STATE_UP && !(svs->check.state & CHK_ST_ENABLED)) + if (sv_state == SRV_STATS_STATE_UP && !(svs->check.state & CHK_ST_ENABLED)) { sv_state = SRV_STATS_STATE_NO_CHECK; + sv_colour = SRV_STATS_COLOUR_NO_CHECK; + } } else if (sv->state == SRV_ST_STOPPING) { if ((!(sv->check.state & CHK_ST_ENABLED) && !sv->track) || - (svs->check.health == svs->check.rise + svs->check.fall - 1)) + (svs->check.health == svs->check.rise + svs->check.fall - 1)) { sv_state = SRV_STATS_STATE_NOLB; - else + sv_colour = SRV_STATS_COLOUR_NOLB; + } else { sv_state = SRV_STATS_STATE_NOLB_GOING_DOWN; + sv_colour = SRV_STATS_COLOUR_GOING_DOWN; + } } else { /* stopped */ - if ((svs->agent.state & CHK_ST_ENABLED) && !svs->agent.health) + if ((svs->agent.state & CHK_ST_ENABLED) && !svs->agent.health) { sv_state = SRV_STATS_STATE_DOWN_AGENT; - else if ((svs->check.state & CHK_ST_ENABLED) && !svs->check.health) + sv_colour = SRV_STATS_COLOUR_DOWN; + } else if ((svs->check.state & CHK_ST_ENABLED) && !svs->check.health) { sv_state = SRV_STATS_STATE_DOWN; /* DOWN */ - else if ((svs->agent.state & CHK_ST_ENABLED) || (svs->check.state & CHK_ST_ENABLED)) + sv_colour = SRV_STATS_COLOUR_DOWN; + } else if ((svs->agent.state & CHK_ST_ENABLED) || (svs->check.state & CHK_ST_ENABLED)) { sv_state = SRV_STATS_STATE_GOING_UP; - else + sv_colour = SRV_STATS_COLOUR_GOING_UP; + } else { sv_state = SRV_STATS_STATE_DOWN; /* DOWN, unchecked */ + sv_colour = SRV_STATS_COLOUR_DOWN; + } } if (((sv_state <= 1) || (sv->admin & SRV_ADMF_MAINT)) && (appctx->ctx.stats.flags & STAT_HIDE_DOWN)) { @@ -3914,7 +3952,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy continue; } - if (stats_dump_sv_stats(si, px, uri ? uri->flags : 0, sv, sv_state)) { + if (stats_dump_sv_stats(si, px, uri ? uri->flags : 0, sv, sv_state, sv_colour)) { if (bi_putchk(rep, &trash) == -1) { si->flags |= SI_FL_WAIT_ROOM; return 0; @@ -4015,26 +4053,20 @@ static void stats_dump_html_head(struct uri_auth *uri) ".frontend {background: #e8e8d0;}\n" ".socket {background: #d0d0d0;}\n" ".backend {background: #e8e8d0;}\n" - ".active0 {background: #ff9090;}\n" - ".active1 {background: #ff9090;}\n" - ".active2 {background: #ffd020;}\n" - ".active3 {background: #ffffa0;}\n" - ".active4 {background: #c0ffc0;}\n" - ".active5 {background: #ffffa0;}\n" /* NOLB state shows same as going down */ - ".active6 {background: #20a0ff;}\n" /* NOLB state shows different to be detected */ - ".active7 {background: #ffffa0;}\n" /* DRAIN going down = same as going down */ - ".active8 {background: #20a0FF;}\n" /* DRAIN must be detected (weight=0) */ - ".active9 {background: #e0e0e0;}\n" - ".backup0 {background: #ff9090;}\n" - ".backup1 {background: #ff9090;}\n" - ".backup2 {background: #ff80ff;}\n" - ".backup3 {background: #c060ff;}\n" - ".backup4 {background: #b0d0ff;}\n" - ".backup5 {background: #c060ff;}\n" /* NOLB state shows same as going down */ - ".backup6 {background: #90b0e0;}\n" /* NOLB state shows same as going down */ - ".backup7 {background: #c060ff;}\n" - ".backup8 {background: #cc9900;}\n" - ".backup9 {background: #e0e0e0;}\n" + ".active_down {background: #ff9090;}\n" + ".active_going_up {background: #ffd020;}\n" + ".active_going_down {background: #ffffa0;}\n" + ".active_up {background: #c0ffc0;}\n" + ".active_nolb {background: #20a0ff;}\n" + ".active_draining {background: #20a0FF;}\n" + ".active_no_check {background: #e0e0e0;}\n" + ".backup_down {background: #ff9090;}\n" + ".backup_going_up {background: #ff80ff;}\n" + ".backup_going_down {background: #c060ff;}\n" + ".backup_up {background: #b0d0ff;}\n" + ".backup_nolb {background: #90b0e0;}\n" + ".backup_draining {background: #cc9900;}\n" + ".backup_no_check {background: #e0e0e0;}\n" ".maintain {background: #c07820;}\n" ".rls {letter-spacing: 0.2em; margin-right: 1px;}\n" /* right letter spacing (used for grouping digits) */ "\n" @@ -4110,21 +4142,21 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u "Running tasks: %d/%d; idle = %d %%
\n" "\n" "\n" - "" - "" + "" + "" "\n" - "" - "" + "" + "" "\n" - "" - "" + "" + "" "\n" - "" - "" + "" + "" "\n" "" "\n" - "" + "" "
 active UP  backup UP  active UP  backup UP
active UP, going down backup UP, going down active UP, going down backup UP, going down
active DOWN, going up backup DOWN, going up active DOWN, going up backup DOWN, going up
active or backup DOWN  not checked active or backup DOWN  not checked
active or backup DOWN for maintenance (MAINT)  
active or backup SOFT STOPPED for maintenance  active or backup SOFT STOPPED for maintenance  
\n" "Note: \"NOLB\"/\"DRAIN\" = UP with load-balancing disabled." "" @@ -4226,7 +4258,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u switch (appctx->ctx.stats.st_code) { case STAT_STATUS_DONE: chunk_appendf(&trash, - "

" + "

" "[X] " "Action processed successfully." "
\n", uri->uri_prefix, @@ -4236,7 +4268,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u break; case STAT_STATUS_NONE: chunk_appendf(&trash, - "

" + "

" "[X] " "Nothing has changed." "
\n", uri->uri_prefix, @@ -4246,7 +4278,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u break; case STAT_STATUS_PART: chunk_appendf(&trash, - "

" + "

" "[X] " "Action partially processed.
" "Some server names are probably unknown or ambiguous (duplicated names in the backend)." @@ -4257,7 +4289,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u break; case STAT_STATUS_ERRP: chunk_appendf(&trash, - "

" + "

" "[X] " "Action not processed because of invalid parameters." "
    " @@ -4272,7 +4304,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u break; case STAT_STATUS_EXCD: chunk_appendf(&trash, - "

    " + "

    " "[X] " "Action not processed : the buffer couldn't store all the data.
    " "You should retry with less servers at a time.
    " @@ -4283,7 +4315,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u break; case STAT_STATUS_DENY: chunk_appendf(&trash, - "

    " + "

    " "[X] " "Action denied." "
    \n", uri->uri_prefix, @@ -4293,7 +4325,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u break; default: chunk_appendf(&trash, - "

    " + "

    " "[X] " "Unexpected result." "
    \n", uri->uri_prefix,