From: Amaury Denoyelle Date: Tue, 30 Apr 2024 10:04:57 +0000 (+0200) Subject: MINOR: counters: move last_change into counters struct X-Git-Tag: v3.0-dev10~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=634cc2a5d84123303b61bf0d6311925b96cdaf3b;p=thirdparty%2Fhaproxy.git MINOR: counters: move last_change into counters struct last_change was a member present in both proxy and server struct. It is used as an age statistics to report the last update of the object. Move last_change into fe_counters/be_counters. This is necessary to be able to manipulate it through generic stat column and report it into stats-file. Note that there is a change for proxy structure with now 2 different last_change values, on frontend and backend side. Special care was taken to ensure that the value is initialized only on the proxy side. The other value is set to 0 unless a listen proxy is instantiated. For the moment, only backend counter is reported in stats. However, with now two distinct values, stats could be extended to report it on both side. --- diff --git a/include/haproxy/counters-t.h b/include/haproxy/counters-t.h index eb1ce66d28..8539d6c221 100644 --- a/include/haproxy/counters-t.h +++ b/include/haproxy/counters-t.h @@ -69,6 +69,8 @@ struct fe_counters { struct freq_ctr sess_per_sec; /* sessions per second on this server */ struct freq_ctr req_per_sec; /* HTTP requests per second on the frontend */ struct freq_ctr conn_per_sec; /* received connections per second on the frontend */ + + unsigned long last_change; /* last time, when the state was changed */ }; /* counters used by servers and backends */ @@ -76,7 +78,6 @@ struct be_counters { unsigned int conn_max; /* max # of active sessions */ long long cum_sess; /* cumulated number of accepted connections */ long long cum_lbconn; /* cumulated number of sessions processed by load balancing (BE only) */ - unsigned long last_sess; /* last session time */ unsigned int cps_max; /* maximum of new connections received per second */ unsigned int sps_max; /* maximum of new connections accepted per second (sessions) */ @@ -123,6 +124,9 @@ struct be_counters { } p; /* protocol-specific stats */ struct freq_ctr sess_per_sec; /* sessions per second on this server */ + + unsigned long last_sess; /* last session time */ + unsigned long last_change; /* last time, when the state was changed */ }; #endif /* _HAPROXY_COUNTERS_T_H */ diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index 7695b4ef36..f6ed211c14 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -361,7 +361,6 @@ struct proxy { unsigned int retry_type; /* Type of retry allowed */ int redispatch_after; /* number of retries before redispatch */ unsigned down_time; /* total time the proxy was down */ - time_t last_change; /* last time, when the state was changed */ int (*accept)(struct stream *s); /* application layer's accept() */ struct conn_src conn_src; /* connection source settings */ enum obj_type *default_target; /* default target to use for accepted streams or NULL */ diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h index b6ff41a9cf..d59ca40ef4 100644 --- a/include/haproxy/server-t.h +++ b/include/haproxy/server-t.h @@ -381,7 +381,6 @@ struct server { struct xprt_ops *xprt; /* transport-layer operations */ unsigned int svc_port; /* the port to connect to (for relevant families) */ unsigned down_time; /* total time the server was down */ - time_t last_change; /* last time, when the state was changed */ int puid; /* proxy-unique server ID, used for SNMP, and "first" LB algo */ int tcp_ut; /* for TCP, user timeout */ diff --git a/src/backend.c b/src/backend.c index cfe1add5a6..7779eb1b43 100644 --- a/src/backend.c +++ b/src/backend.c @@ -2566,7 +2566,7 @@ void back_handle_st_rdy(struct stream *s) */ void set_backend_down(struct proxy *be) { - be->last_change = ns_to_sec(now_ns); + be->be_counters.last_change = ns_to_sec(now_ns); _HA_ATOMIC_INC(&be->be_counters.down_trans); if (!(global.mode & MODE_STARTING)) { @@ -2639,10 +2639,10 @@ no_cookie: } int be_downtime(struct proxy *px) { - if (px->lbprm.tot_weight && px->last_change < ns_to_sec(now_ns)) // ignore negative time + if (px->lbprm.tot_weight && px->be_counters.last_change < ns_to_sec(now_ns)) // ignore negative time return px->down_time; - return ns_to_sec(now_ns) - px->last_change + px->down_time; + return ns_to_sec(now_ns) - px->be_counters.last_change + px->down_time; } /* diff --git a/src/check.c b/src/check.c index ff6977cf09..4e84fdba90 100644 --- a/src/check.c +++ b/src/check.c @@ -1031,9 +1031,9 @@ int httpchk_build_status_header(struct server *s, struct buffer *buf) s->queue.length); if ((s->cur_state == SRV_ST_STARTING) && - ns_to_sec(now_ns) < s->last_change + s->slowstart && - ns_to_sec(now_ns) >= s->last_change) { - ratio = MAX(1, 100 * (ns_to_sec(now_ns) - s->last_change) / s->slowstart); + ns_to_sec(now_ns) < s->counters.last_change + s->slowstart && + ns_to_sec(now_ns) >= s->counters.last_change) { + ratio = MAX(1, 100 * (ns_to_sec(now_ns) - s->counters.last_change) / s->slowstart); chunk_appendf(buf, "; throttle=%d%%", ratio); } diff --git a/src/cli.c b/src/cli.c index c29a15ef69..980735dcdb 100644 --- a/src/cli.c +++ b/src/cli.c @@ -455,7 +455,7 @@ static struct proxy *cli_alloc_fe(const char *name, const char *file, int line) init_new_proxy(fe); fe->next = proxies_list; proxies_list = fe; - fe->last_change = ns_to_sec(now_ns); + fe->fe_counters.last_change = ns_to_sec(now_ns); fe->id = strdup("GLOBAL"); fe->cap = PR_CAP_FE|PR_CAP_INT; fe->maxconn = 10; /* default to 10 concurrent connections */ diff --git a/src/flt_spoe.c b/src/flt_spoe.c index b180ba2dd5..16a6535df0 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -3014,7 +3014,7 @@ spoe_init(struct proxy *px, struct flt_conf *fconf) /* conf->agent_fe was already initialized during the config * parsing. Finish initialization. */ - conf->agent_fe.last_change = ns_to_sec(now_ns); + conf->agent_fe.fe_counters.last_change = ns_to_sec(now_ns); conf->agent_fe.cap = PR_CAP_FE; conf->agent_fe.mode = PR_MODE_TCP; conf->agent_fe.maxconn = 0; diff --git a/src/log.c b/src/log.c index 29618206f8..098d16867a 100644 --- a/src/log.c +++ b/src/log.c @@ -5525,7 +5525,7 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm) px->conf.file = strdup(file); px->conf.line = linenum; px->mode = PR_MODE_SYSLOG; - px->last_change = ns_to_sec(now_ns); + px->fe_counters.last_change = ns_to_sec(now_ns); px->cap = PR_CAP_FE; px->maxconn = 10; px->timeout.client = TICK_ETERNITY; diff --git a/src/peers.c b/src/peers.c index db85acf727..a7d03d42d3 100644 --- a/src/peers.c +++ b/src/peers.c @@ -3219,7 +3219,7 @@ static void peer_session_forceshutdown(struct peer *peer) /* Pre-configures a peers frontend to accept incoming connections */ void peers_setup_frontend(struct proxy *fe) { - fe->last_change = ns_to_sec(now_ns); + fe->fe_counters.last_change = ns_to_sec(now_ns); fe->cap = PR_CAP_FE | PR_CAP_BE; fe->mode = PR_MODE_PEERS; fe->maxconn = 0; diff --git a/src/proxy.c b/src/proxy.c index 6fd123638f..f1d9d7ab05 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -1570,6 +1570,7 @@ void proxy_unref_defaults(struct proxy *px) */ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, char **errmsg) { + uint last_change; struct proxy *curproxy; if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) { @@ -1578,7 +1579,13 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, char **errmsg) } init_new_proxy(curproxy); - curproxy->last_change = ns_to_sec(now_ns); + + last_change = ns_to_sec(now_ns); + if (cap & PR_CAP_FE) + curproxy->fe_counters.last_change = last_change; + if (cap & PR_CAP_BE) + curproxy->be_counters.last_change = last_change; + curproxy->id = strdup(name); curproxy->cap = cap; @@ -2723,7 +2730,7 @@ static int dump_servers_state(struct appctx *appctx) dump_server_addr(&srv->check.addr, srv_check_addr); dump_server_addr(&srv->agent.addr, srv_agent_addr); - srv_time_since_last_change = ns_to_sec(now_ns) - srv->last_change; + srv_time_since_last_change = ns_to_sec(now_ns) - srv->counters.last_change; bk_f_forced_id = px->options & PR_O_FORCED_ID ? 1 : 0; srv_f_forced_id = srv->flags & SRV_F_FORCED_ID ? 1 : 0; diff --git a/src/queue.c b/src/queue.c index f20285b91b..e55bb58982 100644 --- a/src/queue.c +++ b/src/queue.c @@ -114,10 +114,10 @@ unsigned int srv_dynamic_maxconn(const struct server *s) s->proxy->beconn * s->maxconn / s->proxy->fullconn); if ((s->cur_state == SRV_ST_STARTING) && - ns_to_sec(now_ns) < s->last_change + s->slowstart && - ns_to_sec(now_ns) >= s->last_change) { + ns_to_sec(now_ns) < s->counters.last_change + s->slowstart && + ns_to_sec(now_ns) >= s->counters.last_change) { unsigned int ratio; - ratio = 100 * (ns_to_sec(now_ns) - s->last_change) / s->slowstart; + ratio = 100 * (ns_to_sec(now_ns) - s->counters.last_change) / s->slowstart; max = MAX(1, max * ratio / 100); } return max; diff --git a/src/resolvers.c b/src/resolvers.c index 0ee076800a..1a0020b63f 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -3324,7 +3324,7 @@ int check_action_do_resolve(struct act_rule *rule, struct proxy *px, char **err) void resolvers_setup_proxy(struct proxy *px) { - px->last_change = ns_to_sec(now_ns); + px->fe_counters.last_change = px->be_counters.last_change = ns_to_sec(now_ns); px->cap = PR_CAP_FE | PR_CAP_BE; px->maxconn = 0; px->conn_retries = 1; diff --git a/src/server.c b/src/server.c index 5a4020ff96..878bddfd7c 100644 --- a/src/server.c +++ b/src/server.c @@ -141,10 +141,10 @@ const char *srv_op_st_chg_cause(enum srv_op_st_chg_cause cause) int srv_downtime(const struct server *s) { - if ((s->cur_state != SRV_ST_STOPPED) || s->last_change >= ns_to_sec(now_ns)) // ignore negative time + if ((s->cur_state != SRV_ST_STOPPED) || s->counters.last_change >= ns_to_sec(now_ns)) // ignore negative time return s->down_time; - return ns_to_sec(now_ns) - s->last_change + s->down_time; + return ns_to_sec(now_ns) - s->counters.last_change + s->down_time; } int srv_lastsession(const struct server *s) @@ -2336,7 +2336,7 @@ void server_recalc_eweight(struct server *sv, int must_update) struct proxy *px = sv->proxy; unsigned w; - if (ns_to_sec(now_ns) < sv->last_change || ns_to_sec(now_ns) >= sv->last_change + sv->slowstart) { + if (ns_to_sec(now_ns) < sv->counters.last_change || ns_to_sec(now_ns) >= sv->counters.last_change + sv->slowstart) { /* go to full throttle if the slowstart interval is reached unless server is currently down */ if ((sv->cur_state != SRV_ST_STOPPED) && (sv->next_state == SRV_ST_STARTING)) sv->next_state = SRV_ST_RUNNING; @@ -2348,7 +2348,7 @@ void server_recalc_eweight(struct server *sv, int must_update) if ((sv->cur_state == SRV_ST_STOPPED) && (sv->next_state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN)) w = 1; else if ((sv->next_state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN)) - w = (px->lbprm.wdiv * (ns_to_sec(now_ns) - sv->last_change) + sv->slowstart) / sv->slowstart; + w = (px->lbprm.wdiv * (ns_to_sec(now_ns) - sv->counters.last_change) + sv->slowstart) / sv->slowstart; else w = px->lbprm.wdiv; @@ -2868,7 +2868,7 @@ struct server *new_server(struct proxy *proxy) srv->rid = 0; /* rid defaults to 0 */ srv->next_state = SRV_ST_RUNNING; /* early server setup */ - srv->last_change = ns_to_sec(now_ns); + srv->counters.last_change = ns_to_sec(now_ns); srv->check.obj_type = OBJ_TYPE_CHECK; srv->check.status = HCHK_STATUS_INI; @@ -5496,7 +5496,7 @@ static int srv_alloc_lb(struct server *sv, struct proxy *be) /* updates the server's weight during a warmup stage. Once the final weight is * reached, the task automatically stops. Note that any server status change - * must have updated s->last_change accordingly. + * must have updated s->counters.last_change accordingly. */ static struct task *server_warmup(struct task *t, void *context, unsigned int state) { @@ -5552,7 +5552,7 @@ static int init_srv_slowstart(struct server *srv) if (srv->next_state == SRV_ST_STARTING) { task_schedule(srv->warmup, tick_add(now_ms, - MS_TO_TICKS(MAX(1000, (ns_to_sec(now_ns) - srv->last_change)) / 20))); + MS_TO_TICKS(MAX(1000, (ns_to_sec(now_ns) - srv->counters.last_change)) / 20))); } } @@ -6685,8 +6685,8 @@ static void srv_update_status(struct server *s, int type, int cause) if (srv_prev_state != s->cur_state) { if (srv_prev_state == SRV_ST_STOPPED) { /* server was down and no longer is */ - if (s->last_change < ns_to_sec(now_ns)) // ignore negative times - s->down_time += ns_to_sec(now_ns) - s->last_change; + if (s->counters.last_change < ns_to_sec(now_ns)) // ignore negative times + s->down_time += ns_to_sec(now_ns) - s->counters.last_change; _srv_event_hdl_publish(EVENT_HDL_SUB_SERVER_UP, cb_data.common, s); } else if (s->cur_state == SRV_ST_STOPPED) { @@ -6694,7 +6694,7 @@ static void srv_update_status(struct server *s, int type, int cause) s->counters.down_trans++; _srv_event_hdl_publish(EVENT_HDL_SUB_SERVER_DOWN, cb_data.common, s); } - s->last_change = ns_to_sec(now_ns); + s->counters.last_change = ns_to_sec(now_ns); /* publish the state change */ _srv_event_hdl_prepare_state(&cb_data.state, @@ -6709,9 +6709,9 @@ static void srv_update_status(struct server *s, int type, int cause) /* backend was down and is back up again: * no helper function, updating last_change and backend downtime stats */ - if (s->proxy->last_change < ns_to_sec(now_ns)) // ignore negative times - s->proxy->down_time += ns_to_sec(now_ns) - s->proxy->last_change; - s->proxy->last_change = ns_to_sec(now_ns); + if (s->proxy->be_counters.last_change < ns_to_sec(now_ns)) // ignore negative times + s->proxy->down_time += ns_to_sec(now_ns) - s->proxy->be_counters.last_change; + s->proxy->be_counters.last_change = ns_to_sec(now_ns); } } diff --git a/src/server_state.c b/src/server_state.c index ebdcf3c69d..ffc2463d3f 100644 --- a/src/server_state.c +++ b/src/server_state.c @@ -321,7 +321,7 @@ static void srv_state_srv_update(struct server *srv, int version, char **params) srv_adm_set_drain(srv); } - srv->last_change = ns_to_sec(now_ns) - srv_last_time_change; + srv->counters.last_change = ns_to_sec(now_ns) - srv_last_time_change; srv->check.status = srv_check_status; srv->check.result = srv_check_result; diff --git a/src/sink.c b/src/sink.c index 76f3ffb147..af1a334709 100644 --- a/src/sink.c +++ b/src/sink.c @@ -332,7 +332,7 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc /* Pre-configures a ring proxy to emit connections */ void sink_setup_proxy(struct proxy *px) { - px->last_change = ns_to_sec(now_ns); + px->be_counters.last_change = ns_to_sec(now_ns); px->cap = PR_CAP_BE; px->maxconn = 0; px->conn_retries = 1; diff --git a/src/stats.c b/src/stats.c index f9ce6faf5a..e792f86526 100644 --- a/src/stats.c +++ b/src/stats.c @@ -1311,7 +1311,7 @@ int stats_fill_sv_line(struct proxy *px, struct server *sv, int flags, field = mkf_str(FO_STATUS, fld_status); break; case ST_I_PX_LASTCHG: - field = mkf_u32(FN_AGE, ns_to_sec(now_ns) - sv->last_change); + field = mkf_u32(FN_AGE, ns_to_sec(now_ns) - sv->counters.last_change); break; case ST_I_PX_WEIGHT: field = mkf_u32(FN_AVG, (sv->cur_eweight * px->lbprm.wmult + px->lbprm.wdiv - 1) / px->lbprm.wdiv); @@ -1684,7 +1684,7 @@ int stats_fill_be_line(struct proxy *px, int flags, struct field *line, int len, field = mkf_u32(0, px->srv_bck); break; case ST_I_PX_LASTCHG: - field = mkf_u32(FN_AGE, ns_to_sec(now_ns) - px->last_change); + field = mkf_u32(FN_AGE, ns_to_sec(now_ns) - px->be_counters.last_change); break; case ST_I_PX_DOWNTIME: if (px->srv)