Skip to content

Commit

Permalink
Make using errorlog provider and file at the same time possible
Browse files Browse the repository at this point in the history
This commit allows user to use errorlog provider and file or pipe
to utility at the same time. Previous behaviour of ErrorLog directive
is kept intact.
  • Loading branch information
TomasKorbar committed Apr 21, 2023
1 parent f074708 commit 2be0492
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 43 deletions.
4 changes: 4 additions & 0 deletions include/httpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -1385,12 +1385,16 @@ struct server_rec {

/** The name of the error log */
char *error_fname;
/** true if error log file was set */
char errorlog_altered;
/** A file descriptor that references the error log */
apr_file_t *error_log;
/** The log level configuration */
struct ap_logconf log;
/** External error log writer provider */
struct ap_errorlog_provider *errorlog_provider;
/** argument supplied to the errorlog provider */
const char *errorlog_provider_argument;
/** Handle to be passed to external log provider's logging method */
void *errorlog_provider_handle;

Expand Down
4 changes: 2 additions & 2 deletions modules/loggers/mod_journald.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ static apr_status_t journald_error_log(const ap_errorlog_info *info,
const server_rec *s = info->s;
const request_rec *r = info->r;
apr_pool_t *pool;
const char *log_name = (s && s->error_fname && *s->error_fname) ?
s->error_fname : "error_log";
const char *log_name = (s && s->errorlog_provider_argument && *s->errorlog_provider_argument)
? s->errorlog_provider_argument : "error_log";

pool = journald_info_get_pool(info);
if (!pool) {
Expand Down
4 changes: 2 additions & 2 deletions modules/loggers/mod_syslog.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,14 @@ static const TRANS facilities[] = {

static void *syslog_error_log_init(apr_pool_t *p, server_rec *s)
{
char *fname = s->error_fname;
char *fname = s->errorlog_provider_argument;
void *success = (void *)p; /* anything non-NULL is success */

if (*fname == '\0') {
openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL7);
}
else {
/* s->error_fname could be [level]:[tag] (see #60525) */
/* s->errorlog_provider_argument could be [level]:[tag] (see #60525) */
const char *tag;
apr_size_t flen;
const TRANS *fac;
Expand Down
3 changes: 3 additions & 0 deletions server/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -2233,6 +2233,9 @@ static server_rec *init_server_config(process_rec *process, apr_pool_t *p)
s->server_hostname = NULL;
s->server_scheme = NULL;
s->error_fname = DEFAULT_ERRORLOG;
s->errorlog_altered = 0;
s->errorlog_provider = NULL;
s->errorlog_provider_argument = NULL;
s->log.level = DEFAULT_LOGLEVEL;
s->log.module_levels = NULL;
s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
Expand Down
10 changes: 8 additions & 2 deletions server/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -4550,7 +4550,6 @@ static const char *set_errorlog(cmd_parms *cmd, void *dummy, const char *arg1,
{
ap_errorlog_provider *provider;
const char *err;
cmd->server->errorlog_provider = NULL;

if (!arg2) {
/* Stay backward compatible and check for "syslog" */
Expand All @@ -4568,12 +4567,14 @@ static const char *set_errorlog(cmd_parms *cmd, void *dummy, const char *arg1,
arg2 = "";
}
else {
cmd->server->errorlog_altered = 1;
return set_server_string_slot(cmd, dummy, arg1);
}
}
}

if (strcmp("file", arg1) == 0) {
cmd->server->errorlog_altered = 1;
return set_server_string_slot(cmd, dummy, arg2);
}

Expand All @@ -4591,7 +4592,12 @@ static const char *set_errorlog(cmd_parms *cmd, void *dummy, const char *arg1,
}

cmd->server->errorlog_provider = provider;
return set_server_string_slot(cmd, dummy, arg2);
err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
cmd->server->errorlog_provider_argument = arg2;
return NULL;
}

static const char *set_errorlog_format(cmd_parms *cmd, void *dummy,
Expand Down
87 changes: 50 additions & 37 deletions server/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,16 +335,7 @@ static int open_error_log(server_rec *s, int is_main, apr_pool_t *p)
}

s->error_log = dummy;
}
else if (s->errorlog_provider) {
s->errorlog_provider_handle = s->errorlog_provider->init(p, s);
s->error_log = NULL;
if (!s->errorlog_provider_handle) {
/* provider must log something to the console */
return DONE;
}
}
else {
} else if (!s->errorlog_provider || s->errorlog_altered){
fname = ap_server_root_relative(p, s->error_fname);
if (!fname) {
ap_log_error(APLOG_MARK, APLOG_STARTUP, APR_EBADPATH, ap_server_conf, APLOGNO(00090)
Expand All @@ -360,6 +351,22 @@ static int open_error_log(server_rec *s, int is_main, apr_pool_t *p)
ap_server_argv0, fname);
return DONE;
}
} else {
/* When provider is actived and there is no directive specifying logfile then do
* not log into file */
s->error_log = NULL;
}

/* we have to check whether this is the main server, because if it is not
* and errorlog_provider is set, then we have to initialize handle only if it has not
* been inherited from the main server
*/
if (s->errorlog_provider && (is_main || !s->errorlog_provider_handle)) {
s->errorlog_provider_handle = s->errorlog_provider->init(p, s);
if (!s->errorlog_provider_handle) {
/* provider must log something to the console */
return DONE;
}
}

return OK;
Expand Down Expand Up @@ -450,8 +457,11 @@ int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */,
stderr_log = NULL;
}

char perform_opening;
for (virt = s_main->next; virt; virt = virt->next) {
perform_opening = 0;
if (virt->error_fname) {
virt->errorlog_altered = 1;
for (q=s_main; q != virt; q = q->next) {
if (q->error_fname != NULL
&& strcmp(q->error_fname, virt->error_fname) == 0) {
Expand All @@ -460,28 +470,26 @@ int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */,
}

if (q == virt) {
if (open_error_log(virt, 0, p) != OK) {
return DONE;
}
perform_opening = 1;
}
else {
virt->error_log = q->error_log;
}
} else {
virt->error_log = s_main->error_log;
}
else if (virt->errorlog_provider) {

if (virt->errorlog_provider) {
/* separately-configured vhost-specific provider */
if (open_error_log(virt, 0, p) != OK) {
return DONE;
}
}
else if (s_main->errorlog_provider) {
perform_opening = 1;
virt->errorlog_provider_handle = NULL;
} else if (s_main->errorlog_provider) {
/* inherit provider from s_main */
virt->errorlog_provider = s_main->errorlog_provider;
virt->errorlog_provider_handle = s_main->errorlog_provider_handle;
virt->error_log = NULL;
}
else {
virt->error_log = s_main->error_log;
if (perform_opening && open_error_log(virt, 0, p) != OK) {
return DONE;
}
}
return OK;
Expand Down Expand Up @@ -889,13 +897,6 @@ static int do_errorlog_default(const ap_errorlog_info *info, char *buf,
char scratch[MAX_STRING_LEN];
#endif

if (!info->using_provider && !info->startup) {
buf[len++] = '[';
len += log_ctime(info, "u", buf + len, buflen - len);
buf[len++] = ']';
buf[len++] = ' ';
}

if (!info->startup) {
buf[len++] = '[';
len += log_module_name(info, NULL, buf + len, buflen - len);
Expand Down Expand Up @@ -1094,7 +1095,7 @@ static void log_error_core(const char *file, int line, int module_index,
#endif

logf = stderr_log;
if (!logf && ap_server_conf && ap_server_conf->errorlog_provider) {
if (ap_server_conf && ap_server_conf->errorlog_provider) {
errorlog_provider = ap_server_conf->errorlog_provider;
errorlog_provider_handle = ap_server_conf->errorlog_provider_handle;
}
Expand Down Expand Up @@ -1171,7 +1172,7 @@ static void log_error_core(const char *file, int line, int module_index,
info.file = NULL;
info.line = 0;
info.status = 0;
info.using_provider= (logf == NULL);
info.using_provider= errorlog_provider && errorlog_provider_handle;
info.startup = ((level & APLOG_STARTUP) == APLOG_STARTUP);
info.format = fmt;

Expand Down Expand Up @@ -1232,16 +1233,27 @@ static void log_error_core(const char *file, int line, int module_index,
* prepare and log one line
*/

int provider_len = 0;
size_t after_timestamp = 0;

if (log_format && !info.startup) {
len += do_errorlog_format(log_format, &info, errstr + len,
MAX_STRING_LEN - len,
&errstr_start, &errstr_end, fmt, args);
}
else {
} else {
if (!info.startup) {
errstr[len++] = '[';
len += log_ctime(&info, "u", errstr + len, MAX_STRING_LEN - len);
errstr[len++] = ']';
errstr[len++] = ' ';
}
after_timestamp = len;
len += do_errorlog_default(&info, errstr + len, MAX_STRING_LEN - len,
&errstr_start, &errstr_end, fmt, args);
}

provider_len = len - after_timestamp;

if (!*errstr) {
/*
* Don't log empty lines. This can happen with once-per-conn/req
Expand All @@ -1250,8 +1262,7 @@ static void log_error_core(const char *file, int line, int module_index,
continue;
}

if (logf || (errorlog_provider->flags &
AP_ERRORLOG_PROVIDER_ADD_EOL_STR)) {
if (logf || (errorlog_provider->flags & AP_ERRORLOG_PROVIDER_ADD_EOL_STR)) {
/* Truncate for the terminator (as apr_snprintf does) */
if (len > MAX_STRING_LEN - sizeof(APR_EOL_STR)) {
len = MAX_STRING_LEN - sizeof(APR_EOL_STR);
Expand All @@ -1263,9 +1274,11 @@ static void log_error_core(const char *file, int line, int module_index,
if (logf) {
write_logline(errstr, len, logf, level_and_mask);
}
else {
if (errorlog_provider_handle) {
if (errorlog_provider->flags & AP_ERRORLOG_PROVIDER_ADD_EOL_STR)
provider_len += sizeof(APR_EOL_STR);
errorlog_provider->writer(&info, errorlog_provider_handle,
errstr, len);
errstr + after_timestamp, provider_len);
}

if (done) {
Expand Down

0 comments on commit 2be0492

Please sign in to comment.