gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r7345 - GNUnet/src/util/error


From: gnunet
Subject: [GNUnet-SVN] r7345 - GNUnet/src/util/error
Date: Fri, 27 Jun 2008 12:50:18 -0600 (MDT)

Author: grothoff
Date: 2008-06-27 12:50:18 -0600 (Fri, 27 Jun 2008)
New Revision: 7345

Added:
   GNUnet/src/util/error/error_test.c
Modified:
   GNUnet/src/util/error/Makefile.am
   GNUnet/src/util/error/error.c
Log:
fixing SVN 1371

Modified: GNUnet/src/util/error/Makefile.am
===================================================================
--- GNUnet/src/util/error/Makefile.am   2008-06-27 18:26:55 UTC (rev 7344)
+++ GNUnet/src/util/error/Makefile.am   2008-06-27 18:50:18 UTC (rev 7345)
@@ -8,3 +8,13 @@
 liberror_la_SOURCES = \
   error.c
 
+
+check_PROGRAMS = \
+ error_test
+
+TESTS = $(check_PROGRAMS)
+
+error_test_SOURCES = \
+ error_test.c
+error_test_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  

Modified: GNUnet/src/util/error/error.c
===================================================================
--- GNUnet/src/util/error/error.c       2008-06-27 18:26:55 UTC (rev 7344)
+++ GNUnet/src/util/error/error.c       2008-06-27 18:50:18 UTC (rev 7345)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2006 Christian Grothoff (and other contributing authors)
+     (C) 2006, 2008 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -25,11 +25,39 @@
  * @author Christian Grothoff
  */
 #include "platform.h"
-#include "gnunet_util_error.h"
+#include "gnunet_util.h"
 #ifdef MINGW
 #include <conio.h>
 #endif
+
 /**
+ * After how many seconds do we always print
+ * that "message X was repeated N times"?
+ */
+#define BULK_DELAY_THRESHOLD (30 * GNUNET_CRON_SECONDS)
+
+/**
+ * After how many repetitions do we always print
+ * that "message X was repeated N times"? (even if
+ * we have not yet reached the delay threshold)
+ */
+#define BULK_REPEAT_THRESHOLD 1000
+
+/**
+ * How many characters do we use for matching of
+ * bulk messages?
+ */
+#define BULK_TRACK_SIZE 256
+
+/**
+ * How many characters can a date/time string
+ * be at most?
+ */ 
+#define DATE_STR_SIZE 64
+
+
+
+/**
  * Default context for logging errors; used
  * if NULL is passed to GNUNET_GE_LOG.
  */
