5
/* diagnostic interface
9
/* void msg_rate_delay(stamp, delay, log_fn, fmt, ...)
12
/* void (*log_fn)(const char *fmt, ...);
15
/* msg_rate_delay() produces log output at a reduced rate: no
16
/* more than one message per 'delay' seconds. It discards log
17
/* output that would violate the output rate policy.
19
/* This is typically used to log errors accessing a cache with
20
/* high-frequency access but low-value information, to avoid
21
/* spamming the logfile with the same kind of message.
25
/* Time stamp of last log output; specify a zero time stamp
26
/* on the first call. This is an input-output parameter.
27
/* This parameter is ignored when verbose logging is enabled
28
/* or when the delay value is zero.
30
/* The minimum time between log outputs; specify zero to log
31
/* all output for debugging purposes. This parameter is ignored
32
/* when verbose logging is enabled.
34
/* The function that produces log output. Typically, this will
35
/* be msg_info() or msg_warn().
37
/* Format string as used with msg(3) routines.
39
/* msg(3) diagnostics interface
41
/* Fatal errors: memory allocation problem.
45
/* The Secure Mailer license must be distributed with this software.
48
/* IBM T.J. Watson Research
50
/* Yorktown Heights, NY 10598, USA
59
/* Utility library. */
67
#define STR(x) vstring_str(x)
69
/* msg_rate_delay - rate-limit message logging */
71
void msg_rate_delay(time_t *stamp, int delay,
72
void (*log_fn) (const char *,...),
75
const char *myname = "msg_rate_delay";
76
static time_t saved_event_time;
85
msg_panic("%s: bad message rate delay: %d", myname, delay);
88
* This function may be called frequently. Avoid an unnecessary syscall
89
* if possible. Deal with the possibility that a program does not use the
90
* events(3) engine, so that event_time() always produces the same
93
if (msg_verbose == 0 && delay > 0) {
94
if (saved_event_time == 0)
95
now = saved_event_time = event_time();
96
else if ((now = event_time()) == saved_event_time)
97
now = time((time_t *) 0);
100
* Don't log if time is too early.
102
if (*stamp + delay > now)
108
* OK to log. This is a low-rate event, so we can afford some overhead.
110
buf = vstring_alloc(100);
112
vstring_vsprintf(buf, fmt, ap);
114
log_fn("%s", STR(buf));
121
* Proof-of-concept test program: log messages but skip messages during a
126
int main(int argc, char **argv)
131
for (n = 0; n < 6; n++) {
132
msg_rate_delay(&stamp, 2, msg_info, "text here %d", n);