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-f758d93125e5980996348a11486af507b3912fcb.tar passt-f758d93125e5980996348a11486af507b3912fcb.tar.gz passt-f758d93125e5980996348a11486af507b3912fcb.tar.bz2 passt-f758d93125e5980996348a11486af507b3912fcb.tar.lz passt-f758d93125e5980996348a11486af507b3912fcb.tar.xz passt-f758d93125e5980996348a11486af507b3912fcb.tar.zst passt-f758d93125e5980996348a11486af507b3912fcb.zip | |
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 <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; |
