MINOR: stream: Display the currently running filter per channel in stream dump

Since the 3.1, when stream's info are dump, it is possible to print the
yielding filter on each channel, if any. It was useful to detect buggy
filter on spinning loop. But it is not possible to detect a filter consuming
too much CPU per-execution. We can see a filter was executing in the
backtrace reported by the watchdog, but we are unable to spot the specific
one.

Thanks to this patch, it is now possible. When a dump is emitted, the
running or yield filters on each channel are now displayed with their
current state (RUNNING or YIELDING).

This patch could be backported as far as 3.2 because it could be useful to
spot issues. But the filter API was slightly refactored in 3.4, so this
patch should be adapted.
This commit is contained in:
Christopher Faulet 2026-03-04 11:03:01 +01:00
parent cd9f159210
commit 50fb37e5fe
2 changed files with 14 additions and 9 deletions

View File

@ -69,15 +69,16 @@ static inline struct filter *resume_filter_list_start(struct stream *strm, struc
if (chn->flt.current) {
filter = chn->flt.current;
chn->flt.current = NULL;
if (!(chn_prod(chn)->flags & SC_FL_ERROR) &&
!(chn->flags & (CF_READ_TIMEOUT|CF_WRITE_TIMEOUT))) {
(strm)->waiting_entity.type = STRM_ENTITY_NONE;
(strm)->waiting_entity.ptr = NULL;
}
}
else
else {
filter = flt_list_start(strm, chn);
chn->flt.current = filter;
}
return filter;
}
@ -85,22 +86,24 @@ static inline struct filter *resume_filter_list_start(struct stream *strm, struc
static inline struct filter *resume_filter_list_next(struct stream *strm, struct channel *chn,
struct filter *filter)
{
/* simply an alias to flt_list_next() */
return flt_list_next(strm, chn, filter);
filter = flt_list_next(strm, chn, filter);
chn->flt.current = filter;
return filter;
}
static inline void resume_filter_list_break(struct stream *strm, struct channel *chn,
struct filter *filter, int ret)
{
chn->flt.current = NULL;
if (ret == 0) {
strm->waiting_entity.type = STRM_ENTITY_FILTER;
strm->waiting_entity.ptr = filter;
chn->flt.current = filter;
}
else if (ret < 0) {
strm->last_entity.type = STRM_ENTITY_FILTER;
strm->last_entity.ptr = filter;
}
chn->flt.current = filter;
}
/* List head of all known filter keywords */

View File

@ -3801,8 +3801,9 @@ static void __strm_dump_to_buffer(struct buffer *buf, const struct show_sess_ctx
if (HAS_FILTERS(strm) && strm->req.flt.current) {
const struct filter *flt = strm->req.flt.current;
chunk_appendf(buf, "%s current_filter=%p (id=\"%s\" flags=0x%x pre=0x%x post=0x%x) \n", pfx,
flt, flt->config->id, flt->flags, flt->pre_analyzers, flt->post_analyzers);
chunk_appendf(buf, "%s current_filter=%p (id=\"%s\" flags=0x%x pre=0x%x post=0x%x %s) \n", pfx,
flt, flt->config->id, flt->flags, flt->pre_analyzers, flt->post_analyzers,
(flt == strm->waiting_entity.ptr) ? "YIELDING" : "RUNNING");
}
chunk_appendf(buf,
@ -3834,8 +3835,9 @@ static void __strm_dump_to_buffer(struct buffer *buf, const struct show_sess_ctx
if (HAS_FILTERS(strm) && strm->res.flt.current) {
const struct filter *flt = strm->res.flt.current;
chunk_appendf(buf, "%s current_filter=%p (id=\"%s\" flags=0x%x pre=0x%x post=0x%x) \n", pfx,
flt, flt->config->id, flt->flags, flt->pre_analyzers, flt->post_analyzers);
chunk_appendf(buf, "%s current_filter=%p (id=\"%s\" flags=0x%x pre=0x%x post=0x%x %s) \n", pfx,
flt, flt->config->id, flt->flags, flt->pre_analyzers, flt->post_analyzers,
(flt == strm->waiting_entity.ptr) ? "YIELDING" : "RUNNING");
}
if (strm->current_rule_list && strm->current_rule) {