diff options
| author | Anshu Kumari <anskuma@redhat.com> | 2026-03-26 15:20:20 +0530 |
|---|---|---|
| committer | Stefano Brivio <sbrivio@redhat.com> | 2026-03-28 15:02:49 +0100 |
| commit | f758d93125e5980996348a11486af507b3912fcb (patch) | |
| tree | 5a0f552e5fe9b94ab8094f3eeb6e64c430f87d11 | |
| parent | 6dad076df0378eafb544deb64cfa58afbd2ad3d6 (diff) | |
| download | passt-master.tar passt-master.tar.gz passt-master.tar.bz2 passt-master.tar.lz passt-master.tar.xz passt-master.tar.zst passt-master.zip | |
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 <anskuma@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
| -rw-r--r-- | log.h | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -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; |