@@ -37,11 +65,50 @@
 
 typedef struct GNUNET_GE_Context
 {
+  /**
+   * Mask that determines which events to log.
+   */
   GNUNET_GE_KIND mask;
+
+  /**
+   * Handler to call for each event.
+   */
   GNUNET_GE_LogHandler handler;
+
+  /**
+   * Extra argument to handler.
+   */
   void *cls;
+
+  /**
+   * Function to call to destroy this context.
+   */
   GNUNET_GE_CtxFree destruct;
+
   GNUNET_GE_Confirm confirm;
+
+  /**
+   * The last "bulk" error message that we have been logging.
+   * Note that this message maybe truncated to the first BULK_TRACK_SIZE
+   * characters, in which case it is NOT 0-terminated!
+   */
+  char last_bulk[BULK_TRACK_SIZE];
+
+  /**
+   * Type of the last bulk message.
+   */
+  GNUNET_GE_KIND last_bulk_kind;
+
+  /**
+   * Time of the last bulk error message (0 for none)
+   */
+  GNUNET_CronTime last_bulk_time;
+
+  /**
+   * Number of times that bulk message has been repeated since.
+   */
+  unsigned int last_bulk_repeat;
+
 } GNUNET_GE_Context;
 
 /**
@@ -57,16 +124,42 @@
           (both & GNUNET_GE_USERKIND) && (both & GNUNET_GE_ROUTEKIND));
 }
 
+static void
+flush_bulk(struct GNUNET_GE_Context*ctx,
+          const char * datestr)
+{
+  char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
+  
+  if (ctx->last_bulk[strnlen(ctx->last_bulk, BULK_TRACK_SIZE)-1] == '\n') 
+    ctx->last_bulk[strnlen(ctx->last_bulk, BULK_TRACK_SIZE)-1] = '\0';
+
+  snprintf(msg,
+          sizeof(msg),
+          _("%s Message `%.*s' repeated %u times in the last %llums\n"),
+          datestr,
+          BULK_TRACK_SIZE,
+          ctx->last_bulk,
+          ctx->last_bulk_repeat,
+          GNUNET_get_time() - ctx->last_bulk_time);
+  if (ctx != NULL)
+    ctx->handler (ctx->cls, ctx->last_bulk_kind, datestr, msg);
+  else
+    fprintf (stderr, "%s %s", datestr, msg);
+  ctx->last_bulk_time = 0;
+  ctx->last_bulk_repeat = 0;
+}
+
 void
 GNUNET_GE_LOG (struct GNUNET_GE_Context *ctx, GNUNET_GE_KIND kind,
                const char *message, ...)
 {
   va_list va;
-  char date[64];
+  char date[DATE_STR_SIZE];
   time_t timetmp;
   struct tm *tmptr;
   size_t size;
   char *buf;
+  GNUNET_CronTime now;
 
   if (ctx == NULL)
     ctx = defaultContext;
@@ -88,9 +181,38 @@
   VSNPRINTF (buf, size, message, va);
   va_end (va);
   time (&timetmp);
-  memset (date, 0, 64);
+  memset (date, 0, DATE_STR_SIZE);
   tmptr = localtime (&timetmp);
-  strftime (date, 64, "%b %d %H:%M:%S", tmptr);
+  strftime (date, DATE_STR_SIZE, "%b %d %H:%M:%S", tmptr);
+  now = GNUNET_get_time();
+  if ( (kind & GNUNET_GE_BULK) != 0)
+    {
+      if ( (ctx->last_bulk_time != 0) &&
+          (0 == strncmp(message,
+                        ctx->last_bulk,
+                        sizeof(ctx->last_bulk))) )
+       {
+         ctx->last_bulk_repeat++;
+         if ( (now - ctx->last_bulk_time > BULK_DELAY_THRESHOLD) ||
+              (ctx->last_bulk_repeat > BULK_REPEAT_THRESHOLD) )
+           flush_bulk(ctx, date);
+         return;
+       }
+      else
+       {
+         if (ctx->last_bulk_time != 0)
+           flush_bulk(ctx, date);
+         strncpy(ctx->last_bulk,
+                 message,
+                 sizeof(ctx->last_bulk));
+         ctx->last_bulk_repeat = 0;
+         ctx->last_bulk_time = now;
+         ctx->last_bulk_kind = kind;
+       }
+    }
+  if ( (now - ctx->last_bulk_time > BULK_DELAY_THRESHOLD) ||
+       (ctx->last_bulk_repeat > BULK_REPEAT_THRESHOLD) )
+    flush_bulk(ctx, date);
   if (ctx != NULL)
     ctx->handler (ctx->cls, kind, date, buf);
   else
@@ -157,8 +279,17 @@
 void
 GNUNET_GE_free_context (GNUNET_GE_Context * ctx)
 {
+  char date[DATE_STR_SIZE];
+  time_t timetmp;
+  struct tm *tmptr;
+ 
   if (ctx == NULL)
     return;
+  time (&timetmp);
+  memset (date, 0, DATE_STR_SIZE);
+  tmptr = localtime (&timetmp);
+  strftime (date, DATE_STR_SIZE, "%b %d %H:%M:%S", tmptr);
+  flush_bulk(ctx, date);
   if (ctx->destruct != NULL)
     ctx->destruct (ctx->cls);
   free (ctx);
@@ -326,8 +457,4 @@
   defaultContext = ctx;
 }
 
-const char *
-GNUNET_GE_strerror (int errnum)
-{
-  return STRERROR (errnum);
-}
+/* end of error.c */

Added: GNUnet/src/util/error/error_test.c
===================================================================
--- GNUnet/src/util/error/error_test.c                          (rev 0)
+++ GNUnet/src/util/error/error_test.c  2008-06-27 18:50:18 UTC (rev 7345)
@@ -0,0 +1,80 @@
+/*
+     This file is part of GNUnet.
+     (C) 2008 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/error/error_test.c
+ * @brief testcase for the error module
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+static void
+my_log (void *ctx,
+       GNUNET_GE_KIND kind,
+       const char *date,
+       const char *msg)
+{
+  unsigned int * c = ctx;
+  (*c)++;
+}
+
+
+
+int
+main (int argc, char *argv[])
+{
+  struct GNUNET_GE_Context * ectx;
+  unsigned int failureCount = 0;
+  unsigned int logs = 0;
+
+  ectx = GNUNET_GE_create_context_callback(GNUNET_GE_ALL,
+                                          &my_log, 
+                                          &logs,
+                                          NULL,
+                                          NULL);
+  GNUNET_GE_LOG(ectx,
+               GNUNET_GE_USER | GNUNET_GE_WARNING |
+               GNUNET_GE_BULK,
+               "Testing...\n");
+  GNUNET_GE_LOG(ectx,
+               GNUNET_GE_USER | GNUNET_GE_WARNING |
+               GNUNET_GE_BULK,
+               "Testing...\n");
+  GNUNET_GE_LOG(ectx,
+               GNUNET_GE_USER | GNUNET_GE_WARNING |
+               GNUNET_GE_BULK,
+               "Testing...\n");  
+  /* the last 2 calls should be merged (repated bulk messages!) */
+  GNUNET_GE_free_context(ectx);
+  if (logs != 2)
+    failureCount++;
+  if (failureCount != 0)
+    {
+      fprintf (stderr, 
+              "\n\n%d TESTS FAILED!\n\n", 
+              failureCount);
+      return -1;
+    }
+  return 0;
+}                               /* end of main */
+
+/* end of error_test.c */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]