]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Rate limit for most abundant log messages
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 26 Feb 2009 13:23:54 +0000 (14:23 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 26 Feb 2009 13:23:54 +0000 (14:23 +0100)
filter/filter.c
lib/birdlib.h
proto/bgp/bgp.h
proto/bgp/packets.c
sysdep/linux/netlink/netlink.c
sysdep/unix/krt.c
sysdep/unix/log.c

index 9e75f174b2c664d2d51bf2cb0f23706048bce58e..785a0876e4c9be6c61182cc861c387c7dc01bf63 100644 (file)
@@ -281,8 +281,10 @@ rta_cow(void)
   }
 }
 
+static struct rate_limit rl_runtime_err;
+
 #define runtime(x) do { \
-    log( L_ERR "filters, line %d: %s", what->lineno, x); \
+    log_rl(&rl_runtime_err, L_ERR "filters, line %d: %s", what->lineno, x); \
     res.type = T_RETURN; \
     res.val.i = F_ERROR; \
     return res; \
index 93f25fb87837c9a225b4b869cfa4c92efae14e18..b7cd6b43125ab50e66c517ac41b6e5c5d9d9d393 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef _BIRD_BIRDLIB_H_
 #define _BIRD_BIRDLIB_H_
 
+#include "timer.h"
+
 /* Ugly structure offset handling macros */
 
 #define OFFSETOF(s, i) ((unsigned int)&((s *)0)->i)
 
 /* Logging and dying */
 
+struct rate_limit {
+  bird_clock_t timestamp;
+  int count;
+};
+
 #define log log_msg
 void log_msg(char *msg, ...);
+void log_rl(struct rate_limit *rl, char *msg, ...);
 void die(char *msg, ...) NORET;
 void bug(char *msg, ...) NORET;
 
index b706caf10c21f9e7e5c948e96c56e014e1c244e5..b0ead9d3ca827fd80252f7da510cefb8a6848e95 100644 (file)
@@ -139,6 +139,10 @@ void bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code
 #define BGP_TRACE(flags, msg, args...) do { if ((p->p.debug & flags) || BGP_FORCE_DEBUG) \
        log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0)
 
+#define BGP_TRACE_RL(rl, flags, msg, args...) do { if ((p->p.debug & flags) || BGP_FORCE_DEBUG) \
+       log_rl(rl, L_TRACE "%s: " msg, p->p.name , ## args ); } while(0)
+
+
 /* attrs.c */
 
 void bgp_attach_attr(struct ea_list **to, struct linpool *pool, unsigned attr, uintptr_t val);
index 27c0755ee57de64c1c1afef8580f5e30e0879a88..fe7472bdb1f5922c5d30c19870fa927a8b59f404 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "bgp.h"
 
+static struct rate_limit rl_rcv_update,  rl_snd_update;
+
 static byte *
 bgp_create_notification(struct bgp_conn *conn, byte *buf)
 {
@@ -175,7 +177,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
     }
   if (wd_size || r_size)
     {
-      BGP_TRACE(D_PACKETS, "Sending UPDATE");
+      BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
       return w;
     }
   else
@@ -282,7 +284,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
   lp_flush(bgp_linpool);
   if (size)
     {
-      BGP_TRACE(D_PACKETS, "Sending UPDATE");
+      BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
       return w;
     }
   else
@@ -762,7 +764,8 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, int len)
   byte *withdrawn, *attrs, *nlri;
   int withdrawn_len, attr_len, nlri_len;
 
-  BGP_TRACE(D_PACKETS, "Got UPDATE");
+  BGP_TRACE_RL(&rl_rcv_update, D_PACKETS, "Got UPDATE");
+
   if (conn->state != BS_ESTABLISHED)
     { bgp_error(conn, 5, 0, NULL, 0); return; }
   bgp_start_timer(conn->hold_timer, conn->hold_time);
index 08817ca4b5a2d45badea985079c01e1b055b5c0e..734247ec3983a22028dd737d2d9f7e27bf698c61 100644 (file)
@@ -129,6 +129,8 @@ nl_get_reply(void)
     }
 }
 
