diff --git a/src/dumpstats.c b/src/dumpstats.c index 402fb0ae9..b505d4e2e 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; - - if (server_is_draining(sv)) { - if (sv_state == SRV_STATS_STATE_UP_GOING_DOWN) - sv_state = SRV_STATS_STATE_DRAIN_GOING_DOWN; - else - sv_state = SRV_STATS_STATE_DRAIN; + sv_colour = SRV_STATS_COLOUR_UP; } - if (sv_state == SRV_STATS_STATE_UP && !(svs->check.state & CHK_ST_ENABLED)) + if (server_is_draining(sv)) { + if (sv_state == SRV_STATS_STATE_UP_GOING_DOWN) { + sv_state = SRV_STATS_STATE_DRAIN_GOING_DOWN; + } 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)) { 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,