]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Add backend support for multiple logfiles, including console logs.
authorNick Mathewson <nickm@torproject.org>
Tue, 16 Sep 2003 17:58:36 +0000 (17:58 +0000)
committerNick Mathewson <nickm@torproject.org>
Tue, 16 Sep 2003 17:58:36 +0000 (17:58 +0000)
Also optimize logging by formatting messages in memory before sending
them through stdio.  (It turns out (according to gprof) that logging
performance matters.)

svn:r463

src/common/log.c
src/common/log.h

index f38089a40f190bc1965261f5583c4158106ca33e..c4a5e683c906f59a2f0553dba8c32d53a63e128e 100644 (file)
@@ -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 const char *sev_to_string(int severity) {
 }
 
 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 @@ void _log_fn(int severity, const char *fn, const char *format, ...)
   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 38f330c08124d3573d71c17ea2fd134e2ed77ede..9b9d072eec8878ec8eb85d1cd9fa71afe09ee6d5 100644 (file)
 
 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);