+static struct rate_limit rl_netlink_err;
+
 static int
 nl_error(struct nlmsghdr *h)
 {
@@ -143,7 +145,7 @@ nl_error(struct nlmsghdr *h)
   e = (struct nlmsgerr *) NLMSG_DATA(h);
   ec = -e->error;
   if (ec)
-    log(L_WARN "Netlink: %s", strerror(ec));
+    log_rl(&rl_netlink_err, L_WARN "Netlink: %s", strerror(ec));
   return ec;
 }
 
index fded9abe39d4fd69b94e174f837f5d906381f1b4..816eb44482c641db12a5e7ac9e3518c734b05126 100644 (file)
@@ -183,18 +183,18 @@ struct protocol proto_unix_iface = {
  *     Tracing of routes
  */
 
-static void
-krt_trace_in_print(struct krt_proto *p, rte *e, char *msg)
+static inline void
+krt_trace_in(struct krt_proto *p, rte *e, char *msg)
 {
-  DBG("KRT: %I/%d: %s\n", e->net->n.prefix, e->net->n.pxlen, msg);
-  log(L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg);
+  if (p->p.debug & D_PACKETS)
+    log(L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg);
 }
 
 static inline void
-krt_trace_in(struct krt_proto *p, rte *e, char *msg)
+krt_trace_in_rl(struct rate_limit *rl, struct krt_proto *p, rte *e, char *msg)
 {
   if (p->p.debug & D_PACKETS)
-    krt_trace_in_print(p, e, msg);
+    log_rl(rl, L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg);
 }
 
 /*
@@ -203,6 +203,8 @@ krt_trace_in(struct krt_proto *p, rte *e, char *msg)
 
 #ifdef KRT_ALLOW_LEARN
 
+static struct rate_limit rl_alien_seen, rl_alien_updated, rl_alien_created, rl_alien_ignored;
+
 static inline int
 krt_same_key(rte *a, rte *b)
 {
@@ -249,20 +251,20 @@ krt_learn_scan(struct krt_proto *p, rte *e)
     {
       if (krt_uptodate(m, e))
        {
-         krt_trace_in(p, e, "[alien] seen");
+         krt_trace_in_rl(&rl_alien_seen, p, e, "[alien] seen");
          rte_free(e);
          m->u.krt.seen = 1;
        }
       else
        {
-         krt_trace_in(p, e, "[alien] updated");
+         krt_trace_in_rl(&rl_alien_updated, p, e, "[alien] updated");
          *mm = m->next;
          rte_free(m);
          m = NULL;
        }
     }
   else
-    krt_trace_in(p, e, "[alien] created");
+    krt_trace_in_rl(&rl_alien_created, p, e, "[alien] created");
   if (!m)
     {
       e->attrs = rta_lookup(e->attrs);
@@ -516,7 +518,7 @@ krt_got_route(struct krt_proto *p, rte *e)
        krt_learn_scan(p, e);
       else
        {
-         krt_trace_in(p, e, "alien route, ignored");
+         krt_trace_in_rl(&rl_alien_ignored, p, e, "alien route, ignored");
          rte_free(e);
        }
       return;
index 08711e172c380fa5b4c49e0bf0bd125bd5483ba6..eb08309908460aaa1f32864c94246bfda3b5d32f 100644 (file)
@@ -30,6 +30,9 @@ static FILE *dbgf = NULL;
 static list *current_log_list;
 static list init_log_list;
 
+bird_clock_t rate_limit_time = 5;
+int rate_limit_count = 5;
+
 #ifdef HAVE_SYSLOG
 #include <sys/syslog.h>
 
@@ -126,6 +129,35 @@ log_msg(char *msg, ...)
   va_end(args);
 }
 
+void
+log_rl(struct rate_limit *rl, char *msg, ...)
+{
+  int class = 1;
+  va_list args;
+
+  bird_clock_t delta = now - rl->timestamp;
+  if ((0 <= delta) && (delta < rate_limit_time))
+    {
+      rl->count++;
+    }
+  else
+    {
+      rl->timestamp = now;
+      rl->count = 1;
+    }
+
+  if (rl->count > rate_limit_count)
+    return;
+
+  va_start(args, msg);
+  if (*msg >= 1 && *msg <= 8)
+    class = *msg++;
+  vlog(class, msg, args);
+  if (rl->count == rate_limit_count)
+    vlog(class, "...", args);
+  va_end(args);
+}
+
 /**
  * bug - report an internal error
  * @msg: a printf-like error message