📄 mod_log_config.c
字号:
static const char *log_header_out(request_rec *r, char *a){ const char *cp = ap_table_get(r->headers_out, a); if (!strcasecmp(a, "Content-type") && r->content_type) { cp = r->content_type; } if (cp) { return cp; } return ap_table_get(r->err_headers_out, a);}static const char *log_note(request_rec *r, char *a){ return ap_table_get(r->notes, a);}static const char *log_env_var(request_rec *r, char *a){ return ap_table_get(r->subprocess_env, a);}static const char *log_request_time(request_rec *r, char *a){ int timz; struct tm *t; char tstr[MAX_STRING_LEN]; t = ap_get_gmtoff(&timz); if (a && *a) { /* Custom format */ strftime(tstr, MAX_STRING_LEN, a, t); } else { /* CLF format */ char sign = (timz < 0 ? '-' : '+'); size_t l; if (timz < 0) { timz = -timz; } strftime(tstr, MAX_STRING_LEN, "[%d/%b/%Y:%H:%M:%S ", t); l = strlen(tstr); ap_snprintf(tstr + l, sizeof(tstr) - l, "%c%.2d%.2d]", sign, timz / 60, timz % 60); } return ap_pstrdup(r->pool, tstr);}static const char *log_request_duration(request_rec *r, char *a){ return ap_psprintf(r->pool, "%ld", time(NULL) - r->request_time);}/* These next two routines use the canonical name:port so that log * parsers don't need to duplicate all the vhost parsing crud. */static const char *log_virtual_host(request_rec *r, char *a){ return ap_get_server_name(r);}static const char *log_server_port(request_rec *r, char *a){ return ap_psprintf(r->pool, "%u", ap_get_server_port(r));}static const char *log_child_pid(request_rec *r, char *a){ return ap_psprintf(r->pool, "%ld", (long) getpid());}/***************************************************************** * * Parsing the log format string */static struct log_item_list { char ch; item_key_func func; int want_orig_default;} log_item_keys[] = { { 'h', log_remote_host, 0 }, { 'a', log_remote_address, 0 }, { 'l', log_remote_logname, 0 }, { 'u', log_remote_user, 0 }, { 't', log_request_time, 0 }, { 'T', log_request_duration, 1 }, { 'r', log_request_line, 1 }, { 'f', log_request_file, 0 }, { 'U', log_request_uri, 1 }, { 's', log_status, 1 }, { 'b', log_bytes_sent, 0 }, { 'i', log_header_in, 0 }, { 'o', log_header_out, 0 }, { 'n', log_note, 0 }, { 'e', log_env_var, 0 }, { 'v', log_virtual_host, 0 }, { 'p', log_server_port, 0 }, { 'P', log_child_pid, 0 }, { '\0' }};static struct log_item_list *find_log_func(char k){ int i; for (i = 0; log_item_keys[i].ch; ++i) if (k == log_item_keys[i].ch) { return &log_item_keys[i]; } return NULL;}static char *log_format_substring(pool *p, const char *start, const char *end){ char *res = ap_palloc(p, end - start + 1); strncpy(res, start, end - start); res[end - start] = '\0'; return res;}static char *parse_log_misc_string(pool *p, log_format_item *it, const char **sa){ const char *s = *sa; it->func = constant_item; it->conditions = NULL; while (*s && *s != '%') { ++s; } it->arg = log_format_substring(p, *sa, s); *sa = s; return NULL;}static char *parse_log_item(pool *p, log_format_item *it, const char **sa){ const char *s = *sa; if (*s != '%') { return parse_log_misc_string(p, it, sa); } ++s; it->condition_sense = 0; it->conditions = NULL; it->want_orig = -1; it->arg = ""; /* For safety's sake... */ while (*s) { int i; struct log_item_list *l; switch (*s) { case '!': ++s; it->condition_sense = !it->condition_sense; break; case '<': ++s; it->want_orig = 1; break; case '>': ++s; it->want_orig = 0; break; case ',': ++s; break; case '{': ++s; it->arg = ap_getword(p, &s, '}'); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': i = *s - '0'; while (ap_isdigit(*++s)) { i = i * 10 + (*s) - '0'; } if (!it->conditions) { it->conditions = ap_make_array(p, 4, sizeof(int)); } *(int *) ap_push_array(it->conditions) = i; break; default: l = find_log_func(*s++); if (!l) { char dummy[2]; dummy[0] = s[-1]; dummy[1] = '\0'; return ap_pstrcat(p, "Unrecognized LogFormat directive %", dummy, NULL); } it->func = l->func; if (it->want_orig == -1) { it->want_orig = l->want_orig_default; } *sa = s; return NULL; } } return "Ran off end of LogFormat parsing args to some directive";}static array_header *parse_log_string(pool *p, const char *s, const char **err){ array_header *a = ap_make_array(p, 30, sizeof(log_format_item)); char *res; while (*s) { if ((res = parse_log_item(p, (log_format_item *) ap_push_array(a), &s))) { *err = res; return NULL; } } s = "\n"; parse_log_item(p, (log_format_item *) ap_push_array(a), &s); return a;}/***************************************************************** * * Actually logging. */static const char *process_item(request_rec *r, request_rec *orig, log_format_item *item){ const char *cp; /* First, see if we need to process this thing at all... */ if (item->conditions && item->conditions->nelts != 0) { int i; int *conds = (int *) item->conditions->elts; int in_list = 0; for (i = 0; i < item->conditions->nelts; ++i) { if (r->status == conds[i]) { in_list = 1; break; } } if ((item->condition_sense && in_list) || (!item->condition_sense && !in_list)) { return "-"; } } /* We do. Do it... */ cp = (*item->func) (item->want_orig ? orig : r, item->arg); return cp ? cp : "-";}#ifdef BUFFERED_LOGSstatic void flush_log(config_log_state *cls){ if (cls->outcnt && cls->log_fd != -1) { write(cls->log_fd, cls->outbuf, cls->outcnt); cls->outcnt = 0; }}#endifstatic int config_log_transaction(request_rec *r, config_log_state *cls, array_header *default_format){ log_format_item *items; char *str, *s; const char **strs; int *strl; request_rec *orig; int i; int len = 0; array_header *format; if (cls->fname == NULL) { return DECLINED; } format = cls->format ? cls->format : default_format; strs = ap_palloc(r->pool, sizeof(char *) * (format->nelts)); strl = ap_palloc(r->pool, sizeof(int) * (format->nelts)); items = (log_format_item *) format->elts;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -