[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Add SysLog option to direct log messages to the system log ...
- To: or-cvs@freehaven.net
- Subject: [or-cvs] Add SysLog option to direct log messages to the system log ...
- From: nickm@seul.org (Nick Mathewson)
- Date: Tue, 26 Oct 2004 17:48:43 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Tue, 26 Oct 2004 17:49:59 -0400
- Reply-to: or-dev@freehaven.net
- Sender: owner-or-cvs@freehaven.net
Update of /home/or/cvsroot/src/common
In directory moria.mit.edu:/tmp/cvs-serv9964/src/common
Modified Files:
log.c log.h util.c
Log Message:
Add SysLog option to direct log messages to the system log instead of a FILE*.
Index: log.c
===================================================================
RCS file: /home/or/cvsroot/src/common/log.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- log.c 16 Oct 2004 22:28:11 -0000 1.54
+++ log.c 26 Oct 2004 21:48:40 -0000 1.55
@@ -34,6 +34,7 @@
int loglevel; /**< Lowest severity level to send to this stream. */
int max_loglevel; /**< Highest severity level to send to this stream. */
int is_temporary; /**< Boolean: close after initializing logging subsystem.*/
+ int is_syslog; /**< Boolean: send messages to syslog. */
} logfile_t;
/** Helper: map a log severity to descriptive string. */
@@ -50,8 +51,13 @@
/** Linked list of logfile_t. */
static logfile_t *logfiles = NULL;
+#ifdef HAVE_SYSLOG_H
+static int syslog_count = 0;
+#endif
static void delete_log(logfile_t *victim);
+static void close_log(logfile_t *victim);
+static int reset_log(logfile_t *lf);
static INLINE size_t
_log_prefix(char *buf, size_t buf_len, int severity)
@@ -104,16 +110,19 @@
/** Helper: Format a log message into a fixed-sized buffer. (This is
* factored out of <b>logv</b> so that we never format a message more
- * than once.)
+ * than once.) Return a pointer to the first character of the message
+ * portion of the formatted string.
*/
-static INLINE void format_msg(char *buf, size_t buf_len,
+static INLINE char *format_msg(char *buf, size_t buf_len,
int severity, const char *funcname,
const char *format, va_list ap)
{
size_t n;
+ char *end_of_prefix;
buf_len -= 2; /* subtract 2 characters so we have room for \n\0 */
n = _log_prefix(buf, buf_len, severity);
+ end_of_prefix = buf+n;
if (funcname) {
n += snprintf(buf+n, buf_len-n, "%s(): ", funcname);
@@ -128,6 +137,7 @@
}
buf[n]='\n';
buf[n+1]='\0';
+ return end_of_prefix;
}
/** Helper: sends a message to the appropriate logfiles, at loglevel
@@ -140,23 +150,32 @@
char buf[10024];
int formatted = 0;
logfile_t *lf;
+ char *end_of_prefix=NULL;
assert(format);
lf = logfiles;
while(lf) {
- if (severity < lf->loglevel || severity > lf->max_loglevel) {
+ if (severity > lf->loglevel || severity < lf->max_loglevel) {
lf = lf->next;
continue;
}
- if (!lf->file) {
+ if (! (lf->file || lf->is_syslog)) {
lf = lf->next;
continue;
}
if (!formatted) {
- format_msg(buf, sizeof(buf), severity, funcname, format, ap);
+ end_of_prefix =
+ format_msg(buf, sizeof(buf), severity, funcname, format, ap);
formatted = 1;
}
+ if (lf->is_syslog) {
+#ifdef HAVE_SYSLOG_H
+ syslog(severity, "%s", end_of_prefix);
+#endif
+ lf = lf->next;
+ continue;
+ }
if(fputs(buf, lf->file) == EOF ||
fflush(lf->file) == EOF) { /* error */
/* don't log the error! Blow away this log entry and continue. */
@@ -194,8 +213,7 @@
while(logfiles) {
victim = logfiles;
logfiles = logfiles->next;
- if (victim->needs_close)
- fclose(victim->file);
+ close_log(victim);
tor_free(victim->filename);
tor_free(victim);
}
@@ -206,17 +224,12 @@
{
logfile_t *lf = logfiles;
while(lf) {
- if (lf->needs_close) {
- if(fclose(lf->file)==EOF ||
- !(lf->file = fopen(lf->filename, "a"))) {
- /* error. don't log it. delete the log entry and continue. */
- logfile_t *victim = lf;
- lf = victim->next;
- delete_log(victim);
- continue;
- } else {
- log_tor_version(lf, 1);
- }
+ if (reset_log(lf)) {
+ /* error. don't log it. delete the log entry and continue. */
+ logfile_t *victim = lf;
+ lf = victim->next;
+ delete_log(victim);
+ continue;
}
lf = lf->next;
}
@@ -241,19 +254,43 @@
tor_free(victim);
}
+static void close_log(logfile_t *victim)
+{
+ if (victim->needs_close && victim->file) {
+ fclose(victim->file);
+ } else if (victim->is_syslog) {
+#ifdef HAVE_SYSLOG_H
+ if (--syslog_count == 0)
+ /* There are no other syslogs; close the logging facility. */
+ closelog();
+#endif
+ }
+}
+
+static int reset_log(logfile_t *lf)
+{
+ if (lf->needs_close) {
+ if(fclose(lf->file)==EOF ||
+ !(lf->file = fopen(lf->filename, "a"))) {
+ return -1;
+ } else {
+ log_tor_version(lf, 1);
+ }
+ }
+ return 0;
+}
+
/** Add a log handler to send all messages of severity <b>loglevel</b>
* or higher to <b>stream</b>. */
void add_stream_log(int loglevelMin, int loglevelMax, const char *name, FILE *stream)
{
logfile_t *lf;
- lf = tor_malloc(sizeof(logfile_t));
+ lf = tor_malloc_zero(sizeof(logfile_t));
lf->filename = tor_strdup(name);
- lf->needs_close = 0;
lf->loglevel = loglevelMin;
lf->max_loglevel = loglevelMax;
lf->file = stream;
lf->next = logfiles;
- lf->is_temporary = 0;
logfiles = lf;
}
@@ -266,6 +303,7 @@
logfiles->is_temporary = 1;
}
+/** Close any log handlers added by add_temp_log or marked by mark_logs_temp */
void close_temp_logs(void)
{
logfile_t *lf, **p;
@@ -273,8 +311,7 @@
if ((*p)->is_temporary) {
lf = *p;
*p = (*p)->next;
- if (lf->needs_close)
- fclose(lf->file);
+ close_log(lf);
tor_free(lf->filename);
tor_free(lf);
} else {
@@ -283,6 +320,7 @@
}
}
+/** Configure all log handles to be closed by close_temp_logs */
void mark_logs_temp(void)
{
logfile_t *lf;
@@ -306,6 +344,28 @@
return 0;
}
+#ifdef HAVE_SYSLOG_H
+/**
+ * Add a log handler to send messages to they system log facility.
+ */
+int add_syslog_log(int loglevelMin, int loglevelMax)
+{
+ logfile_t *lf;
+ if (syslog_count++ == 0)
+ /* This is the the first syslog. */
+ openlog("Tor", LOG_NDELAY, LOG_DAEMON);
+
+ lf = tor_malloc_zero(sizeof(logfile_t));
+ lf->loglevel = loglevelMin;
+ lf->filename = tor_strdup("<syslog>");
+ lf->max_loglevel = loglevelMax;
+ lf->is_syslog = 1;
+ lf->next = logfiles;
+ logfiles = lf;
+ return 0;
+}
+#endif
+
/** If <b>level</b> is a valid log severity, return the corresponding
* numeric value. Otherwise, return -1. */
int parse_log_level(const char *level) {
@@ -327,7 +387,7 @@
logfile_t *lf;
int min = LOG_ERR;
for (lf = logfiles; lf; lf = lf->next) {
- if (lf->loglevel < min)
+ if (lf->loglevel > min)
min = lf->loglevel;
}
return min;
Index: log.h
===================================================================
RCS file: /home/or/cvsroot/src/common/log.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- log.h 2 Jun 2004 19:18:37 -0000 1.28
+++ log.h 26 Oct 2004 21:48:41 -0000 1.29
@@ -18,24 +18,37 @@
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#define LOG_WARN LOG_WARNING
+#if LOG_DEBUG < LOG_ERR
+#error "Your syslog.h thinks high numbers are more important. We aren't prepared to deal with that."
+#endif
#else
+/* XXXX Note: The code was originally written to refer to severities,
+ * with 0 being the least severe; while syslog's logging code refers to
+ * priorities, with 0 being the most important. Thus, all our comparisons
+ * needed to be reversed when we added syslog support.
+ *
+ * The upshot of this is that comments about log levels may be messed
+ * up: for "maximum severity" read "most severe" and "numerically
+ * *lowest* severity".
+ */
+
/** Debug-level severity: for hyper-verbose messages of no interest to
* anybody but developers. */
-#define LOG_DEBUG 0
+#define LOG_DEBUG 7
/** Info-level severity: for messages that appear frequently during normal
* operation. */
-#define LOG_INFO 1
+#define LOG_INFO 6
/** Notice-level severity: for messages that appear infrequently
* during normal operation; that the user will probably care about;
* and that are not errors.
*/
-#define LOG_NOTICE 2
+#define LOG_NOTICE 5
/** Warn-level severity: for messages that only appear when something has gone
* wrong. */
-#define LOG_WARN 3
+#define LOG_WARN 4
/** Error-level severity: for messages that only appear when something has gone
* very wrong, and the Tor process can no longer proceed. */
-#define LOG_ERR 4
+#define LOG_ERR 3
#endif
/* magic to make GCC check for proper format strings. */
@@ -49,9 +62,12 @@
int parse_log_level(const char *level);
void add_stream_log(int severityMin, int severityMax, const char *name, FILE *stream);
int add_file_log(int severityMin, int severityMax, const char *filename);
+#ifdef HAVE_SYSLOG_H
+int add_syslog_log(int loglevelMin, int loglevelMax);
+#endif
int get_min_log_level(void);
-void close_logs();
-void reset_logs();
+void close_logs(void);
+void reset_logs(void);
void add_temp_log(void);
void close_temp_logs(void);
void mark_logs_temp(void);
Index: util.c
===================================================================
RCS file: /home/or/cvsroot/src/common/util.c,v
retrieving revision 1.151
retrieving revision 1.152
diff -u -d -r1.151 -r1.152
--- util.c 16 Oct 2004 22:56:03 -0000 1.151
+++ util.c 26 Oct 2004 21:48:41 -0000 1.152
@@ -1740,13 +1740,17 @@
while(*value && isspace((int)*value))
value++;
+#if 0
if(!*end || !*value) { /* only a key on this line. no value. */
*end = 0;
log_fn(LOG_WARN,"Line has keyword '%s' but no value. Failing.",key);
return -1;
}
+#endif
*end = 0; /* null it out */
+ tor_assert(key);
+ tor_assert(value);
log_fn(LOG_DEBUG,"got keyword '%s', value '%s'", key, value);
*key_out = key, *value_out = value;
return 1;