Browse Source

Add a torrc option to report log domains

Nick Mathewson 14 years ago
parent
commit
89ee779f92
6 changed files with 80 additions and 15 deletions
  1. 3 0
      changes/log_domains
  2. 5 0
      doc/tor.1.txt
  3. 62 14
      src/common/log.c
  4. 1 0
      src/common/torlog.h
  5. 6 1
      src/or/config.c
  6. 3 0
      src/or/or.h

+ 3 - 0
changes/log_domains

@@ -2,6 +2,9 @@
     - Make it simpler to specify "All log domains except for A and B".
     - Make it simpler to specify "All log domains except for A and B".
       Previously you needed to say "[*,~A,~B]".  Now you can just say
       Previously you needed to say "[*,~A,~B]".  Now you can just say
       "[~A,~B]".
       "[~A,~B]".
+    - Add a LogMessageDomains option to include the domains of log messages
+      along with the messages.  Without this, there's no way to use
+      log domains without reading the source or doing a lot of guessing
 
 
   o Documentation
   o Documentation
     - Add documentation for configuring logging at different severities in
     - Add documentation for configuring logging at different severities in

+ 5 - 0
doc/tor.1.txt

@@ -346,6 +346,11 @@ Other options can be specified either on the command-line (--option
     messages from domains other than networking and memory management, and all
     messages from domains other than networking and memory management, and all
     messages of severity notice or higher.
     messages of severity notice or higher.
 
 
+**LogMessageDomains** **0**|**1**::
+    If 1, Tor includes message domains with each log message.  Every log
+    message currently has at least one domain; most currently have exactly
+    one.  This doesn't affect controller log messages. (Default: 0)
+
 **OutboundBindAddress** __IP__::
 **OutboundBindAddress** __IP__::
     Make all outbound connections originate from the IP address specified. This
     Make all outbound connections originate from the IP address specified. This
     is only useful when you have multiple network interfaces, and you want all
     is only useful when you have multiple network interfaces, and you want all

+ 62 - 14
src/common/log.c

@@ -97,6 +97,9 @@ static int log_mutex_initialized = 0;
 
 
 /** Linked list of logfile_t. */
 /** Linked list of logfile_t. */
 static logfile_t *logfiles = NULL;
 static logfile_t *logfiles = NULL;
+/** Boolean: do we report logging domains? */
+static int log_domains_are_logged = 0;
+
 #ifdef HAVE_SYSLOG_H
 #ifdef HAVE_SYSLOG_H
 /** The number of open syslog log handlers that we have.  When this reaches 0,
 /** The number of open syslog log handlers that we have.  When this reaches 0,
  * we can close our connection to the syslog facility. */
  * we can close our connection to the syslog facility. */
@@ -126,6 +129,9 @@ int _log_global_min_severity = LOG_NOTICE;
 static void delete_log(logfile_t *victim);
 static void delete_log(logfile_t *victim);
 static void close_log(logfile_t *victim);
 static void close_log(logfile_t *victim);
 
 
+static char *domain_to_string(log_domain_mask_t domain,
+                             char *buf, size_t buflen);
+
 /** Name of the application: used to generate the message we write at the
 /** Name of the application: used to generate the message we write at the
  * start of each new log. */
  * start of each new log. */
 static char *appname = NULL;
 static char *appname = NULL;
@@ -218,12 +224,22 @@ format_msg(char *buf, size_t buf_len,
   int r;
   int r;
   char *end_of_prefix;
   char *end_of_prefix;
 
 
-  assert(buf_len >= 2); /* prevent integer underflow */
+  assert(buf_len >= 16); /* prevent integer underflow and general stupidity */
   buf_len -= 2; /* subtract 2 characters so we have room for \n\0 */
   buf_len -= 2; /* subtract 2 characters so we have room for \n\0 */
 
 
   n = _log_prefix(buf, buf_len, severity);
   n = _log_prefix(buf, buf_len, severity);
   end_of_prefix = buf+n;
   end_of_prefix = buf+n;
 
 
+  if (log_domains_are_logged) {
+    char *cp = buf+n;
+    *cp++ = '{';
+    cp = domain_to_string(domain, cp, (buf+buf_len-cp));
+    *cp++ = '}';
+    *cp++ = ' ';
+    end_of_prefix = cp;
+    n = cp-buf;
+  }
+
   if (funcname && should_log_function_name(domain, severity)) {
   if (funcname && should_log_function_name(domain, severity)) {
     r = tor_snprintf(buf+n, buf_len-n, "%s(): ", funcname);
     r = tor_snprintf(buf+n, buf_len-n, "%s(): ", funcname);
     if (r<0)
     if (r<0)
@@ -305,6 +321,7 @@ logv(int severity, log_domain_mask_t domain, const char *funcname,
                    &msg_len);
                    &msg_len);
       formatted = 1;
       formatted = 1;
     }
     }
+
     if (lf->is_syslog) {
     if (lf->is_syslog) {
 #ifdef HAVE_SYSLOG_H
 #ifdef HAVE_SYSLOG_H
       char *m = end_of_prefix;
       char *m = end_of_prefix;
@@ -563,8 +580,7 @@ add_stream_log_impl(const log_severity_list_t *severity,
  * to <b>fd</b>. Steals a reference to <b>severity</b>; the caller must
  * to <b>fd</b>. Steals a reference to <b>severity</b>; the caller must
  * not use it after calling this function. */
  * not use it after calling this function. */
 void
 void
-add_stream_log(const log_severity_list_t *severity,
-               const char *name, int fd)
+add_stream_log(const log_severity_list_t *severity, const char *name, int fd)
 {
 {
   LOCK_LOGS();
   LOCK_LOGS();
   add_stream_log_impl(severity, name, fd);
   add_stream_log_impl(severity, name, fd);
@@ -583,6 +599,16 @@ init_logging(void)
     pending_cb_messages = smartlist_create();
     pending_cb_messages = smartlist_create();
 }
 }
 
 
+/** Set whether we report logging domains as a part of our log messages.
+ */
+void
+logs_set_domain_logging(int enabled)
+{
+  LOCK_LOGS();
+  log_domains_are_logged = enabled;
+  UNLOCK_LOGS();
+}
+
 /** Add a log handler to receive messages during startup (before the real
 /** Add a log handler to receive messages during startup (before the real
  * logs are initialized).
  * logs are initialized).
  */
  */
@@ -775,7 +801,6 @@ add_syslog_log(const log_severity_list_t *severity)
   lf->fd = -1;
   lf->fd = -1;
   lf->severities = tor_memdup(severity, sizeof(log_severity_list_t));
   lf->severities = tor_memdup(severity, sizeof(log_severity_list_t));
   lf->filename = tor_strdup("<syslog>");
   lf->filename = tor_strdup("<syslog>");
-
   lf->is_syslog = 1;
   lf->is_syslog = 1;
 
 
   LOCK_LOGS();
   LOCK_LOGS();
@@ -832,18 +857,41 @@ parse_log_domain(const char *domain)
   }
   }
   return 0;
   return 0;
 }
 }
