📄 log.c
字号:
*e = '\0'; } file = tmp; }#endif /*_OSD_POSIX*/ len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, "%s(%d): ", file, line); }#endif /* TPF */ if (r && r->connection) { /* XXX: TODO: add a method of selecting whether logged client * addresses are in dotted quad or resolved form... dotted * quad is the most secure, which is why I'm implementing it * first. -djg */ len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, "[client %s] ", r->connection->remote_ip); } if (status != 0) { if (status < APR_OS_START_EAIERR) { len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, "(%d)", status); } else if (status < APR_OS_START_SYSERR) { len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, "(EAI %d)", status - APR_OS_START_EAIERR); } else if (status < 100000 + APR_OS_START_SYSERR) { len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, "(OS %d)", status - APR_OS_START_SYSERR); } else { len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, "(os 0x%08x)", status - APR_OS_START_SYSERR); } apr_strerror(status, errstr + len, MAX_STRING_LEN - len); len += strlen(errstr + len); if (MAX_STRING_LEN - len > 2) { errstr[len++] = ':'; errstr[len++] = ' '; errstr[len] = '\0'; } } errstrlen = len;#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED if (apr_vsnprintf(scratch, MAX_STRING_LEN - len, fmt, args)) { len += ap_escape_errorlog_item(errstr + len, scratch, MAX_STRING_LEN - len); }#else len += apr_vsnprintf(errstr + len, MAX_STRING_LEN - len, fmt, args);#endif if ( r && (referer = apr_table_get(r->headers_in, "Referer"))#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED && ap_escape_errorlog_item(scratch, referer, MAX_STRING_LEN - len)#endif ) { len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, ", referer: %s",#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED scratch#else referer#endif ); } /* NULL if we are logging to syslog */ if (logf) { /* 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); } strcpy(errstr + len, APR_EOL_STR); apr_file_puts(errstr, logf); apr_file_flush(logf); }#ifdef HAVE_SYSLOG else { syslog(level_and_mask, "%s", errstr); }#endif ap_run_error_log(file, line, level, status, s, r, pool, errstr + errstrlen);}AP_DECLARE(void) ap_log_error(const char *file, int line, int level, apr_status_t status, const server_rec *s, const char *fmt, ...){ va_list args; va_start(args, fmt); log_error_core(file, line, level, status, s, NULL, NULL, fmt, args); va_end(args);}AP_DECLARE(void) ap_log_perror(const char *file, int line, int level, apr_status_t status, apr_pool_t *p, const char *fmt, ...){ va_list args; va_start(args, fmt); log_error_core(file, line, level, status, NULL, NULL, p, fmt, args); va_end(args);}AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level, apr_status_t status, const request_rec *r, const char *fmt, ...){ va_list args; va_start(args, fmt); log_error_core(file, line, level, status, r->server, r, NULL, fmt, args); /* * IF APLOG_TOCLIENT is set, * AND the error level is 'warning' or more severe, * AND there isn't already error text associated with this request, * THEN make the message text available to ErrorDocument and * other error processors. */ va_end(args); va_start(args,fmt); if ((level & APLOG_TOCLIENT) && ((level & APLOG_LEVELMASK) <= APLOG_WARNING) && (apr_table_get(r->notes, "error-notes") == NULL)) { apr_table_setn(r->notes, "error-notes", ap_escape_html(r->pool, apr_pvsprintf(r->pool, fmt, args))); } va_end(args);}AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *filename){ apr_file_t *pid_file = NULL; apr_finfo_t finfo; static pid_t saved_pid = -1; pid_t mypid; apr_status_t rv; const char *fname; if (!filename) { return; } fname = ap_server_root_relative(p, filename); if (!fname) { ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, APR_EBADPATH, NULL, "Invalid PID file path %s, ignoring.", filename); return; } mypid = getpid(); if (mypid != saved_pid && apr_stat(&finfo, fname, APR_FINFO_MTIME, p) == APR_SUCCESS) { /* AP_SIG_GRACEFUL and HUP call this on each restart. * Only warn on first time through for this pid. * * XXX: Could just write first time through too, although * that may screw up scripts written to do something * based on the last modification time of the pid file. */ ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p, apr_psprintf(p, "pid file %s overwritten -- Unclean " "shutdown of previous Apache run?", fname)); } if ((rv = apr_file_open(&pid_file, fname, APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD, p)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "could not create %s", fname); ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "%s: could not log pid to file %s", ap_server_argv0, fname); exit(1); } apr_file_printf(pid_file, "%ld" APR_EOL_STR, (long)mypid); apr_file_close(pid_file); saved_pid = mypid;}AP_DECLARE(apr_status_t) ap_read_pid(apr_pool_t *p, const char *filename, pid_t *mypid){ const apr_size_t BUFFER_SIZE = sizeof(long) * 3 + 2; /* see apr_ltoa */ apr_file_t *pid_file = NULL; apr_status_t rv; const char *fname; char *buf, *endptr; apr_size_t bytes_read; if (!filename) { return APR_EGENERAL; } fname = ap_server_root_relative(p, filename); if (!fname) { ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, APR_EBADPATH, NULL, "Invalid PID file path %s, ignoring.", filename); return APR_EGENERAL; } rv = apr_file_open(&pid_file, fname, APR_READ, APR_OS_DEFAULT, p); if (rv != APR_SUCCESS) { return rv; } /* Ensure null-termination, so that strtol doesn't go crazy. */ buf = apr_palloc(p, BUFFER_SIZE); buf[BUFFER_SIZE - 1] = '\0'; rv = apr_file_read_full(pid_file, buf, BUFFER_SIZE - 1, &bytes_read); if (rv != APR_SUCCESS && rv != APR_EOF) { return rv; } /* If we fill the buffer, we're probably reading a corrupt pid file. * To be nice, let's also ensure the first char is a digit. */ if (bytes_read == BUFFER_SIZE - 1 || !apr_isdigit(*buf)) { return APR_EGENERAL; } *mypid = strtol(buf, &endptr, 10); apr_file_close(pid_file); return APR_SUCCESS;}AP_DECLARE(void) ap_log_assert(const char *szExp, const char *szFile, int nLine){ char time_str[APR_CTIME_LEN]; apr_ctime(time_str, apr_time_now()); ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, "[%s] file %s, line %d, assertion \"%s\" failed", time_str, szFile, nLine, szExp);#if defined(WIN32) DebugBreak();#else /* unix assert does an abort leading to a core dump */ abort();#endif}/* piped log support */#ifdef AP_HAVE_RELIABLE_PIPED_LOGS/* forward declaration */static void piped_log_maintenance(int reason, void *data, apr_wait_t status);static int piped_log_spawn(piped_log *pl){ int rc = 0; apr_procattr_t *procattr; apr_proc_t *procnew = NULL; apr_status_t status; if (((status = apr_procattr_create(&procattr, pl->p)) != APR_SUCCESS) || ((status = apr_procattr_child_in_set(procattr, ap_piped_log_read_fd(pl), ap_piped_log_write_fd(pl))) != APR_SUCCESS) || ((status = apr_procattr_child_errfn_set(procattr, log_child_errfn)) != APR_SUCCESS) || ((status = apr_procattr_error_check_set(procattr, 1)) != APR_SUCCESS)) { char buf[120]; /* Something bad happened, give up and go away. */ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "piped_log_spawn: unable to setup child process '%s': %s", pl->program, apr_strerror(status, buf, sizeof(buf))); rc = -1; } else { char **args; const char *pname; apr_tokenize_to_argv(pl->program, &args, pl->p); pname = apr_pstrdup(pl->p, args[0]); procnew = apr_pcalloc(pl->p, sizeof(apr_proc_t)); status = apr_proc_create(procnew, pname, (const char * const *) args, NULL, procattr, pl->p); if (status == APR_SUCCESS) { pl->pid = procnew; ap_piped_log_write_fd(pl) = procnew->in; apr_proc_other_child_register(procnew, piped_log_maintenance, pl, ap_piped_log_write_fd(pl), pl->p); } else { char buf[120]; /* Something bad happened, give up and go away. */ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "unable to start piped log program '%s': %s", pl->program, apr_strerror(status, buf, sizeof(buf))); rc = -1; } } return rc;}static void piped_log_maintenance(int reason, void *data, apr_wait_t status){ piped_log *pl = data; apr_status_t stats; int mpm_state; switch (reason) { case APR_OC_REASON_DEATH: case APR_OC_REASON_LOST: pl->pid = NULL; /* in case we don't get it going again, this * tells other logic not to try to kill it */ apr_proc_other_child_unregister(pl); stats = ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state); if (stats != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "can't query MPM state; not restarting " "piped log program '%s'", pl->program); } else if (mpm_state != AP_MPMQ_STOPPING) { ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "piped log program '%s' failed unexpectedly", pl->program); if ((stats = piped_log_spawn(pl)) != APR_SUCCESS) { /* what can we do? This could be the error log we're having * problems opening up... */ char buf[120]; ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "piped_log_maintenance: unable to respawn '%s': %s", pl->program, apr_strerror(stats, buf, sizeof(buf))); } } break; case APR_OC_REASON_UNWRITABLE: /* We should not kill off the pipe here, since it may only be full. * If it really is locked, we should kill it off manually. */ break; case APR_OC_REASON_RESTART: if (pl->pid != NULL) { apr_proc_kill(pl->pid, SIGTERM); pl->pid = NULL; } break; case APR_OC_REASON_UNREGISTER: break; }}static apr_status_t piped_log_cleanup_for_exec(void *data){ piped_log *pl = data; apr_file_close(ap_piped_log_read_fd(pl)); apr_file_close(ap_piped_log_write_fd(pl)); return APR_SUCCESS;}static apr_status_t piped_log_cleanup(void *data){ piped_log *pl = data; if (pl->pid != NULL) { apr_proc_kill(pl->pid, SIGTERM); } return piped_log_cleanup_for_exec(data);}AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program){ piped_log *pl; pl = apr_palloc(p, sizeof (*pl)); pl->p = p; pl->program = apr_pstrdup(p, program); pl->pid = NULL; if (apr_file_pipe_create(&ap_piped_log_read_fd(pl), &ap_piped_log_write_fd(pl), p) != APR_SUCCESS) { return NULL; } apr_pool_cleanup_register(p, pl, piped_log_cleanup, piped_log_cleanup_for_exec); if (piped_log_spawn(pl) == -1) { int save_errno = errno; apr_pool_cleanup_kill(p, pl, piped_log_cleanup); apr_file_close(ap_piped_log_read_fd(pl)); apr_file_close(ap_piped_log_write_fd(pl)); errno = save_errno; return NULL; } return pl;}#else /* !AP_HAVE_RELIABLE_PIPED_LOGS */static apr_status_t piped_log_cleanup(void *data){ piped_log *pl = data; apr_file_close(ap_piped_log_write_fd(pl)); return APR_SUCCESS;}AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program){ piped_log *pl; apr_file_t *dummy = NULL; int rc; rc = log_child(p, program, &dummy); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, "Couldn't start piped log process"); return NULL; } pl = apr_palloc(p, sizeof (*pl)); pl->p = p; ap_piped_log_read_fd(pl) = NULL; ap_piped_log_write_fd(pl) = dummy; apr_pool_cleanup_register(p, pl, piped_log_cleanup, piped_log_cleanup); return pl;}#endifAP_DECLARE(void) ap_close_piped_log(piped_log *pl){ apr_pool_cleanup_run(pl->p, pl, piped_log_cleanup);}AP_IMPLEMENT_HOOK_VOID(error_log, (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 *errstr), (file, line, level, status, s, r, pool, errstr))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -