Postfix3.3.1
msg_rate_delay.c
[詳解]
1 /*++
2 /* NAME
3 /* msg_rate_delay 3
4 /* SUMMARY
5 /* diagnostic interface
6 /* SYNOPSIS
7 /* #include <msg.h>
8 /*
9 /* void msg_rate_delay(stamp, delay, log_fn, fmt, ...)
10 /* time_t *stamp;
11 /* int delay;
12 /* void (*log_fn)(const char *fmt, ...);
13 /* const char *fmt;
14 /* DESCRIPTION
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.
18 /*
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.
22 /*
23 /* Arguments:
24 /* .IP stamp
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.
29 /* .IP delay
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.
33 /* .IP log_fn
34 /* The function that produces log output. Typically, this will
35 /* be msg_info() or msg_warn().
36 /* .IP fmt
37 /* Format string as used with msg(3) routines.
38 /* SEE ALSO
39 /* msg(3) diagnostics interface
40 /* DIAGNOSTICS
41 /* Fatal errors: memory allocation problem.
42 /* LICENSE
43 /* .ad
44 /* .fi
45 /* The Secure Mailer license must be distributed with this software.
46 /* AUTHOR(S)
47 /* Wietse Venema
48 /* IBM T.J. Watson Research
49 /* P.O. Box 704
50 /* Yorktown Heights, NY 10598, USA
51 /*--*/
52 
53 
54 /* System library. */
55 
56 #include <sys_defs.h>
57 #include <time.h>
58 
59 /* Utility library. */
60 
61 #include <msg.h>
62 #include <vstring.h>
63 #include <events.h>
64 
65 /* SLMs. */
66 
67 #define STR(x) vstring_str(x)
68 
69 /* msg_rate_delay - rate-limit message logging */
70 
71 void msg_rate_delay(time_t *stamp, int delay,
72  void (*log_fn) (const char *,...),
73  const char *fmt,...)
74 {
75  const char *myname = "msg_rate_delay";
76  static time_t saved_event_time;
77  time_t now;
78  VSTRING *buf;
79  va_list ap;
80 
81  /*
82  * Sanity check.
83  */
84  if (delay < 0)
85  msg_panic("%s: bad message rate delay: %d", myname, delay);
86 
87  /*
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
91  * result.
92  */
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);
98 
99  /*
100  * Don't log if time is too early.
101  */
102  if (*stamp + delay > now)
103  return;
104  *stamp = now;
105  }
106 
107  /*
108  * OK to log. This is a low-rate event, so we can afford some overhead.
109  */
110  buf = vstring_alloc(100);
111  va_start(ap, fmt);
112  vstring_vsprintf(buf, fmt, ap);
113  va_end(ap);
114  log_fn("%s", STR(buf));
115  vstring_free(buf);
116 }
117 
118 #ifdef TEST
119 
120  /*
121  * Proof-of-concept test program: log messages but skip messages during a
122  * two-second gap.
123  */
124 #include <unistd.h>
125 
126 int main(int argc, char **argv)
127 {
128  int n;
129  time_t stamp = 0;
130 
131  for (n = 0; n < 6; n++) {
132  msg_rate_delay(&stamp, 2, msg_info, "text here %d", n);
133  sleep(1);
134  }
135  return (0);
136 }
137 
138 #endif
int msg_verbose
Definition: msg.c:177
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
int main(int argc, char **argv)
Definition: anvil.c:1010
void msg_rate_delay(time_t *stamp, int delay, void(*log_fn)(const char *,...), const char *fmt,...)
int const char * fmt
VSTRING * vstring_vsprintf(VSTRING *vp, const char *format, va_list ap)
Definition: vstring.c:614
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
time_t event_time(void)
Definition: events.c:647
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
#define STR(x)
void msg_info(const char *fmt,...)
Definition: msg.c:199