Add server.breakagelog, a "special" stderr (fixes #1863)

* The breakage-log simply replaces stderr (the old stderr is moved away if needed for errorlog),
  and stderr isn't closed after forking.
  It defaults to stderr if started with -n (no daemonize), otherwise it defaults to /dev/null.
  It is _not_ reopened in log_error_cycle, as there may be many long running childs which have it
  still open anyway. Use a pipe-logger with cycle-support if you need it.


git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2550 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.24
Stefan Bühler 14 years ago
parent 214484dec0
commit fbdb305f8a

@ -8,6 +8,7 @@ NEWS
* Use unsigned int (and T_CONFIG_INT) for max_request_size
* Use unsigned int for secdownload.timeout (fixes #1966)
* Keep url/host values from connection to display information while keep-alive in mod_status (fixes #1202)
* Add server.breakagelog, a "special" stderr (fixes #1863)
- 1.4.23 - 2009-06-19
* Added some extra warning options in cmake and fix the resulting warnings (unused/static functions)

@ -473,6 +473,7 @@ typedef struct {
buffer *errorlog_file;
unsigned short errorlog_use_syslog;
buffer *breakagelog_file;
unsigned short dont_daemonize;
buffer *changeroot;
@ -539,7 +540,7 @@ typedef struct server {
/* the errorlog */
int errorlog_fd;
enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG, ERRORLOG_PIPE } errorlog_mode;
enum { ERRORLOG_FILE, ERRORLOG_FD, ERRORLOG_SYSLOG, ERRORLOG_PIPE } errorlog_mode;
buffer *errorlog_buf;
fdevents *ev, *ev_ins;

@ -91,12 +91,13 @@ static int config_insert(server *srv) {
{ "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 46 */
{ "ssl.cipher-list", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 47 */
{ "ssl.use-sslv2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 48 */
{ "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */
{ "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */
{ "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 51 */
{ "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */
{ "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */
{ "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 51 */
{ "server.reject-expect-100-with-417", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 52 */
{ "debug.log-timeouts", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 53 */
{ "server.defer-accept", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 54 */
{ "server.defer-accept", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 54 */
{ "server.breakagelog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 55 */
{ "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 },
{ "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
@ -139,6 +140,8 @@ static int config_insert(server *srv) {
cv[43].destination = &(srv->srvconf.max_conns);
cv[12].destination = &(srv->srvconf.max_request_size);
cv[52].destination = &(srv->srvconf.reject_expect_100_with_417);
cv[55].destination = srv->srvconf.breakagelog_file;
srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
assert(srv->config_storage);

@ -150,13 +150,13 @@ int open_logfile_or_pipe(server *srv, const char* logfile) {
*/
int log_error_open(server *srv) {
int close_stderr = 1;
#ifdef HAVE_SYSLOG_H
/* perhaps someone wants to use syslog() */
openlog("lighttpd", LOG_CONS | LOG_PID, LOG_DAEMON);
#endif
srv->errorlog_mode = ERRORLOG_STDERR;
srv->errorlog_mode = ERRORLOG_FD;
srv->errorlog_fd = STDERR_FILENO;
if (srv->srvconf.errorlog_use_syslog) {
srv->errorlog_mode = ERRORLOG_SYSLOG;
@ -171,20 +171,36 @@ int log_error_open(server *srv) {
log_error_write(srv, __FILE__, __LINE__, "s", "server started");
#ifdef HAVE_VALGRIND_VALGRIND_H
/* 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 && srv->srvconf.dont_daemonize) {
if (srv->errorlog_mode == ERRORLOG_FD && !srv->srvconf.dont_daemonize) {
/* We can only log to stderr in dont-daemonize mode;
* if we do daemonize and no errorlog file is specified, we log into /dev/null
*/
close_stderr = 0;
srv->errorlog_fd = -1;
}
/* move stderr to /dev/null */
if (close_stderr) openDevNull(STDERR_FILENO);
if (!buffer_is_empty(srv->srvconf.breakagelog_file)) {
int breakage_fd;
const char *logfile = srv->srvconf.breakagelog_file->ptr;
if (srv->errorlog_mode == ERRORLOG_FD) {
srv->errorlog_fd = dup(STDERR_FILENO);
#ifdef FD_CLOEXEC
fcntl(srv->errorlog_fd, F_SETFD, FD_CLOEXEC);
#endif
}
if (-1 == (breakage_fd = open_logfile_or_pipe(srv, logfile))) {
return -1;
}
if (STDERR_FILENO != breakage_fd) {
dup2(breakage_fd, STDERR_FILENO);
close(breakage_fd);
}
} else if (!srv->srvconf.dont_daemonize) {
/* move stderr to /dev/null */
openDevNull(STDERR_FILENO);
}
return 0;
}
@ -235,15 +251,19 @@ int log_error_close(server *srv) {
switch(srv->errorlog_mode) {
case ERRORLOG_PIPE:
case ERRORLOG_FILE:
close(srv->errorlog_fd);
case ERRORLOG_FD:
if (-1 != srv->errorlog_fd) {
/* don't close STDERR */
if (STDERR_FILENO != srv->errorlog_fd)
close(srv->errorlog_fd);
srv->errorlog_fd = -1;
}
break;
case ERRORLOG_SYSLOG:
#ifdef HAVE_SYSLOG_H
closelog();
#endif
break;
case ERRORLOG_STDERR:
break;
}
return 0;
@ -255,7 +275,8 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const
switch(srv->errorlog_mode) {
case ERRORLOG_PIPE:
case ERRORLOG_FILE:
case ERRORLOG_STDERR:
case ERRORLOG_FD:
if (-1 == srv->errorlog_fd) return 0;
/* cache the generated timestamp */
if (srv->cur_ts != srv->last_generated_debug_ts) {
buffer_prepare_copy(srv->ts_debug_str, 255);
@ -349,13 +370,10 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const
switch(srv->errorlog_mode) {
case ERRORLOG_PIPE:
case ERRORLOG_FILE:
case ERRORLOG_FD:
buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("\n"));
write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
break;
case ERRORLOG_STDERR:
buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("\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;

@ -1018,8 +1018,6 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
*c = '/';
}
openDevNull(STDERR_FILENO);
/* we don't need the client socket */
for (i = 3; i < 256; i++) {
if (i != srv->errorlog_fd) close(i);

@ -993,8 +993,6 @@ static int fcgi_spawn_connection(server *srv,
close(fcgi_fd);
}
openDevNull(STDERR_FILENO);
/* we don't need the client socket */
for (i = 3; i < 256; i++) {
close(i);

@ -141,8 +141,6 @@ static int mod_rrd_create_pipe(server *srv, plugin_data *p) {
args[i++] = dash;
args[i++] = NULL;
openDevNull(STDERR_FILENO);
/* we don't need the client socket */
for (i = 3; i < 256; i++) {
close(i);

@ -783,8 +783,6 @@ static int scgi_spawn_connection(server *srv,
close(fd);
}
openDevNull(STDERR_FILENO);
/* build clean environment */
if (host->bin_env_copy->used) {
for (i = 0; i < host->bin_env_copy->used; i++) {

@ -187,6 +187,7 @@ static server *server_init(void) {
CLEAN(cond_check_buf);
CLEAN(srvconf.errorlog_file);
CLEAN(srvconf.breakagelog_file);
CLEAN(srvconf.groupname);
CLEAN(srvconf.username);
CLEAN(srvconf.changeroot);
@ -242,8 +243,8 @@ static server *server_init(void) {
srv->srvconf.reject_expect_100_with_417 = 1;
/* use syslog */
srv->errorlog_fd = -1;
srv->errorlog_mode = ERRORLOG_STDERR;
srv->errorlog_fd = STDERR_FILENO;
srv->errorlog_mode = ERRORLOG_FD;
srv->split_vals = array_init();
@ -271,6 +272,7 @@ static void server_free(server *srv) {
CLEAN(cond_check_buf);
CLEAN(srvconf.errorlog_file);
CLEAN(srvconf.breakagelog_file);
CLEAN(srvconf.groupname);
CLEAN(srvconf.username);
CLEAN(srvconf.changeroot);

Loading…
Cancel
Save