⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * http_log.c: Dealing with the logs and errors * * Rob McCool * */#include "apr.h"#include "apr_general.h"        /* for signal stuff */#include "apr_strings.h"#include "apr_errno.h"#include "apr_thread_proc.h"#include "apr_lib.h"#include "apr_signal.h"#define APR_WANT_STDIO#define APR_WANT_STRFUNC#include "apr_want.h"#if APR_HAVE_STDARG_H#include <stdarg.h>#endif#if APR_HAVE_UNISTD_H#include <unistd.h>#endif#define CORE_PRIVATE#include "ap_config.h"#include "httpd.h"#include "http_config.h"#include "http_core.h"#include "http_log.h"#include "http_main.h"#include "util_time.h"#include "ap_mpm.h"#ifndef APR_LARGEFILE#define APR_LARGEFILE 0#endiftypedef struct {    char    *t_name;    int      t_val;} TRANS;APR_HOOK_STRUCT(    APR_HOOK_LINK(error_log))int AP_DECLARE_DATA ap_default_loglevel = DEFAULT_LOGLEVEL;#ifdef HAVE_SYSLOGstatic const TRANS facilities[] = {    {"auth",    LOG_AUTH},#ifdef LOG_AUTHPRIV    {"authpriv",LOG_AUTHPRIV},#endif#ifdef LOG_CRON    {"cron",    LOG_CRON},#endif#ifdef LOG_DAEMON    {"daemon",  LOG_DAEMON},#endif#ifdef LOG_FTP    {"ftp", LOG_FTP},#endif#ifdef LOG_KERN    {"kern",    LOG_KERN},#endif#ifdef LOG_LPR    {"lpr", LOG_LPR},#endif#ifdef LOG_MAIL    {"mail",    LOG_MAIL},#endif#ifdef LOG_NEWS    {"news",    LOG_NEWS},#endif#ifdef LOG_SYSLOG    {"syslog",  LOG_SYSLOG},#endif#ifdef LOG_USER    {"user",    LOG_USER},#endif#ifdef LOG_UUCP    {"uucp",    LOG_UUCP},#endif#ifdef LOG_LOCAL0    {"local0",  LOG_LOCAL0},#endif#ifdef LOG_LOCAL1    {"local1",  LOG_LOCAL1},#endif#ifdef LOG_LOCAL2    {"local2",  LOG_LOCAL2},#endif#ifdef LOG_LOCAL3    {"local3",  LOG_LOCAL3},#endif#ifdef LOG_LOCAL4    {"local4",  LOG_LOCAL4},#endif#ifdef LOG_LOCAL5    {"local5",  LOG_LOCAL5},#endif#ifdef LOG_LOCAL6    {"local6",  LOG_LOCAL6},#endif#ifdef LOG_LOCAL7    {"local7",  LOG_LOCAL7},#endif    {NULL,      -1},};#endifstatic const TRANS priorities[] = {    {"emerg",   APLOG_EMERG},    {"alert",   APLOG_ALERT},    {"crit",    APLOG_CRIT},    {"error",   APLOG_ERR},    {"warn",    APLOG_WARNING},    {"notice",  APLOG_NOTICE},    {"info",    APLOG_INFO},    {"debug",   APLOG_DEBUG},    {NULL,      -1},};static apr_file_t *stderr_log = NULL;AP_DECLARE(void) ap_open_stderr_log(apr_pool_t *p){    apr_file_open_stderr(&stderr_log, p);}AP_DECLARE(apr_status_t) ap_replace_stderr_log(apr_pool_t *p,                                                const char *fname){    apr_file_t *stderr_file;    apr_status_t rc;    char *filename = ap_server_root_relative(p, fname);    if (!filename) {        ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT,                     APR_EBADPATH, NULL, "Invalid -E error log file %s",                     fname);        return APR_EBADPATH;    }    if ((rc = apr_file_open(&stderr_file, filename,                            APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE,                            APR_OS_DEFAULT, p)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL,                     "%s: could not open error log file %s.",                     ap_server_argv0, fname);        return rc;    }    if ((rc = apr_file_open_stderr(&stderr_log, p)) == APR_SUCCESS) {        apr_file_flush(stderr_log);        if ((rc = apr_file_dup2(stderr_log, stderr_file, p)) == APR_SUCCESS) {            apr_file_close(stderr_file);        }    }    if (rc != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rc, NULL,                     "unable to replace stderr with error_log");    }    return rc;}static void log_child_errfn(apr_pool_t *pool, apr_status_t err,                            const char *description){    ap_log_error(APLOG_MARK, APLOG_ERR, err, NULL,                 "%s", description);}static int log_child(apr_pool_t *p, const char *progname,                     apr_file_t **fpin){    /* Child process code for 'ErrorLog "|..."';     * may want a common framework for this, since I expect it will     * be common for other foo-loggers to want this sort of thing...     */    apr_status_t rc;    apr_procattr_t *procattr;    apr_proc_t *procnew;    if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS)        && ((rc = apr_procattr_io_set(procattr,                                      APR_FULL_BLOCK,                                      APR_NO_PIPE,                                      APR_NO_PIPE)) == APR_SUCCESS)        && ((rc = apr_procattr_error_check_set(procattr, 1)) == APR_SUCCESS)        && ((rc = apr_procattr_child_errfn_set(procattr, log_child_errfn)) == APR_SUCCESS)) {        char **args;        const char *pname;        apr_tokenize_to_argv(progname, &args, p);        pname = apr_pstrdup(p, args[0]);        procnew = (apr_proc_t *)apr_pcalloc(p, sizeof(*procnew));        rc = apr_proc_create(procnew, pname, (const char * const *)args,                             NULL, procattr, p);        if (rc == APR_SUCCESS) {            apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);            (*fpin) = procnew->in;        }    }    return rc;}static int open_error_log(server_rec *s, apr_pool_t *p){    const char *fname;    int rc;    if (*s->error_fname == '|') {        apr_file_t *dummy = NULL;        /* This starts a new process... */        rc = log_child (p, s->error_fname + 1, &dummy);        if (rc != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL,                         "Couldn't start ErrorLog process");            return DONE;        }        s->error_log = dummy;    }#ifdef HAVE_SYSLOG    else if (!strncasecmp(s->error_fname, "syslog", 6)) {        if ((fname = strchr(s->error_fname, ':'))) {            const TRANS *fac;            fname++;            for (fac = facilities; fac->t_name; fac++) {                if (!strcasecmp(fname, fac->t_name)) {                    openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID,                            fac->t_val);                    s->error_log = NULL;                    return OK;                }            }        }        else {            openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL7);        }        s->error_log = NULL;    }#endif    else {        fname = ap_server_root_relative(p, s->error_fname);        if (!fname) {            ap_log_error(APLOG_MARK, APLOG_STARTUP, APR_EBADPATH, NULL,                         "%s: Invalid error log path %s.",                         ap_server_argv0, s->error_fname);            return DONE;        }        if ((rc = apr_file_open(&s->error_log, fname,                               APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE,                               APR_OS_DEFAULT, p)) != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL,                         "%s: could not open error log file %s.",                         ap_server_argv0, fname);            return DONE;        }    }    return OK;}int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */,                  apr_pool_t *ptemp, server_rec *s_main){    apr_status_t rc = APR_SUCCESS;    server_rec *virt, *q;    int replace_stderr;    apr_file_t *errfile = NULL;    if (open_error_log(s_main, p) != OK) {        return DONE;    }    replace_stderr = 1;    if (s_main->error_log) {        /* replace stderr with this new log */        apr_file_flush(s_main->error_log);        if ((rc = apr_file_open_stderr(&errfile, p)) == APR_SUCCESS) {            rc = apr_file_dup2(errfile, s_main->error_log, p);        }        if (rc != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s_main,                         "unable to replace stderr with error_log");        }        else {            replace_stderr = 0;        }    }    /* note that stderr may still need to be replaced with something     * because it points to the old error log, or back to the tty     * of the submitter.     * XXX: This is BS - /dev/null is non-portable     */    if (replace_stderr && freopen("/dev/null", "w", stderr) == NULL) {        ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s_main,                     "unable to replace stderr with /dev/null");    }    for (virt = s_main->next; virt; virt = virt->next) {        if (virt->error_fname) {            for (q=s_main; q != virt; q = q->next) {                if (q->error_fname != NULL                    && strcmp(q->error_fname, virt->error_fname) == 0) {                    break;                }            }            if (q == virt) {                if (open_error_log(virt, p) != OK) {                    return DONE;                }            }            else {                virt->error_log = q->error_log;            }        }        else {            virt->error_log = s_main->error_log;        }    }    return OK;}AP_DECLARE(void) ap_error_log2stderr(server_rec *s) {    apr_file_t *errfile = NULL;    apr_file_open_stderr(&errfile, s->process->pool);    if (s->error_log != NULL) {        apr_file_dup2(s->error_log, errfile, s->process->pool);    }}static void log_error_core(const char *file, int line, int level,                           apr_status_t status, const server_rec *s,                           const request_rec *r, apr_pool_t *pool,                           const char *fmt, va_list args){    char errstr[MAX_STRING_LEN];#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED    char scratch[MAX_STRING_LEN];#endif    apr_size_t len, errstrlen;    apr_file_t *logf = NULL;    const char *referer;    int level_and_mask = level & APLOG_LEVELMASK;    if (s == NULL) {        /*         * If we are doing stderr logging (startup), don't log messages that are         * above the default server log level unless it is a startup/shutdown         * notice         */        if ((level_and_mask != APLOG_NOTICE)            && (level_and_mask > ap_default_loglevel)) {            return;        }        logf = stderr_log;    }    else if (s->error_log) {        /*         * If we are doing normal logging, don't log messages that are         * above the server log level unless it is a startup/shutdown notice         */        if ((level_and_mask != APLOG_NOTICE)            && (level_and_mask > s->loglevel)) {            return;        }        logf = s->error_log;    }#ifdef TPF    else if (tpf_child) {        /*         * If we are doing normal logging, don't log messages that are         * above the server log level unless it is a startup/shutdown notice         */        if ((level_and_mask != APLOG_NOTICE)            && (level_and_mask > s->loglevel)) {            return;        }        logf = stderr;    }#endif /* TPF */    else {        /*         * If we are doing syslog logging, don't log messages that are         * above the server log level (including a startup/shutdown notice)         */        if (level_and_mask > s->loglevel) {            return;        }    }    if (logf && ((level & APLOG_STARTUP) != APLOG_STARTUP)) {        errstr[0] = '[';        ap_recent_ctime(errstr + 1, apr_time_now());        errstr[1 + APR_CTIME_LEN - 1] = ']';        errstr[1 + APR_CTIME_LEN    ] = ' ';        len = 1 + APR_CTIME_LEN + 1;    } else {        len = 0;    }    if ((level & APLOG_STARTUP) != APLOG_STARTUP) {        len += apr_snprintf(errstr + len, MAX_STRING_LEN - len,                            "[%s] ", priorities[level_and_mask].t_name);    }#ifndef TPF    if (file && level_and_mask == APLOG_DEBUG) {#if defined(_OSD_POSIX) || defined(WIN32)        char tmp[256];        char *e = strrchr(file, '/');#ifdef WIN32        if (!e) {            e = strrchr(file, '\\');        }#endif        /* In OSD/POSIX, the compiler returns for __FILE__         * a string like: __FILE__="*POSIX(/usr/include/stdio.h)"         * (it even returns an absolute path for sources in         * the current directory). Here we try to strip this         * down to the basename.         */        if (e != NULL && e[1] != '\0') {            apr_snprintf(tmp, sizeof(tmp), "%s", &e[1]);            e = &tmp[strlen(tmp)-1];            if (*e == ')') {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -