[or-cvs] Add backend support for multiple logfiles, including consol...

Nick Mathewson nickm at seul.org
Tue Sep 16 17:58:38 UTC 2003


Update of /home/or/cvsroot/src/common
In directory moria.mit.edu:/tmp/cvs-serv1221/src/common

Modified Files:
	log.c log.h 
Log Message:
Add backend support for multiple logfiles, including console logs.

Also optimize logging by formatting messages in memory before sending
them through stdio.  (It turns out (according to gprof) that logging
performance matters.)




Index: log.c
===================================================================
RCS file: /home/or/cvsroot/src/common/log.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- log.c	11 Sep 2003 22:13:13 -0000	1.11
+++ log.c	16 Sep 2003 17:58:36 -0000	1.12
@@ -5,7 +5,18 @@
 #include "../or/or.h"
 #include "util.h"
 
-static const char *sev_to_string(int severity) {
+struct logfile_t;
+
+typedef struct logfile_t {
+  struct logfile_t *next;
+  const char *filename;
+  FILE *file;
+  int needs_close;
+  int loglevel;
+  int max_loglevel;
+} logfile_t;
+
+static INLINE const char *sev_to_string(int severity) {
   switch(severity) {
     case LOG_DEBUG:   return "debug";
     case LOG_INFO:    return "info";
@@ -20,26 +31,63 @@
 }
 
 static int loglevel = LOG_DEBUG;
+static logfile_t *logfiles = NULL;
 
-static void 
-logv(int severity, const char *funcname, const char *format, va_list ap)
+/* Format a log message into a fixed-sized buffer. (This is factored out
+ * of 'logv' so that we never format a message more than once.
+ */
+static INLINE void format_msg(char *buf, size_t buf_len,
+			      int severity, const char *funcname, 
+			      const char *format, va_list ap) 
 {
-  char buf[201];
   time_t t;
   struct timeval now;
+  int n;
+
+  buf_len -= 2; /* subtract 2 characters so we have room for \n\0 */
+  
+  my_gettimeofday(&now);
+  t = (time_t)now.tv_sec;
+  
+  n  = strftime(buf, buf_len, "%b %d %H:%M:%S", localtime(&t));
+  n += snprintf(buf+n, buf_len-n,
+		".%.3ld [%s] ", 
+		(long)now.tv_usec / 1000, sev_to_string(severity));
+  if (funcname)
+    n += snprintf(buf+n, buf_len-n, "%s(): ", funcname);
+
+  n += vsnprintf(buf+n,buf_len-n,format,ap);
+  buf[n]='\n';
+  buf[n+1]='\0';
+}
+
+static void 
+logv(int severity, const char *funcname, const char *format, va_list ap)
+{
+  char buf[1024];
+  int formatted = 0;
+  logfile_t *lf;
   
   assert(format);
   if (severity < loglevel)
     return;
-  my_gettimeofday(&now);
+  if (!logfiles) {
+    /* XXX This is a temporary measure until we get configuration support
+       for logfiles. */
+    add_stream_log(loglevel, "<stdout>", stdout);
+  }
+  for (lf = logfiles; lf; lf = lf->next) {
+    if (severity < lf->loglevel || severity > lf->max_loglevel)
+      continue;
+    if (!lf->file)
+      continue;
 
-  t = time(NULL);
-  strftime(buf, 200, "%b %d %H:%M:%S", localtime(&t));
-  printf("%s.%.3ld [%s] ", buf, (long)now.tv_usec / 1000, sev_to_string(severity));
-  if (funcname)
-    printf("%s(): ", funcname);
-  vprintf(format,ap);
-  printf("\n");
+    if (!formatted) {
+      format_msg(buf, 1024, severity, funcname, format, ap);
+      formatted = 1;
+    }
+    fputs(buf, lf->file);
+  }
 }
 
 void 
@@ -65,4 +113,47 @@
   va_end(ap);
 }
 
+void close_logs()
+{
+  logfile_t *next, *lf;
+  for (lf = logfiles; lf; lf = lf->next) {
+    if (lf->needs_close)
+      fclose(lf->file);
+    next = lf->next;
+    free(lf);
+  }
+  logfiles = NULL;
+}
 
+void reset_logs()
+{
+  logfile_t *lf;
+  for (lf = logfiles; lf; lf = lf->next) {
+    if (lf->needs_close) {
+      fclose(lf->file);
+      lf->file = fopen(lf->filename, "a");
+    }
+  }
+}
+
+void add_stream_log(int loglevel, const char *name, FILE *stream)
+{
+  logfile_t *lf;
+  lf = tor_malloc(sizeof(logfile_t));
+  lf->filename = name;
+  lf->needs_close = 0;
+  lf->loglevel = loglevel;
+  lf->max_loglevel = LOG_EMERG;
+  lf->file = stream;
+  lf->next = logfiles;
+  logfiles = lf;
+}
+
+void add_file_log(int loglevel, const char *filename) 
+{
+  FILE *f;
+  f = fopen(filename, "a");
+  if (!f) return;
+  add_stream_log(loglevel, filename, f);
+  logfiles->needs_close = 1;
+}

Index: log.h
===================================================================
RCS file: /home/or/cvsroot/src/common/log.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- log.h	12 Aug 2003 03:16:14 -0000	1.13
+++ log.h	16 Sep 2003 17:58:36 -0000	1.14
@@ -30,6 +30,11 @@
 
 void log_set_severity(int severity);
 
+void add_stream_log(int loglevel, const char *name, FILE *stream);
+void add_file_log(int severity, const char *filename);
+void close_logs();
+void reset_logs();
+
 /* Outputs a message to stdout */
 void log(int severity, const char *format, ...) CHECK_PRINTF(2,3);
 



More information about the tor-commits mailing list