mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-23 14:40:51 +01:00
Change logging code to use fds instead of stdio. Fixes bug 861, and probably makes logging slightly faster. Not a backport candidate: bug 861 is too obscure and harmless.
svn:r17456
This commit is contained in:
parent
6221bdd294
commit
bd6b3072f9
7 changed files with 54 additions and 35 deletions
|
@ -26,6 +26,9 @@ Changes in version 0.2.1.8-alpha - 2008-??-??
|
||||||
- Build correctly on platforms without socklen_t.
|
- Build correctly on platforms without socklen_t.
|
||||||
- Avoid potential crash on internal error during signature collection.
|
- Avoid potential crash on internal error during signature collection.
|
||||||
Fixes bug 864. Patch from rovv.
|
Fixes bug 864. Patch from rovv.
|
||||||
|
- Do not use C's stdio library for writing to log files. This will
|
||||||
|
improve logging performance by a minute amount, and will stop leaking
|
||||||
|
fds when our disk is full. Fixes bug 861.
|
||||||
|
|
||||||
o Minor features:
|
o Minor features:
|
||||||
- Report the case where all signatures in a detached set are rejected
|
- Report the case where all signatures in a detached set are rejected
|
||||||
|
|
|
@ -14,7 +14,7 @@ const char log_c_id[] = "$Id$";
|
||||||
#include "orconfig.h"
|
#include "orconfig.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
// #include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
@ -23,6 +23,16 @@ const char log_c_id[] = "$Id$";
|
||||||
#ifdef HAVE_TIME_H
|
#ifdef HAVE_TIME_H
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
#include "compat.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#define LOG_PRIVATE
|
#define LOG_PRIVATE
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
@ -37,7 +47,7 @@ const char log_c_id[] = "$Id$";
|
||||||
typedef struct logfile_t {
|
typedef struct logfile_t {
|
||||||
struct logfile_t *next; /**< Next logfile_t in the linked list. */
|
struct logfile_t *next; /**< Next logfile_t in the linked list. */
|
||||||
char *filename; /**< Filename to open. */
|
char *filename; /**< Filename to open. */
|
||||||
FILE *file; /**< Stream to receive log messages. */
|
int fd; /**< fd to receive log messages, or -1 for none. */
|
||||||
int seems_dead; /**< Boolean: true if the stream seems to be kaput. */
|
int seems_dead; /**< Boolean: true if the stream seems to be kaput. */
|
||||||
int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */
|
int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */
|
||||||
int is_temporary; /**< Boolean: close after initializing logging subsystem.*/
|
int is_temporary; /**< Boolean: close after initializing logging subsystem.*/
|
||||||
|
@ -170,11 +180,9 @@ log_tor_version(logfile_t *lf, int reset)
|
||||||
if (lf->is_temporary)
|
if (lf->is_temporary)
|
||||||
/* If it's temporary, it isn't really a file. */
|
/* If it's temporary, it isn't really a file. */
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef HAVE_FTELLO
|
|
||||||
is_new = (ftello(lf->file) == 0);
|
is_new = lf->fd >= 0 && tor_fd_getpos(lf->fd) == 0;
|
||||||
#else
|
|
||||||
is_new = (ftell(lf->file) == 0);
|
|
||||||
#endif
|
|
||||||
if (reset && !is_new)
|
if (reset && !is_new)
|
||||||
/* We are resetting, but we aren't at the start of the file; no
|
/* We are resetting, but we aren't at the start of the file; no
|
||||||
* need to log again. */
|
* need to log again. */
|
||||||
|
@ -187,8 +195,7 @@ log_tor_version(logfile_t *lf, int reset)
|
||||||
tor_snprintf(buf+n, sizeof(buf)-n,
|
tor_snprintf(buf+n, sizeof(buf)-n,
|
||||||
"Tor %s opening %slog file.\n", VERSION, is_new?"new ":"");
|
"Tor %s opening %slog file.\n", VERSION, is_new?"new ":"");
|
||||||
}
|
}
|
||||||
if (fputs(buf, lf->file) == EOF ||
|
if (write_all(lf->fd, buf, strlen(buf), 0) < 0) /* error */
|
||||||
fflush(lf->file) == EOF) /* error */
|
|
||||||
return -1; /* failed */
|
return -1; /* failed */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +208,7 @@ log_tor_version(logfile_t *lf, int reset)
|
||||||
static INLINE char *
|
static INLINE char *
|
||||||
format_msg(char *buf, size_t buf_len,
|
format_msg(char *buf, size_t buf_len,
|
||||||
log_domain_mask_t domain, int severity, const char *funcname,
|
log_domain_mask_t domain, int severity, const char *funcname,
|
||||||
const char *format, va_list ap)
|
const char *format, va_list ap, size_t *msg_len_out)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
int r;
|
int r;
|
||||||
|
@ -244,6 +251,7 @@ format_msg(char *buf, size_t buf_len,
|
||||||
}
|
}
|
||||||
buf[n]='\n';
|
buf[n]='\n';
|
||||||
buf[n+1]='\0';
|
buf[n+1]='\0';
|
||||||
|
*msg_len_out = n+1;
|
||||||
return end_of_prefix;
|
return end_of_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +264,7 @@ logv(int severity, log_domain_mask_t domain, const char *funcname,
|
||||||
const char *format, va_list ap)
|
const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
char buf[10024];
|
char buf[10024];
|
||||||
|
size_t msg_len = 0;
|
||||||
int formatted = 0;
|
int formatted = 0;
|
||||||
logfile_t *lf;
|
logfile_t *lf;
|
||||||
char *end_of_prefix=NULL;
|
char *end_of_prefix=NULL;
|
||||||
|
@ -272,7 +281,7 @@ logv(int severity, log_domain_mask_t domain, const char *funcname,
|
||||||
lf = lf->next;
|
lf = lf->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (! (lf->file || lf->is_syslog || lf->callback)) {
|
if (! (lf->fd >= 0 || lf->is_syslog || lf->callback)) {
|
||||||
lf = lf->next;
|
lf = lf->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -283,7 +292,8 @@ logv(int severity, log_domain_mask_t domain, const char *funcname,
|
||||||
|
|
||||||
if (!formatted) {
|
if (!formatted) {
|
||||||
end_of_prefix =
|
end_of_prefix =
|
||||||
format_msg(buf, sizeof(buf), domain, severity, funcname, format, ap);
|
format_msg(buf, sizeof(buf), domain, severity, funcname, format, ap,
|
||||||
|
&msg_len);
|
||||||
formatted = 1;
|
formatted = 1;
|
||||||
}
|
}
|
||||||
if (lf->is_syslog) {
|
if (lf->is_syslog) {
|
||||||
|
@ -299,8 +309,7 @@ logv(int severity, log_domain_mask_t domain, const char *funcname,
|
||||||
lf = lf->next;
|
lf = lf->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fputs(buf, lf->file) == EOF ||
|
if (write_all(lf->fd, buf, msg_len, 0) < 0) { /* error */
|
||||||
fflush(lf->file) == EOF) { /* error */
|
|
||||||
/* don't log the error! mark this log entry to be blown away, and
|
/* don't log the error! mark this log entry to be blown away, and
|
||||||
* continue. */
|
* continue. */
|
||||||
lf->seems_dead = 1;
|
lf->seems_dead = 1;
|
||||||
|
@ -465,8 +474,9 @@ delete_log(logfile_t *victim)
|
||||||
static void
|
static void
|
||||||
close_log(logfile_t *victim)
|
close_log(logfile_t *victim)
|
||||||
{
|
{
|
||||||
if (victim->needs_close && victim->file) {
|
if (victim->needs_close && victim->fd >= 0) {
|
||||||
fclose(victim->file);
|
close(victim->fd);
|
||||||
|
victim->fd = -1;
|
||||||
} else if (victim->is_syslog) {
|
} else if (victim->is_syslog) {
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
if (--syslog_count == 0) {
|
if (--syslog_count == 0) {
|
||||||
|
@ -495,16 +505,16 @@ set_log_severity_config(int loglevelMin, int loglevelMax,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add a log handler named <b>name</b> to send all messages in <b>severity</b>
|
/** Add a log handler named <b>name</b> to send all messages in <b>severity</b>
|
||||||
* to <b>stream</b>. Copies <b>severity</b>. Helper: does no locking. */
|
* to <b>fd</b>. Copies <b>severity</b>. Helper: does no locking. */
|
||||||
static void
|
static void
|
||||||
add_stream_log_impl(const log_severity_list_t *severity,
|
add_stream_log_impl(const log_severity_list_t *severity,
|
||||||
const char *name, FILE *stream)
|
const char *name, int fd)
|
||||||
{
|
{
|
||||||
logfile_t *lf;
|
logfile_t *lf;
|
||||||
lf = tor_malloc_zero(sizeof(logfile_t));
|
lf = tor_malloc_zero(sizeof(logfile_t));
|
||||||
|
lf->fd = fd;
|
||||||
lf->filename = tor_strdup(name);
|
lf->filename = tor_strdup(name);
|
||||||
lf->severities = tor_memdup(severity, sizeof(log_severity_list_t));
|
lf->severities = tor_memdup(severity, sizeof(log_severity_list_t));
|
||||||
lf->file = stream;
|
|
||||||
lf->next = logfiles;
|
lf->next = logfiles;
|
||||||
|
|
||||||
logfiles = lf;
|
logfiles = lf;
|
||||||
|
@ -512,14 +522,14 @@ add_stream_log_impl(const log_severity_list_t *severity,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add a log handler named <b>name</b> to send all messages in <b>severity</b>
|
/** Add a log handler named <b>name</b> to send all messages in <b>severity</b>
|
||||||
* to <b>stream</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, FILE *stream)
|
const char *name, int fd)
|
||||||
{
|
{
|
||||||
LOCK_LOGS();
|
LOCK_LOGS();
|
||||||
add_stream_log_impl(severity, name, stream);
|
add_stream_log_impl(severity, name, fd);
|
||||||
UNLOCK_LOGS();
|
UNLOCK_LOGS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,7 +550,7 @@ add_temp_log(int min_severity)
|
||||||
log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t));
|
log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t));
|
||||||
set_log_severity_config(min_severity, LOG_ERR, s);
|
set_log_severity_config(min_severity, LOG_ERR, s);
|
||||||
LOCK_LOGS();
|
LOCK_LOGS();
|
||||||
add_stream_log_impl(s, "<temp>", stdout);
|
add_stream_log_impl(s, "<temp>", fileno(stdout));
|
||||||
tor_free(s);
|
tor_free(s);
|
||||||
logfiles->is_temporary = 1;
|
logfiles->is_temporary = 1;
|
||||||
UNLOCK_LOGS();
|
UNLOCK_LOGS();
|
||||||
|
@ -555,6 +565,7 @@ add_callback_log(const log_severity_list_t *severity, log_callback cb)
|
||||||
{
|
{
|
||||||
logfile_t *lf;
|
logfile_t *lf;
|
||||||
lf = tor_malloc_zero(sizeof(logfile_t));
|
lf = tor_malloc_zero(sizeof(logfile_t));
|
||||||
|
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("<callback>");
|
lf->filename = tor_strdup("<callback>");
|
||||||
lf->callback = cb;
|
lf->callback = cb;
|
||||||
|
@ -635,19 +646,23 @@ mark_logs_temp(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a log handler to send messages to <b>filename</b>. If opening
|
* Add a log handler to send messages to <b>filename</b>. If opening the
|
||||||
* the logfile fails, -1 is returned and errno is set appropriately
|
* logfile fails, -1 is returned and errno is set appropriately (by open(2)).
|
||||||
* (by fopen).
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
add_file_log(const log_severity_list_t *severity, const char *filename)
|
add_file_log(const log_severity_list_t *severity, const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f;
|
int fd;
|
||||||
logfile_t *lf;
|
logfile_t *lf;
|
||||||
f = fopen(filename, "a");
|
|
||||||
if (!f) return -1;
|
fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0644);
|
||||||
|
if (fd<0)
|
||||||
|
return -1;
|
||||||
|
if (tor_fd_seekend(fd)<0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
LOCK_LOGS();
|
LOCK_LOGS();
|
||||||
add_stream_log_impl(severity, filename, f);
|
add_stream_log_impl(severity, filename, fd);
|
||||||
logfiles->needs_close = 1;
|
logfiles->needs_close = 1;
|
||||||
lf = logfiles;
|
lf = logfiles;
|
||||||
_log_global_min_severity = get_min_log_level();
|
_log_global_min_severity = get_min_log_level();
|
||||||
|
@ -675,6 +690,7 @@ add_syslog_log(const log_severity_list_t *severity)
|
||||||
openlog("Tor", LOG_PID | LOG_NDELAY, LOGFACILITY);
|
openlog("Tor", LOG_PID | LOG_NDELAY, LOGFACILITY);
|
||||||
|
|
||||||
lf = tor_malloc_zero(sizeof(logfile_t));
|
lf = tor_malloc_zero(sizeof(logfile_t));
|
||||||
|
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>");
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ int parse_log_severity_config(const char **cfg,
|
||||||
void set_log_severity_config(int minSeverity, int maxSeverity,
|
void set_log_severity_config(int minSeverity, int maxSeverity,
|
||||||
log_severity_list_t *severity_out);
|
log_severity_list_t *severity_out);
|
||||||
void add_stream_log(const log_severity_list_t *severity, const char *name,
|
void add_stream_log(const log_severity_list_t *severity, const char *name,
|
||||||
FILE *stream);
|
int fd);
|
||||||
int add_file_log(const log_severity_list_t *severity, const char *filename);
|
int add_file_log(const log_severity_list_t *severity, const char *filename);
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
int add_syslog_log(const log_severity_list_t *severity);
|
int add_syslog_log(const log_severity_list_t *severity);
|
||||||
|
|
|
@ -4170,7 +4170,7 @@ options_init_logs(or_options_t *options, int validate_only)
|
||||||
err?"stderr":"stdout");
|
err?"stderr":"stdout");
|
||||||
} else {
|
} else {
|
||||||
add_stream_log(severity, err?"<stderr>":"<stdout>",
|
add_stream_log(severity, err?"<stderr>":"<stdout>",
|
||||||
err?stderr:stdout);
|
fileno(err?stderr:stdout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
@ -4479,7 +4479,7 @@ main(int c, char**v)
|
||||||
log_severity_list_t s;
|
log_severity_list_t s;
|
||||||
memset(&s, 0, sizeof(s));
|
memset(&s, 0, sizeof(s));
|
||||||
set_log_severity_config(loglevel, LOG_ERR, &s);
|
set_log_severity_config(loglevel, LOG_ERR, &s);
|
||||||
add_stream_log(&s, "", stdout);
|
add_stream_log(&s, "", fileno(stdout));
|
||||||
}
|
}
|
||||||
|
|
||||||
options->command = CMD_RUN_UNITTESTS;
|
options->command = CMD_RUN_UNITTESTS;
|
||||||
|
|
|
@ -195,7 +195,7 @@ parse_commandline(int argc, char **argv)
|
||||||
set_log_severity_config(LOG_DEBUG, LOG_ERR, &s);
|
set_log_severity_config(LOG_DEBUG, LOG_ERR, &s);
|
||||||
else
|
else
|
||||||
set_log_severity_config(LOG_WARN, LOG_ERR, &s);
|
set_log_severity_config(LOG_WARN, LOG_ERR, &s);
|
||||||
add_stream_log(&s, "<stderr>", stderr);
|
add_stream_log(&s, "<stderr>", fileno(stderr));
|
||||||
|
|
||||||
if (!identity_key_file) {
|
if (!identity_key_file) {
|
||||||
identity_key_file = tor_strdup("./authority_identity_key");
|
identity_key_file = tor_strdup("./authority_identity_key");
|
||||||
|
|
|
@ -367,7 +367,7 @@ main(int argc, char **argv)
|
||||||
set_log_severity_config(LOG_DEBUG, LOG_ERR, s);
|
set_log_severity_config(LOG_DEBUG, LOG_ERR, s);
|
||||||
else
|
else
|
||||||
set_log_severity_config(LOG_WARN, LOG_ERR, s);
|
set_log_severity_config(LOG_WARN, LOG_ERR, s);
|
||||||
add_stream_log(s, "<stderr>", stderr);
|
add_stream_log(s, "<stderr>", fileno(stderr));
|
||||||
|
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
log_debug(LD_CONFIG, "defaulting to localhost");
|
log_debug(LD_CONFIG, "defaulting to localhost");
|
||||||
|
|
Loading…
Add table
Reference in a new issue