Loading changes/log_domains 0 → 100644 +12 −0 Changes for changes/log_domains: 12 added lines, 0 removed lines. Original line number Original line Diff line number Diff line o Minor features - 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 "[~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 - Add documentation for configuring logging at different severities in different log domains. We've had this feature since 0.2.1.1-alpha, but for some reason it never made it into the manpage. Fixes bug 2215. doc/tor.1.txt +28 −0 Changes for doc/tor.1.txt: 28 added lines, 0 removed lines. Original line number Original line Diff line number Diff line Loading @@ -323,6 +323,34 @@ Other options can be specified either on the command-line (--option Messages are sent to all the logs that match their severity Messages are sent to all the logs that match their severity level. level. **Log** **[**__domain__,...**]**__minSeverity__[-__maxSeverity__] ... **file** __FILENAME__ + **Log** **[**__domain__,...**]**__minSeverity__[-__maxSeverity__] ... **stderr**|**stdout**|**syslog** :: As above, but select messages by range of log severity __and__ by a set of "logging domains". Each logging domain corresponds to an area of functionality inside Tor. You can specify any number of severity ranges for a single log statement, each of them prefixed by a comma-separated list of logging domains. You can prefix a domain with ~ to indicate negation, and use * to indicate "all domains". If you specify a severity range without a list of domains, it matches all domains. + + This is an advanced feature which is most useful for debugging one or two of Tor's subsystems at a time. + + The currently recognized domains are: general, crypto, net, config, fs, protocol, mm, http, app, control, circ, rend, bug, dir, dirserv, or, edge, acct, hist, and handshake. Domain names are case-insensitive. + + For example, "`Log [handshake]debug [~net,~mm]info notice stdout`" sends to stdout: all handshake messages of any severity, all info-and-higher messages from domains other than networking and memory management, and all 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 Loading src/common/log.c +75 −13 Changes for src/common/log.c: 75 added lines, 13 removed lines. Original line number Original line Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -217,13 +223,34 @@ format_msg(char *buf, size_t buf_len, size_t n; size_t n; int r; int r; char *end_of_prefix; char *end_of_prefix; char *buf_end; 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 */ buf_end = buf+buf_len; /* point *after* the last char we can write to */ 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; if (cp == buf_end) goto format_msg_no_room_for_domains; *cp++ = '{'; if (cp == buf_end) goto format_msg_no_room_for_domains; cp = domain_to_string(domain, cp, (buf+buf_len-cp)); if (cp == buf_end) goto format_msg_no_room_for_domains; *cp++ = '}'; if (cp == buf_end) goto format_msg_no_room_for_domains; *cp++ = ' '; if (cp == buf_end) goto format_msg_no_room_for_domains; end_of_prefix = cp; n = cp-buf; format_msg_no_room_for_domains: /* This will leave end_of_prefix and n unchanged, and thus cause * whatever log domain string we had written to be clobbered. */ ; } 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) Loading Loading @@ -305,6 +332,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; Loading Loading @@ -563,8 +591,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, add_stream_log(const log_severity_list_t *severity, const char *name, int fd) const char *name, int fd) { { LOCK_LOGS(); LOCK_LOGS(); add_stream_log_impl(severity, name, fd); add_stream_log_impl(severity, name, fd); Loading @@ -583,6 +610,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). */ */ Loading Loading @@ -775,7 +812,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(); Loading Loading @@ -832,18 +868,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 /** Translate a bitmask of log domains to a string. */ * is undecodable. */ static char * static const char * domain_to_string(log_domain_mask_t domain, char *buf, size_t buflen) domain_to_string(log_domain_mask_t domain) { { char *cp = buf; char *eos = buf+buflen; buf[0] = '\0'; if (! domain) return buf; while (1) { const char *d; int bit = tor_log2(domain); int bit = tor_log2(domain); if ((bit == 0 && domain == 0) || bit >= N_LOGGING_DOMAINS) size_t n; return NULL; if (bit >= N_LOGGING_DOMAINS) { return domain_list[bit]; 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 Loading Loading @@ -919,6 +978,9 @@ parse_log_severity_config(const char **cfg_ptr, smartlist_free(domains_list); smartlist_free(domains_list); if (err) if (err) return -1; return -1; if (domains == 0 && neg_domains) domains = ~neg_domains; else domains &= ~neg_domains; domains &= ~neg_domains; cfg = eat_whitespace(closebracket+1); cfg = eat_whitespace(closebracket+1); } else { } else { Loading src/common/torlog.h +1 −0 Changes for src/common/torlog.h: 1 added line, 0 removed lines. Original line number Original line Diff line number Diff line Loading @@ -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); Loading src/or/config.c +6 −1 Changes for src/or/config.c: 6 added lines, 1 removed line. Original line number Original line Diff line number Diff line Loading @@ -288,6 +288,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"), Loading Loading @@ -3817,7 +3818,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. */ Loading Loading @@ -4393,6 +4395,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; } } Loading Loading
changes/log_domains 0 → 100644 +12 −0 Changes for changes/log_domains: 12 added lines, 0 removed lines. Original line number Original line Diff line number Diff line o Minor features - 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 "[~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 - Add documentation for configuring logging at different severities in different log domains. We've had this feature since 0.2.1.1-alpha, but for some reason it never made it into the manpage. Fixes bug 2215.
doc/tor.1.txt +28 −0 Changes for doc/tor.1.txt: 28 added lines, 0 removed lines. Original line number Original line Diff line number Diff line Loading @@ -323,6 +323,34 @@ Other options can be specified either on the command-line (--option Messages are sent to all the logs that match their severity Messages are sent to all the logs that match their severity level. level. **Log** **[**__domain__,...**]**__minSeverity__[-__maxSeverity__] ... **file** __FILENAME__ + **Log** **[**__domain__,...**]**__minSeverity__[-__maxSeverity__] ... **stderr**|**stdout**|**syslog** :: As above, but select messages by range of log severity __and__ by a set of "logging domains". Each logging domain corresponds to an area of functionality inside Tor. You can specify any number of severity ranges for a single log statement, each of them prefixed by a comma-separated list of logging domains. You can prefix a domain with ~ to indicate negation, and use * to indicate "all domains". If you specify a severity range without a list of domains, it matches all domains. + + This is an advanced feature which is most useful for debugging one or two of Tor's subsystems at a time. + + The currently recognized domains are: general, crypto, net, config, fs, protocol, mm, http, app, control, circ, rend, bug, dir, dirserv, or, edge, acct, hist, and handshake. Domain names are case-insensitive. + + For example, "`Log [handshake]debug [~net,~mm]info notice stdout`" sends to stdout: all handshake messages of any severity, all info-and-higher messages from domains other than networking and memory management, and all 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 Loading
src/common/log.c +75 −13 Changes for src/common/log.c: 75 added lines, 13 removed lines. Original line number Original line Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -217,13 +223,34 @@ format_msg(char *buf, size_t buf_len, size_t n; size_t n; int r; int r; char *end_of_prefix; char *end_of_prefix; char *buf_end; 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 */ buf_end = buf+buf_len; /* point *after* the last char we can write to */ 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; if (cp == buf_end) goto format_msg_no_room_for_domains; *cp++ = '{'; if (cp == buf_end) goto format_msg_no_room_for_domains; cp = domain_to_string(domain, cp, (buf+buf_len-cp)); if (cp == buf_end) goto format_msg_no_room_for_domains; *cp++ = '}'; if (cp == buf_end) goto format_msg_no_room_for_domains; *cp++ = ' '; if (cp == buf_end) goto format_msg_no_room_for_domains; end_of_prefix = cp; n = cp-buf; format_msg_no_room_for_domains: /* This will leave end_of_prefix and n unchanged, and thus cause * whatever log domain string we had written to be clobbered. */ ; } 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) Loading Loading @@ -305,6 +332,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; Loading Loading @@ -563,8 +591,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, add_stream_log(const log_severity_list_t *severity, const char *name, int fd) const char *name, int fd) { { LOCK_LOGS(); LOCK_LOGS(); add_stream_log_impl(severity, name, fd); add_stream_log_impl(severity, name, fd); Loading @@ -583,6 +610,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). */ */ Loading Loading @@ -775,7 +812,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(); Loading Loading @@ -832,18 +868,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 /** Translate a bitmask of log domains to a string. */ * is undecodable. */ static char * static const char * domain_to_string(log_domain_mask_t domain, char *buf, size_t buflen) domain_to_string(log_domain_mask_t domain) { { char *cp = buf; char *eos = buf+buflen; buf[0] = '\0'; if (! domain) return buf; while (1) { const char *d; int bit = tor_log2(domain); int bit = tor_log2(domain); if ((bit == 0 && domain == 0) || bit >= N_LOGGING_DOMAINS) size_t n; return NULL; if (bit >= N_LOGGING_DOMAINS) { return domain_list[bit]; 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 Loading Loading @@ -919,6 +978,9 @@ parse_log_severity_config(const char **cfg_ptr, smartlist_free(domains_list); smartlist_free(domains_list); if (err) if (err) return -1; return -1; if (domains == 0 && neg_domains) domains = ~neg_domains; else domains &= ~neg_domains; domains &= ~neg_domains; cfg = eat_whitespace(closebracket+1); cfg = eat_whitespace(closebracket+1); } else { } else { Loading
src/common/torlog.h +1 −0 Changes for src/common/torlog.h: 1 added line, 0 removed lines. Original line number Original line Diff line number Diff line Loading @@ -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); Loading
src/or/config.c +6 −1 Changes for src/or/config.c: 6 added lines, 1 removed line. Original line number Original line Diff line number Diff line Loading @@ -288,6 +288,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"), Loading Loading @@ -3817,7 +3818,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. */ Loading Loading @@ -4393,6 +4395,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; } } Loading