From adcc83d26fbd6b29520bbea0eafb893b2eb83a84 Mon Sep 17 00:00:00 2001 From: Jan Kneschke Date: Tue, 26 Jul 2005 08:26:28 +0000 Subject: [PATCH] cleaned up the errorlog writing, default is now stderr, syslog is requested explicitly git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.3.x@475 152afb58-edef-0310-8abb-c4023f1b3aa9 --- src/base.h | 15 +++-- src/config.c | 5 +- src/log.c | 138 ++++++++++++++++++++++++-------------------- src/mod_accesslog.c | 7 --- src/mod_cgi.c | 11 +++- src/mod_rrdtool.c | 7 ++- src/server.c | 13 ++--- 7 files changed, 109 insertions(+), 87 deletions(-) diff --git a/src/base.h b/src/base.h index 9081d7e6..66d52fcd 100644 --- a/src/base.h +++ b/src/base.h @@ -407,13 +407,15 @@ typedef struct { typedef struct { unsigned short port; buffer *bindhost; - buffer *error_logfile; + + buffer *errorlog_file; + unsigned short errorlog_use_syslog; + unsigned short dont_daemonize; buffer *changeroot; buffer *username; buffer *groupname; - buffer *license; buffer *pid_file; buffer *event_handler; @@ -455,13 +457,17 @@ typedef struct { typedef struct { server_socket_array srv_sockets; - int log_error_fd; - int log_using_syslog; + /* the errorlog */ + int errorlog_fd; + enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode; + buffer *errorlog_buf; + fdevents *ev, *ev_ins; buffer_plugin plugins; void *plugin_slots; + /* counters */ int con_opened; int con_read; int con_written; @@ -477,7 +483,6 @@ typedef struct { /* buffers */ buffer *parse_full_path; buffer *response_header; - buffer *error_log; buffer *response_range; buffer *tmp_buf; diff --git a/src/config.c b/src/config.c index aa7bafcc..42f11d53 100644 --- a/src/config.c +++ b/src/config.c @@ -76,6 +76,7 @@ static int config_insert(server *srv) { { "dir-listing.external-css", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 40 */ { "dir-listing.encoding", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 41 */ + { "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 42 */ { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, @@ -92,7 +93,7 @@ static int config_insert(server *srv) { /* 0 */ cv[0].destination = srv->srvconf.bindhost; - cv[1].destination = srv->srvconf.error_logfile; + cv[1].destination = srv->srvconf.errorlog_file; cv[3].destination = srv->srvconf.changeroot; cv[4].destination = srv->srvconf.username; cv[5].destination = srv->srvconf.groupname; @@ -107,6 +108,8 @@ static int config_insert(server *srv) { cv[36].destination = &(srv->srvconf.log_request_header_on_error); cv[37].destination = &(srv->srvconf.log_state_handling); + cv[42].destination = &(srv->srvconf.errorlog_use_syslog); + srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); assert(srv->config_storage); diff --git a/src/log.c b/src/log.c index 7d7a3331..11f7701b 100644 --- a/src/log.c +++ b/src/log.c @@ -32,8 +32,12 @@ /** * open the errorlog * + * we have 3 possibilities: + * - stderr (default) + * - syslog + * - logfile + * * if the open failed, report to the user and die - * if no filename is given, use syslog instead * */ @@ -41,10 +45,18 @@ int log_error_open(server *srv) { int fd; int close_stderr = 1; - if (srv->srvconf.error_logfile->used) { - const char *logfile = srv->srvconf.error_logfile->ptr; +#ifdef HAVE_SYSLOG_H + /* perhaps someone wants to use syslog() */ + openlog("lighttpd", LOG_CONS | LOG_PID, LOG_DAEMON); +#endif + srv->errorlog_mode = ERRORLOG_STDERR; + + if (srv->srvconf.errorlog_use_syslog) { + srv->errorlog_mode = ERRORLOG_SYSLOG; + } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) { + const char *logfile = srv->srvconf.errorlog_file->ptr; - if (-1 == (srv->log_error_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { + if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { log_error_write(srv, __FILE__, __LINE__, "SSSS", "opening errorlog '", logfile, "' failed: ", strerror(errno)); @@ -53,15 +65,9 @@ int log_error_open(server *srv) { } #ifdef FD_CLOEXEC /* close fd on exec (cgi) */ - fcntl(srv->log_error_fd, F_SETFD, FD_CLOEXEC); -#endif - } else { - srv->log_error_fd = -1; -#ifdef HAVE_SYSLOG_H - /* syslog-mode */ - srv->log_using_syslog = 1; - openlog("lighttpd", LOG_CONS, LOG_LOCAL0); + fcntl(srv->errorlog_fd, F_SETFD, FD_CLOEXEC); #endif + srv->errorlog_mode = ERRORLOG_FILE; } log_error_write(srv, __FILE__, __LINE__, "s", "server started"); @@ -70,7 +76,8 @@ int log_error_open(server *srv) { /* don't close stderr for debugging purposes if run in valgrind */ if (RUNNING_ON_VALGRIND) close_stderr = 0; #endif - + if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0; + /* move stderr to /dev/null */ if (close_stderr && -1 != (fd = open("/dev/null", O_WRONLY))) { @@ -92,8 +99,8 @@ int log_error_open(server *srv) { int log_error_cycle(server *srv) { /* only cycle if we are not in syslog-mode */ - if (0 == srv->log_using_syslog) { - const char *logfile = srv->srvconf.error_logfile->ptr; + if (srv->errorlog_mode == ERRORLOG_FILE) { + const char *logfile = srv->srvconf.errorlog_file->ptr; /* already check of opening time */ int new_fd; @@ -105,18 +112,15 @@ int log_error_cycle(server *srv) { "' failed: ", strerror(errno), ", falling back to syslog()"); - close(srv->log_error_fd); - srv->log_error_fd = -1; + close(srv->errorlog_fd); + srv->errorlog_fd = -1; #ifdef HAVE_SYSLOG_H - /* fall back to syslog() */ - srv->log_using_syslog = 1; - - openlog("lighttpd", LOG_CONS, LOG_LOCAL0); + srv->errorlog_mode = ERRORLOG_SYSLOG; #endif } else { /* ok, new log is open, close the old one */ - close(srv->log_error_fd); - srv->log_error_fd = new_fd; + close(srv->errorlog_fd); + srv->errorlog_fd = new_fd; } } @@ -128,12 +132,17 @@ int log_error_cycle(server *srv) { int log_error_close(server *srv) { log_error_write(srv, __FILE__, __LINE__, "s", "server stopped"); - if (srv->log_error_fd >= 0) { - close(srv->log_error_fd); - } else if(srv->log_using_syslog) { + switch(srv->errorlog_mode) { + case ERRORLOG_FILE: + close(srv->errorlog_fd); + break; + case ERRORLOG_SYSLOG: #ifdef HAVE_SYSLOG_H closelog(); #endif + break; + case ERRORLOG_STDERR: + break; } return 0; @@ -142,7 +151,9 @@ int log_error_close(server *srv) { int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...) { va_list ap; - if (srv->log_using_syslog == 0) { + switch(srv->errorlog_mode) { + case ERRORLOG_FILE: + case ERRORLOG_STDERR: /* cache the generated timestamp */ if (srv->cur_ts != srv->last_generated_debug_ts) { buffer_prepare_copy(srv->ts_debug_str, 255); @@ -152,15 +163,19 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const srv->last_generated_debug_ts = srv->cur_ts; } - buffer_copy_string_buffer(srv->error_log, srv->ts_debug_str); - BUFFER_APPEND_STRING_CONST(srv->error_log, ": ("); - } else { - BUFFER_COPY_STRING_CONST(srv->error_log, "("); + buffer_copy_string_buffer(srv->errorlog_buf, srv->ts_debug_str); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ": ("); + break; + case ERRORLOG_SYSLOG: + /* syslog is generating its own timestamps */ + BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "("); + break; } - buffer_append_string(srv->error_log, filename); - BUFFER_APPEND_STRING_CONST(srv->error_log, "."); - buffer_append_long(srv->error_log, line); - BUFFER_APPEND_STRING_CONST(srv->error_log, ") "); + + buffer_append_string(srv->errorlog_buf, filename); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "."); + buffer_append_long(srv->errorlog_buf, line); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") "); for(va_start(ap, fmt); *fmt; fmt++) { @@ -172,41 +187,41 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const switch(*fmt) { case 's': /* string */ s = va_arg(ap, char *); - buffer_append_string(srv->error_log, s); - BUFFER_APPEND_STRING_CONST(srv->error_log, " "); + buffer_append_string(srv->errorlog_buf, s); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); break; case 'b': /* buffer */ b = va_arg(ap, buffer *); - buffer_append_string_buffer(srv->error_log, b); - BUFFER_APPEND_STRING_CONST(srv->error_log, " "); + buffer_append_string_buffer(srv->errorlog_buf, b); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); break; case 'd': /* int */ d = va_arg(ap, int); - buffer_append_long(srv->error_log, d); - BUFFER_APPEND_STRING_CONST(srv->error_log, " "); + buffer_append_long(srv->errorlog_buf, d); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); break; case 'o': /* off_t */ o = va_arg(ap, off_t); - buffer_append_off_t(srv->error_log, o); - BUFFER_APPEND_STRING_CONST(srv->error_log, " "); + buffer_append_off_t(srv->errorlog_buf, o); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); break; case 'x': /* int (hex) */ d = va_arg(ap, int); - BUFFER_APPEND_STRING_CONST(srv->error_log, "0x"); - buffer_append_hex(srv->error_log, d); - BUFFER_APPEND_STRING_CONST(srv->error_log, " "); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "0x"); + buffer_append_hex(srv->errorlog_buf, d); + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); break; case 'S': /* string */ s = va_arg(ap, char *); - buffer_append_string(srv->error_log, s); + buffer_append_string(srv->errorlog_buf, s); break; case 'B': /* buffer */ b = va_arg(ap, buffer *); - buffer_append_string_buffer(srv->error_log, b); + buffer_append_string_buffer(srv->errorlog_buf, b); break; case 'D': /* int */ d = va_arg(ap, int); - buffer_append_long(srv->error_log, d); + buffer_append_long(srv->errorlog_buf, d); break; case '(': case ')': @@ -214,23 +229,24 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const case '>': case ',': case ' ': - buffer_append_string_len(srv->error_log, fmt, 1); + buffer_append_string_len(srv->errorlog_buf, fmt, 1); break; } } va_end(ap); - BUFFER_APPEND_STRING_CONST(srv->error_log, "\n"); - - if (srv->log_error_fd >= 0) { - write(srv->log_error_fd, srv->error_log->ptr, srv->error_log->used - 1); - } else if (srv->log_using_syslog == 0) { - /* only available at startup time */ - write(STDERR_FILENO, srv->error_log->ptr, srv->error_log->used - 1); - } else { -#ifdef HAVE_SYSLOG_H - syslog(LOG_ERR, "%s", srv->error_log->ptr); -#endif + switch(srv->errorlog_mode) { + case ERRORLOG_FILE: + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n"); + write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1); + break; + case ERRORLOG_STDERR: + BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n"); + write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1); + break; + case ERRORLOG_SYSLOG: + syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr); + break; } return 0; diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c index b23b04bf..e789926d 100644 --- a/src/mod_accesslog.c +++ b/src/mod_accesslog.c @@ -445,13 +445,6 @@ SETDEFAULTS_FUNC(log_access_open) { } if (s->use_syslog) { - if (srv->log_using_syslog == 0) { - log_error_write(srv, __FILE__, __LINE__, "s", - "accesslog can only be written to syslog if errorlog is also sent to syslog. ABORTING."); - - return HANDLER_ERROR; - } - /* ignore the next checks */ continue; } diff --git a/src/mod_cgi.c b/src/mod_cgi.c index 6aedaa6e..02ffe468 100644 --- a/src/mod_cgi.c +++ b/src/mod_cgi.c @@ -741,9 +741,14 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer * /* not needed */ close(to_cgi_fds[1]); - if (srv->log_error_fd >= 0) { + /* HACK: + * this is not nice, but it works + * + * we feed the stderr of the CGI to our errorlog, if possible + */ + if (srv->errorlog_mode == ERRORLOG_FILE) { close(STDERR_FILENO); - dup2(srv->log_error_fd, STDERR_FILENO); + dup2(srv->errorlog_fd, STDERR_FILENO); } /* create environment */ @@ -921,7 +926,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer * /* we don't need the client socket */ for (i = 3; i < 256; i++) { - if (i != srv->log_error_fd) close(i); + if (i != srv->errorlog_fd) close(i); } /* exec the cgi */ diff --git a/src/mod_rrdtool.c b/src/mod_rrdtool.c index b320b15b..d6582186 100644 --- a/src/mod_rrdtool.c +++ b/src/mod_rrdtool.c @@ -132,9 +132,10 @@ int mod_rrd_create_pipe(server *srv, plugin_data *p) { close(to_rrdtool_fds[1]); close(STDERR_FILENO); - if (srv->log_error_fd != -1) { - dup2(srv->log_error_fd, STDERR_FILENO); - close(srv->log_error_fd); + + if (srv->errorlog_mode == ERRORLOG_FILE) { + dup2(srv->errorlog_fd, STDERR_FILENO); + close(srv->errorlog_fd); } /* set up args */ diff --git a/src/server.c b/src/server.c index 3de9edde..fd525485 100644 --- a/src/server.c +++ b/src/server.c @@ -122,7 +122,7 @@ static server *server_init(void) { CLEAN(parse_full_path); CLEAN(ts_debug_str); CLEAN(ts_date_str); - CLEAN(error_log); + CLEAN(errorlog_buf); CLEAN(response_range); CLEAN(tmp_buf); CLEAN(file_cache_etag); @@ -131,12 +131,11 @@ static server *server_init(void) { buffer_copy_string(srv->empty_string, ""); - CLEAN(srvconf.error_logfile); + CLEAN(srvconf.errorlog_file); CLEAN(srvconf.groupname); CLEAN(srvconf.username); CLEAN(srvconf.changeroot); CLEAN(srvconf.bindhost); - CLEAN(srvconf.license); CLEAN(srvconf.event_handler); CLEAN(srvconf.pid_file); @@ -172,7 +171,8 @@ static server *server_init(void) { srv->srvconf.modules = array_init(); /* use syslog */ - srv->log_error_fd = -1; + srv->errorlog_fd = -1; + srv->errorlog_mode = ERRORLOG_STDERR; srv->split_vals = array_init(); @@ -203,19 +203,18 @@ static void server_free(server *srv) { CLEAN(parse_full_path); CLEAN(ts_debug_str); CLEAN(ts_date_str); - CLEAN(error_log); + CLEAN(errorlog_buf); CLEAN(response_range); CLEAN(tmp_buf); CLEAN(file_cache_etag); CLEAN(range_buf); CLEAN(empty_string); - CLEAN(srvconf.error_logfile); + CLEAN(srvconf.errorlog_file); CLEAN(srvconf.groupname); CLEAN(srvconf.username); CLEAN(srvconf.changeroot); CLEAN(srvconf.bindhost); - CLEAN(srvconf.license); CLEAN(srvconf.event_handler); CLEAN(srvconf.pid_file);