1 /* Copyright (c) 2003-2004, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
8 * \brief Summarize similar messages that would otherwise flood the logs.
11 #include "lib/log/ratelim.h"
12 #include "lib/malloc/malloc.h"
13 #include "lib/string/printf.h"
14 #include "lib/intmath/muldiv.h"
16 /** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return the number
17 * of calls to rate_limit_is_ready (including this one!) since the last time
18 * rate_limit_is_ready returned nonzero. Otherwise return 0.
19 * If the call number hits <b>RATELIM_TOOMANY</b> limit, drop a warning
20 * about this event and stop counting. */
22 rate_limit_is_ready(ratelim_t
*lim
, time_t now
)
24 if (lim
->rate
+ lim
->last_allowed
<= now
) {
25 int res
= lim
->n_calls_since_last_time
+ 1;
26 lim
->last_allowed
= now
;
27 lim
->n_calls_since_last_time
= 0;
30 if (lim
->n_calls_since_last_time
<= RATELIM_TOOMANY
) {
31 ++lim
->n_calls_since_last_time
;
38 /** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return a newly
39 * allocated string indicating how many messages were suppressed, suitable to
40 * append to a log message. Otherwise return NULL. */
42 rate_limit_log(ratelim_t
*lim
, time_t now
)
45 if ((n
= rate_limit_is_ready(lim
, now
))) {
46 time_t started_limiting
= lim
->started_limiting
;
47 lim
->started_limiting
= 0;
49 return tor_strdup("");
52 const char *opt_over
= (n
>= RATELIM_TOOMANY
) ? "over " : "";
53 unsigned difference
= (unsigned)(now
- started_limiting
);
54 difference
= round_to_next_multiple_of(difference
, 60);
56 " [%s%d similar message(s) suppressed in last %d seconds]",
57 opt_over
, n
-1, (int)difference
);
61 if (lim
->started_limiting
== 0) {
62 lim
->started_limiting
= now
;