From: Willy Tarreau Date: Wed, 24 Apr 2019 06:41:29 +0000 (+0200) Subject: MINOR: applet: measure and report an appctx's call rate in "show sess" X-Git-Tag: v2.0-dev3~177 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22d63a24d93211f431ae3ef504c7a85c243fb618;p=thirdparty%2Fhaproxy.git MINOR: applet: measure and report an appctx's call rate in "show sess" Very similarly to previous commit doing the same for streams, we now measure and report an appctx's call rate. This will help catch applets which do not consume all their data and/or which do not properly report that they're waiting for something else. Some of them like peers might theorically be able to exhibit some occasional peeks when teaching a full table to a nearby peer (e.g. the new replacement process), but nothing close to what a bogus service can do so there is no risk of confusion. --- diff --git a/include/proto/applet.h b/include/proto/applet.h index 91d7be25bf..62612b5546 100644 --- a/include/proto/applet.h +++ b/include/proto/applet.h @@ -48,6 +48,9 @@ static inline void appctx_init(struct appctx *appctx, unsigned long thread_mask) appctx->chunk = NULL; appctx->io_release = NULL; appctx->thread_mask = thread_mask; + appctx->call_rate.curr_sec = 0; + appctx->call_rate.curr_ctr = 0; + appctx->call_rate.prev_ctr = 0; appctx->state = 0; } diff --git a/include/types/applet.h b/include/types/applet.h index 21c0e90e78..4786b31f2b 100644 --- a/include/types/applet.h +++ b/include/types/applet.h @@ -22,6 +22,7 @@ #ifndef _TYPES_APPLET_H #define _TYPES_APPLET_H +#include #include #include #include @@ -70,6 +71,7 @@ struct appctx { struct buffer_wait buffer_wait; /* position in the list of objects waiting for a buffer */ unsigned long thread_mask; /* mask of thread IDs authorized to process the applet */ struct task *t; /* task associated to the applet */ + struct freq_ctr call_rate; /* appctx call rate */ union { struct { diff --git a/src/applet.c b/src/applet.c index 9c591c760a..aacc04b67a 100644 --- a/src/applet.c +++ b/src/applet.c @@ -73,6 +73,9 @@ struct task *task_run_applet(struct task *t, void *context, unsigned short state si_cant_get(si); si_rx_endp_done(si); + /* measure the call rate */ + update_freq_ctr(&app->call_rate, 1); + /* Now we'll try to allocate the input buffer. We wake up the applet in * all cases. So this is the applet's responsibility to check if this * buffer was allocated or not. This leaves a chance for applets to do diff --git a/src/stream.c b/src/stream.c index 7f3e99d140..1af563d679 100644 --- a/src/stream.c +++ b/src/stream.c @@ -3070,14 +3070,14 @@ static int stats_dump_full_strm_to_buffer(struct stream_interface *si, struct st } else if ((tmpctx = objt_appctx(strm->si[0].end)) != NULL) { chunk_appendf(&trash, - " app0=%p st0=%d st1=%d st2=%d applet=%s tmask=0x%lx nice=%d calls=%u cpu=%llu lat=%llu\n", + " app0=%p st0=%d st1=%d st2=%d applet=%s tmask=0x%lx nice=%d calls=%u rate=%u cpu=%llu lat=%llu\n", tmpctx, tmpctx->st0, tmpctx->st1, tmpctx->st2, tmpctx->applet->name, tmpctx->thread_mask, - tmpctx->t->nice, tmpctx->t->calls, + tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate), (unsigned long long)tmpctx->t->cpu_time, (unsigned long long)tmpctx->t->lat_time); } @@ -3107,14 +3107,14 @@ static int stats_dump_full_strm_to_buffer(struct stream_interface *si, struct st } else if ((tmpctx = objt_appctx(strm->si[1].end)) != NULL) { chunk_appendf(&trash, - " app1=%p st0=%d st1=%d st2=%d applet=%s tmask=0x%lx, nice=%d, calls=%u, cpu=%llu, lat=%llu\n", + " app1=%p st0=%d st1=%d st2=%d applet=%s tmask=0x%lx nice=%d calls=%u rate=%u cpu=%llu lat=%llu\n", tmpctx, tmpctx->st0, tmpctx->st1, tmpctx->st2, tmpctx->applet->name, tmpctx->thread_mask, - tmpctx->t->nice, tmpctx->t->calls, + tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate), (unsigned long long)tmpctx->t->cpu_time, (unsigned long long)tmpctx->t->lat_time); }