-#if 0
-/** Translate a bitmask of log domains to a string, or NULL if the bitmask
- * is undecodable. */
-static const char *
-domain_to_string(log_domain_mask_t domain)
+
+/** Translate a bitmask of log domains to a string. */
+static char *
+domain_to_string(log_domain_mask_t domain, char *buf, size_t buflen)
 {
 {
-  int bit = tor_log2(domain);
-  if ((bit == 0 && domain == 0) || bit >= N_LOGGING_DOMAINS)
-    return NULL;
-  return domain_list[bit];
+  char *cp = buf;
+  char *eos = buf+buflen;
+
+  buf[0] = '\0';
+  if (! domain)
+    return buf;
+  while (1) {
+    const char *d;
+    int bit = tor_log2(domain);
+    size_t n;
+    if (bit >= N_LOGGING_DOMAINS) {
+      tor_snprintf(buf, buflen, "<BUG:Unknown domain %lx>", (long)domain);
+      return buf+strlen(buf);
+    }
+    d = domain_list[bit];
+    n = strlcpy(cp, d, eos-cp);
+    if (n >= buflen) {
+      tor_snprintf(buf, buflen, "<BUG:Truncating domain %lx>", (long)domain);
+      return buf+strlen(buf);
+    }
+    cp += n;
+    domain &= ~(1<<bit);
+
+    if (domain == 0 || (eos-cp) < 2)
+      return cp;
+
+    memcpy(cp, ",", 2); /*Nul-terminated ,"*/
+    cp++;
+  }
 }
 }
