[PATCH v4] log: Add rate-limiting macros for log messages
Currently, some log messages that would be useful at info or warn level
are kept at debug level because there is no way to throttle them, and a
guest could otherwise flood the host logs.
Add a logmsg_ratelimit() macro that uses per-call-site static variables
to independently track each call site's rate. It allows up to
LOG_RATELIMIT_BURST (5) messages per LOG_RATELIMIT_INTERVAL (1 second)
window, then prints a suppression notice. When a new window opens and
messages were suppressed, the count is reported after the next allowed
message.
Link: https://bugs.passt.top/show_bug.cgi?id=134
Signed-off-by: Anshu Kumari
On Thu, Mar 26, 2026 at 03:20:20PM +0530, Anshu Kumari wrote:
Currently, some log messages that would be useful at info or warn level are kept at debug level because there is no way to throttle them, and a guest could otherwise flood the host logs.
Add a logmsg_ratelimit() macro that uses per-call-site static variables to independently track each call site's rate. It allows up to LOG_RATELIMIT_BURST (5) messages per LOG_RATELIMIT_INTERVAL (1 second) window, then prints a suppression notice. When a new window opens and messages were suppressed, the count is reported after the next allowed message.
Link: https://bugs.passt.top/show_bug.cgi?id=134 Signed-off-by: Anshu Kumari
Reviewed-by: David Gibson
--- v4: - Print suppression notice immediately after the last allowed message, not on the next call, to avoid confusion with unrelated messages in between. - Add Link: tag before Signed-off-by --- log.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/log.h b/log.h index 6ceb686..dbab006 100644 --- a/log.h +++ b/log.h @@ -48,6 +48,50 @@ void logmsg_perror(int pri, const char *format, ...) passt_exit(EXIT_FAILURE); \ } while (0)
+#define LOG_RATELIMIT_INTERVAL 1 /* Default rate limit window in seconds */ +#define LOG_RATELIMIT_BURST 5 /* Max messages per window per call site */ + +/** + * logmsg_ratelimit() - Log a message with rate limiting + * @fn: Logging function name (e.g. warn, info, debug) + * @now: Current timestamp + */ +#define logmsg_ratelimit(fn, now, ...) \ + do { \ + static unsigned int rl_suppressed_; \ + static unsigned int rl_printed_; \ + static time_t rl_last_; \ + \ + if ((now)->tv_sec - rl_last_ > LOG_RATELIMIT_INTERVAL) {\ + rl_last_ = (now)->tv_sec; \ + rl_printed_ = 0; \ + } \ + \ + if (rl_printed_ < LOG_RATELIMIT_BURST) { \ + fn(__VA_ARGS__); \ + if (rl_suppressed_) { \ + fn("(suppressed %u similar messages)", \ + rl_suppressed_); \ + rl_suppressed_ = 0; \ + } \ + rl_printed_++; \ + if (rl_printed_ == LOG_RATELIMIT_BURST) \ + fn("(suppressing further similar" \ + " messages)"); \ + } else { \ + rl_suppressed_++; \ + } \ + } while (0) + +#define err_ratelimit(now, ...) \ + logmsg_ratelimit(err, now, __VA_ARGS__) +#define warn_ratelimit(now, ...) \ + logmsg_ratelimit(warn, now, __VA_ARGS__) +#define info_ratelimit(now, ...) \ + logmsg_ratelimit(info, now, __VA_ARGS__) +#define debug_ratelimit(now, ...) \ + logmsg_ratelimit(debug, now, __VA_ARGS__) + extern int log_file; extern int log_trace; extern bool log_conf_parsed; -- 2.53.0
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
On Thu, 26 Mar 2026 15:20:20 +0530
Anshu Kumari
Currently, some log messages that would be useful at info or warn level are kept at debug level because there is no way to throttle them, and a guest could otherwise flood the host logs.
Add a logmsg_ratelimit() macro that uses per-call-site static variables to independently track each call site's rate. It allows up to LOG_RATELIMIT_BURST (5) messages per LOG_RATELIMIT_INTERVAL (1 second) window, then prints a suppression notice. When a new window opens and messages were suppressed, the count is reported after the next allowed message.
Link: https://bugs.passt.top/show_bug.cgi?id=134 Signed-off-by: Anshu Kumari
Applied, thanks, and welcome to the git log!
--- v4: - Print suppression notice immediately after the last allowed message, not on the next call, to avoid confusion with unrelated messages in between. - Add Link: tag before Signed-off-by
By the way, you can also decide to leave the whole history (v2, v3) here. I actually find it a bit more convenient, but not everybody does. I guess it depends on how fast you re-post: if there are chances somebody missed your v3, then having the whole history is nicer for reviewers. You could also consider using git-publish for this: https://github.com/stefanha/git-publish I don't use it because of my own scripts and habits, but some others on this list certainly do. -- Stefano
participants (3)
-
Anshu Kumari
-
David Gibson
-
Stefano Brivio