Skip to content

Commit

Permalink
MINOR: filters: add per-filter call counters
Browse files Browse the repository at this point in the history
The idea here is to record how many times a filter is being called on a
stream. We're incrementing the same counter all along, regardless of the
type of event, since the purpose is essentially to detect one that might
be misbehaving. The number of calls is reported in "show sess all" next
to the filter name. It may also help detect suboptimal processing. For
example compressing 1GB shows 138k calls to the compression filter, which
is roughly two calls per buffer. Maybe we wake up with incomplete buffers
and compress less. That's left for a future analysis.
  • Loading branch information
wtarreau committed Oct 22, 2024
1 parent 37d5c6f commit 19e4ec4
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
1 change: 1 addition & 0 deletions include/haproxy/filters-t.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ struct filter {
struct flt_conf *config; /* the filter's configuration */
void *ctx; /* The filter context (opaque) */
unsigned short flags; /* FLT_FL_* */
unsigned int calls; /* number of calls */
unsigned long long offset[2]; /* Offset of input data already filtered for a specific channel
* 0: request channel, 1: response channel */
unsigned int pre_analyzers; /* bit field indicating analyzers to pre-process */
Expand Down
34 changes: 27 additions & 7 deletions src/filters.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ flt_stream_release(struct stream *s, int only_backend)

list_for_each_entry_safe(filter, back, &strm_flt(s)->filters, list) {
if (!only_backend || (filter->flags & FLT_FL_IS_BACKEND_FILTER)) {
filter->calls++;
if (FLT_OPS(filter)->detach)
FLT_OPS(filter)->detach(s, filter);
LIST_DELETE(&filter->list);
Expand All @@ -485,8 +486,11 @@ flt_stream_start(struct stream *s)
struct filter *filter;

list_for_each_entry(filter, &strm_flt(s)->filters, list) {
if (FLT_OPS(filter)->stream_start && FLT_OPS(filter)->stream_start(s, filter) < 0)
return -1;
if (FLT_OPS(filter)->stream_start) {
filter->calls++;
if (FLT_OPS(filter)->stream_start(s, filter) < 0)
return -1;
}
}
if (strm_li(s) && (strm_li(s)->bind_conf->analysers & AN_REQ_FLT_START_FE)) {
s->req.flags |= CF_FLT_ANALYZE;
Expand All @@ -505,8 +509,10 @@ flt_stream_stop(struct stream *s)
struct filter *filter;

list_for_each_entry(filter, &strm_flt(s)->filters, list) {
if (FLT_OPS(filter)->stream_stop)
if (FLT_OPS(filter)->stream_stop) {
filter->calls++;
FLT_OPS(filter)->stream_stop(s, filter);
}
}
}

Expand All @@ -520,8 +526,10 @@ flt_stream_check_timeouts(struct stream *s)
struct filter *filter;

list_for_each_entry(filter, &strm_flt(s)->filters, list) {
if (FLT_OPS(filter)->check_timeouts)
if (FLT_OPS(filter)->check_timeouts) {
filter->calls++;
FLT_OPS(filter)->check_timeouts(s, filter);
}
}
}

Expand All @@ -546,9 +554,11 @@ flt_set_stream_backend(struct stream *s, struct proxy *be)

end:
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
if (FLT_OPS(filter)->stream_set_backend &&
FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0)
return -1;
if (FLT_OPS(filter)->stream_set_backend) {
filter->calls++;
if (FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0)
return -1;
}
}
if (be->be_req_ana & AN_REQ_FLT_START_BE) {
s->req.flags |= CF_FLT_ANALYZE;
Expand Down Expand Up @@ -590,6 +600,7 @@ flt_http_end(struct stream *s, struct http_msg *msg)

if (FLT_OPS(filter)->http_end) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->http_end(s, filter, msg);
if (ret <= 0)
BREAK_EXECUTION(s, msg->chn, end);
Expand Down Expand Up @@ -617,6 +628,7 @@ flt_http_reset(struct stream *s, struct http_msg *msg)
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
if (FLT_OPS(filter)->http_reset) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
FLT_OPS(filter)->http_reset(s, filter, msg);
}
}
Expand All @@ -636,6 +648,7 @@ flt_http_reply(struct stream *s, short status, const struct buffer *msg)
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
if (FLT_OPS(filter)->http_reply) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
FLT_OPS(filter)->http_reply(s, filter, status, msg);
}
}
Expand Down Expand Up @@ -678,6 +691,7 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)

if (FLT_OPS(filter)->http_payload) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, data - offset);
if (ret < 0)
goto end;
Expand Down Expand Up @@ -749,6 +763,7 @@ flt_start_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
FLT_OFF(filter, chn) = 0;
if (FLT_OPS(filter)->channel_start_analyze) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->channel_start_analyze(s, filter, chn);
if (ret <= 0)
BREAK_EXECUTION(s, chn, end);
Expand Down Expand Up @@ -781,6 +796,7 @@ flt_pre_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
RESUME_FILTER_LOOP(s, chn) {
if (FLT_OPS(filter)->channel_pre_analyze && (filter->pre_analyzers & an_bit)) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->channel_pre_analyze(s, filter, chn, an_bit);
if (ret <= 0)
BREAK_EXECUTION(s, chn, check_result);
Expand Down Expand Up @@ -814,6 +830,7 @@ flt_post_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
if (FLT_OPS(filter)->channel_post_analyze && (filter->post_analyzers & an_bit)) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->channel_post_analyze(s, filter, chn, an_bit);
if (ret < 0)
break;
Expand Down Expand Up @@ -842,6 +859,7 @@ flt_analyze_http_headers(struct stream *s, struct channel *chn, unsigned int an_
RESUME_FILTER_LOOP(s, chn) {
if (FLT_OPS(filter)->http_headers) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->http_headers(s, filter, msg);
if (ret <= 0)
BREAK_EXECUTION(s, chn, check_result);
Expand Down Expand Up @@ -887,6 +905,7 @@ flt_end_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)

if (FLT_OPS(filter)->channel_end_analyze) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->channel_end_analyze(s, filter, chn);
if (ret <= 0)
BREAK_EXECUTION(s, chn, end);
Expand Down Expand Up @@ -965,6 +984,7 @@ flt_tcp_payload(struct stream *s, struct channel *chn, unsigned int len)
if (FLT_OPS(filter)->tcp_payload) {

DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->tcp_payload(s, filter, chn, out + offset, data - offset);
if (ret < 0)
goto end;
Expand Down
2 changes: 1 addition & 1 deletion src/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -3537,7 +3537,7 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
list_for_each_entry(flt, &strm->strm_flt.filters, list) {
if (flt->list.p != &strm->strm_flt.filters)
chunk_appendf(buf, ", ");
chunk_appendf(buf, "%p=\"%s\"", flt, FLT_ID(flt));
chunk_appendf(buf, "%p=\"%s\" [%u]", flt, FLT_ID(flt), flt->calls);
}
chunk_appendf(buf, "}\n");
}
Expand Down

0 comments on commit 19e4ec4

Please sign in to comment.