-#endif
 
 
 /** Parse a log severity pattern in *<b>cfg_ptr</b>.  Advance cfg_ptr after
 /** Parse a log severity pattern in *<b>cfg_ptr</b>.  Advance cfg_ptr after
  * the end of the severityPattern.  Set the value of <b>severity_out</b> to
  * the end of the severityPattern.  Set the value of <b>severity_out</b> to

+ 1 - 0
src/common/torlog.h

@@ -132,6 +132,7 @@ int add_file_log(const log_severity_list_t *severity, const char *filename);
 int add_syslog_log(const log_severity_list_t *severity);
 int add_syslog_log(const log_severity_list_t *severity);
 #endif
 #endif
 int add_callback_log(const log_severity_list_t *severity, log_callback cb);
 int add_callback_log(const log_severity_list_t *severity, log_callback cb);
+void logs_set_domain_logging(int enabled);
 int get_min_log_level(void);
 int get_min_log_level(void);
 void switch_logs_debug(void);
 void switch_logs_debug(void);
 void logs_free_all(void);
 void logs_free_all(void);

+ 6 - 1
src/or/config.c

@@ -287,6 +287,7 @@ static config_var_t _option_vars[] = {
   OBSOLETE("IgnoreVersion"),
   OBSOLETE("IgnoreVersion"),
   V(KeepalivePeriod,             INTERVAL, "5 minutes"),
   V(KeepalivePeriod,             INTERVAL, "5 minutes"),
   VAR("Log",                     LINELIST, Logs,             NULL),
   VAR("Log",                     LINELIST, Logs,             NULL),
+  V(LogMessageDomains,           BOOL,     "0"),
   OBSOLETE("LinkPadding"),
   OBSOLETE("LinkPadding"),
   OBSOLETE("LogLevel"),
   OBSOLETE("LogLevel"),
   OBSOLETE("LogFile"),
   OBSOLETE("LogFile"),
@@ -3811,7 +3812,8 @@ options_transition_affects_workers(or_options_t *old_options,
       old_options->SafeLogging != new_options->SafeLogging ||
       old_options->SafeLogging != new_options->SafeLogging ||
       old_options->ClientOnly != new_options->ClientOnly ||
       old_options->ClientOnly != new_options->ClientOnly ||
       public_server_mode(old_options) != public_server_mode(new_options) ||
       public_server_mode(old_options) != public_server_mode(new_options) ||
-      !config_lines_eq(old_options->Logs, new_options->Logs))
+      !config_lines_eq(old_options->Logs, new_options->Logs) ||
+      old_options->LogMessageDomains != new_options->LogMessageDomains)
     return 1;
     return 1;
 
 
   /* Check whether log options match. */
   /* Check whether log options match. */
@@ -4387,6 +4389,9 @@ options_init_logs(or_options_t *options, int validate_only)
   }
   }
   smartlist_free(elts);
   smartlist_free(elts);
 
 
+  if (ok && !validate_only)
+    logs_set_domain_logging(options->LogMessageDomains);
+
   return ok?0:-1;
   return ok?0:-1;
 }
 }
 
 

+ 3 - 0
src/or/or.h

@@ -2338,6 +2338,9 @@ typedef struct {
   config_line_t *Logs; /**< New-style list of configuration lines
   config_line_t *Logs; /**< New-style list of configuration lines
                         * for logs */
                         * for logs */
 
 
+  int LogMessageDomains; /**< Boolean: Should we log the domain(s) in which
+                          * each log message occurs? */
+
   char *DebugLogFile; /**< Where to send verbose log messages. */
   char *DebugLogFile; /**< Where to send verbose log messages. */
   char *DataDirectory; /**< OR only: where to store long-term data. */
   char *DataDirectory; /**< OR only: where to store long-term data. */
   char *Nickname; /**< OR only: nickname of this onion router. */
   char *Nickname; /**< OR only: nickname of this onion router. */