mirror of
https://github.com/haproxy/haproxy.git
synced 2026-07-12 02:25:58 -04:00
MINOR: cache: add a counter for cache hits serving early hints
Add a cache_hint_hits counter to the per-proxy HTTP stats, incremented each time the cache emits a 103 Early Hints response. It is reported in the CSV/typed outputs, on the stats page next to the cache hits, and exported to prometheus as http_cache_hint_hits_total. Since the new field changes the shm stats file mapping, its minor version is bumped along with the object size assertion.
This commit is contained in:
parent
25fcee5b0c
commit
6f8c422252
10 changed files with 37 additions and 8 deletions
|
|
@ -259,6 +259,7 @@ listed below. Metrics from extra counters are not listed.
|
|||
| haproxy_frontend_failed_header_rewriting_total |
|
||||
| haproxy_frontend_http_cache_lookups_total |
|
||||
| haproxy_frontend_http_cache_hits_total |
|
||||
| haproxy_frontend_http_cache_hint_hits_total |
|
||||
| haproxy_frontend_internal_errors_total |
|
||||
+-------------------------------------------------+
|
||||
|
||||
|
|
@ -329,6 +330,7 @@ listed below. Metrics from extra counters are not listed.
|
|||
| haproxy_backend_connection_reuses_total |
|
||||
| haproxy_backend_http_cache_lookups_total |
|
||||
| haproxy_backend_http_cache_hits_total |
|
||||
| haproxy_backend_http_cache_hint_hits_total |
|
||||
| haproxy_backend_max_queue_time_seconds |
|
||||
| haproxy_backend_max_connect_time_seconds |
|
||||
| haproxy_backend_max_response_time_seconds |
|
||||
|
|
|
|||
|
|
@ -587,6 +587,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
|||
case ST_I_PX_INTERCEPTED:
|
||||
case ST_I_PX_CACHE_LOOKUPS:
|
||||
case ST_I_PX_CACHE_HITS:
|
||||
case ST_I_PX_CACHE_HINT_HITS:
|
||||
case ST_I_PX_COMP_IN:
|
||||
case ST_I_PX_COMP_OUT:
|
||||
case ST_I_PX_COMP_BYP:
|
||||
|
|
@ -1065,6 +1066,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||
case ST_I_PX_REQ_TOT:
|
||||
case ST_I_PX_CACHE_LOOKUPS:
|
||||
case ST_I_PX_CACHE_HITS:
|
||||
case ST_I_PX_CACHE_HINT_HITS:
|
||||
case ST_I_PX_COMP_IN:
|
||||
case ST_I_PX_COMP_OUT:
|
||||
case ST_I_PX_COMP_BYP:
|
||||
|
|
|
|||
|
|
@ -1375,6 +1375,8 @@ Here is the list of static fields using the proxy statistics domain:
|
|||
process started
|
||||
117. resbout [LFBS]: total number of response bytes sent since the worker
|
||||
process started
|
||||
118. cache_hint_hits [.FB.]: cumulative number of cache hits having served
|
||||
early hints
|
||||
|
||||
For all other statistics domains, the presence or the order of the fields are
|
||||
not guaranteed. In this case, the header line should always be used to parse
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ struct fe_counters_shared_tg {
|
|||
long long cum_req[4]; /* cumulated number of processed other/h1/h2/h3 requests */
|
||||
long long cache_hits; /* cache hits */
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long cache_hint_hits; /* cache hits serving early hints */
|
||||
long long comp_rsp; /* number of compressed responses */
|
||||
long long rsp[6]; /* http response codes */
|
||||
} http;
|
||||
|
|
@ -144,6 +145,7 @@ struct be_counters_shared_tg {
|
|||
|
||||
long long cache_hits; /* cache hits */
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long cache_hint_hits; /* cache hits serving early hints */
|
||||
long long comp_rsp; /* number of compressed responses */
|
||||
long long rsp[6]; /* http response codes */
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ enum stfile_domain {
|
|||
};
|
||||
|
||||
#define SHM_STATS_FILE_VER_MAJOR 1
|
||||
#define SHM_STATS_FILE_VER_MINOR 2
|
||||
#define SHM_STATS_FILE_VER_MINOR 3
|
||||
|
||||
#define SHM_STATS_FILE_HEARTBEAT_TIMEOUT 60 /* passed this delay (seconds) process which has not
|
||||
* sent heartbeat will be considered down
|
||||
|
|
|
|||
|
|
@ -495,6 +495,7 @@ enum stat_idx_px {
|
|||
ST_I_PX_REQ_OUT,
|
||||
ST_I_PX_RES_IN,
|
||||
ST_I_PX_RES_OUT,
|
||||
ST_I_PX_CACHE_HINT_HITS,
|
||||
/* must always be the last one */
|
||||
ST_I_PX_MAX
|
||||
};
|
||||
|
|
|
|||
26
src/cache.c
26
src/cache.c
|
|
@ -2442,16 +2442,17 @@ static int should_send_notmodified_response(struct cache *cache, struct htx *htx
|
|||
* length <hint_data_len>. The format matches what http_action_store_cache
|
||||
* writes: concatenated records of {uint16_t length, char value[length]}, each
|
||||
* value being a Link header value. Skipped for HTTP/1.0 clients.
|
||||
* Returns 1 if a 103 response was emitted, 0 otherwise.
|
||||
*/
|
||||
static void cache_emit_early_hints(struct stream *s, const char *hint_data,
|
||||
unsigned int hint_data_len)
|
||||
static int cache_emit_early_hints(struct stream *s, const char *hint_data,
|
||||
unsigned int hint_data_len)
|
||||
{
|
||||
struct htx *htx;
|
||||
const char *p = hint_data;
|
||||
const char *end = hint_data + hint_data_len;
|
||||
|
||||
if (!(s->txn.http->req.flags & HTTP_MSGF_VER_11))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
htx = http_early_hint_start(s);
|
||||
if (!htx)
|
||||
|
|
@ -2470,11 +2471,12 @@ static void cache_emit_early_hints(struct stream *s, const char *hint_data,
|
|||
|
||||
if (!http_early_hint_end(s))
|
||||
goto error;
|
||||
return;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
channel_htx_truncate(&s->res, htxbuf(&s->res.buf));
|
||||
s->txn.http->status = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *px,
|
||||
|
|
@ -2586,8 +2588,20 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
|
|||
shctx_wrunlock(shctx);
|
||||
cache_rdunlock(cache_tree);
|
||||
|
||||
if (hint_buf && b_data(hint_buf) > 0)
|
||||
cache_emit_early_hints(s, b_orig(hint_buf), b_data(hint_buf));
|
||||
if (hint_buf && b_data(hint_buf) > 0 &&
|
||||
cache_emit_early_hints(s, b_orig(hint_buf), b_data(hint_buf))) {
|
||||
long long *ctr = NULL;
|
||||
|
||||
if (px == strm_fe(s)) {
|
||||
if (px->fe_counters.shared.tg)
|
||||
ctr = &px->fe_counters.shared.tg[tgid - 1]->p.http.cache_hint_hits;
|
||||
}
|
||||
else if (px->be_counters.shared.tg)
|
||||
ctr = &px->be_counters.shared.tg[tgid - 1]->p.http.cache_hint_hits;
|
||||
|
||||
if (ctr)
|
||||
_HA_ATOMIC_INC(ctr);
|
||||
}
|
||||
|
||||
/* In case of Vary, we could have multiple entries with the same
|
||||
* primary hash. We need to calculate the secondary hash in order
|
||||
|
|
|
|||
|
|
@ -849,7 +849,7 @@ int shm_stats_file_prepare(void)
|
|||
BUG_ON(sizeof(struct shm_stats_file_hdr) != 672, "shm_stats_file_hdr struct size changed, "
|
||||
"it is part of the exported API: ensure all precautions were taken (ie: shm_stats_file "
|
||||
"version change) before adjusting this");
|
||||
BUG_ON(sizeof(struct shm_stats_file_object) != 552, "shm_stats_file_object struct size changed, "
|
||||
BUG_ON(sizeof(struct shm_stats_file_object) != 560, "shm_stats_file_object struct size changed, "
|
||||
"it is part of the exported API: ensure all precautions were taken (ie: shm_stats_file "
|
||||
"version change) before adjusting this");
|
||||
|
||||
|
|
|
|||
|
|
@ -611,6 +611,7 @@ int stats_dump_fields_html(struct buffer *out,
|
|||
"<tr><th>Intercepted requests:</th><td>%s</td></tr>"
|
||||
"<tr><th>Cache lookups:</th><td>%s</td></tr>"
|
||||
"<tr><th>Cache hits:</th><td>%s</td><td>(%d%%)</td></tr>"
|
||||
"<tr><th>Cache hint hits:</th><td>%s</td></tr>"
|
||||
"<tr><th>Failed hdr rewrites:</th><td>%s</td></tr>"
|
||||
"<tr><th>Internal errors:</th><td>%s</td></tr>"
|
||||
"",
|
||||
|
|
@ -619,6 +620,7 @@ int stats_dump_fields_html(struct buffer *out,
|
|||
U2H(stats[ST_I_PX_CACHE_HITS].u.u64),
|
||||
stats[ST_I_PX_CACHE_LOOKUPS].u.u64 ?
|
||||
(int)(100 * stats[ST_I_PX_CACHE_HITS].u.u64 / stats[ST_I_PX_CACHE_LOOKUPS].u.u64) : 0,
|
||||
U2H(stats[ST_I_PX_CACHE_HINT_HITS].u.u64),
|
||||
U2H(stats[ST_I_PX_WREW].u.u64),
|
||||
U2H(stats[ST_I_PX_EINT].u.u64));
|
||||
}
|
||||
|
|
@ -1216,6 +1218,7 @@ int stats_dump_fields_html(struct buffer *out,
|
|||
"<tr><th>- other responses:</th><td>%s</td></tr>"
|
||||
"<tr><th>Cache lookups:</th><td>%s</td></tr>"
|
||||
"<tr><th>Cache hits:</th><td>%s</td><td>(%d%%)</td></tr>"
|
||||
"<tr><th>Cache hint hits:</th><td>%s</td></tr>"
|
||||
"<tr><th>Failed hdr rewrites:</th><td>%s</td></tr>"
|
||||
"<tr><th>Internal errors:</th><td>%s</td></tr>"
|
||||
"",
|
||||
|
|
@ -1237,6 +1240,7 @@ int stats_dump_fields_html(struct buffer *out,
|
|||
U2H(stats[ST_I_PX_CACHE_HITS].u.u64),
|
||||
stats[ST_I_PX_CACHE_LOOKUPS].u.u64 ?
|
||||
(int)(100 * stats[ST_I_PX_CACHE_HITS].u.u64 / stats[ST_I_PX_CACHE_LOOKUPS].u.u64) : 0,
|
||||
U2H(stats[ST_I_PX_CACHE_HINT_HITS].u.u64),
|
||||
U2H(stats[ST_I_PX_WREW].u.u64),
|
||||
U2H(stats[ST_I_PX_EINT].u.u64));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ const struct stat_col stat_cols_px[ST_I_PX_MAX] = {
|
|||
[ST_I_PX_REQ_OUT] = ME_NEW_PX_SHARED("reqbout", "req_bytes_out_total", FN_COUNTER, FF_U64, req_out, STATS_PX_CAP_LFBS, "Total number of request bytes sent since process started"),
|
||||
[ST_I_PX_RES_IN] = ME_NEW_PX_SHARED("resbin", "res_bytes_in_total", FN_COUNTER, FF_U64, res_in, STATS_PX_CAP_LFBS, "Total number of response bytes received since process started"),
|
||||
[ST_I_PX_RES_OUT] = ME_NEW_PX_SHARED("resbout", "res_bytes_out_total", FN_COUNTER, FF_U64, res_out, STATS_PX_CAP_LFBS, "Total number of response bytes sent since process started"),
|
||||
[ST_I_PX_CACHE_HINT_HITS] = ME_NEW_PX_SHARED("cache_hint_hits", "http_cache_hint_hits_total", FN_COUNTER, FF_U64, p.http.cache_hint_hits, STATS_PX_CAP__FB_, "Total number of HTTP requests for which a 103 Early Hints response was emitted from the cache on this frontend/backend since the worker process started"),
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -236,6 +237,7 @@ static int stcol_hide(enum stat_idx_px idx, enum obj_type *objt)
|
|||
case ST_I_PX_INTERCEPTED:
|
||||
case ST_I_PX_CACHE_LOOKUPS:
|
||||
case ST_I_PX_CACHE_HITS:
|
||||
case ST_I_PX_CACHE_HINT_HITS:
|
||||
return px->mode != PR_MODE_HTTP;
|
||||
|
||||
case ST_I_PX_CHKFAIL:
|
||||
|
|
|
|||
Loading…
Reference in a new issue