<-
Apache > HTTP服务器 > 文档 > V2.0 > 模块

Apache模块 mod_log_config

说明允许将请求记录日志和定制日志文件格式
状态Base
模块名log_config_module
源文件mod_log_config.c

概述

本模块提供了灵活的方法将客户请求记录到日志。日志可以以自定义的格式直接写入文件,或者传送到一个外部程序中继续处理。条件日志功能可以实现根据请求的特征来决定一个日志信息是否被包含在最终的日志记录里面。

本模块提供了三个指令:TransferLog指令用来生成一个日志文件,LogFormat指令用来设定自定义的日志格式,CustomLog指令可以同时完成日志文件和格式的设定。TransferLogCustomLog指令在每个服务器上都可以被多次使用,以便将一个请求记录到多个文件中。

top

定制日志文件格式

LogFormatCustomLog指令的格式化参数是一个字符串。这个字符串会在每次请求发生的时候,被记录到日志中去。它可以包含将被原样写入日志的文本字符串以及C风格的控制字符"\n"和"\t"以实现换行与制表。文本中的引号和反斜杠应通过"\"来转义。

请求本身的情况将通过在格式字串中放置各种"%"转义符的方法来记录,它们在写入日志文件时,根据下表的定义进行转换:

格式字符串 描述
%% 百分号(Apache2.0.44或更高的版本)
%...a 远端IP地址
%...A 本机IP地址
%...B 除HTTP头以外传送的字节数
%...b 以CLF格式显示的除HTTP头以外传送的字节数,例如:当没有字节传送时显示'-'而不是0。
%...{Foobar}C 在请求中传送给服务端的cookie Foobar的内容。
%...D 服务器处理本请求所用时间,以毫秒为单位。
%...{FOOBAR}e 环境变量FOOBAR的值
%...f 文件名
%...h 远端主机
%...H 请求使用的协议
%...{Foobar}i 发送到服务器的请求头Foobar:的内容。
%...l 远端登录名(由identd而来,如果支持的话),除非IdentityCheck设为"On",否则将得到一个"-"。
%...m 请求的方法
%...{Foobar}n 来自另一个模块的注解Foobar的内容。
%...{Foobar}o 应答头Foobar:的内容。
%...p 服务器服务于该请求的标准端口。
%...P 为本请求提供服务的子进程的PID。
%...{format}P 服务于该请求的PID或TID(线程ID),format的取值范围为:pidtid (2.0.46及以后版本)
%...q 查询字符串(若存在则由一个"?"引导,否则返回空串)
%...r 请求的第一行
%...s 状态。对于内部重定向的请求,这个状态指的是原始请求的状态,---%...>s则指的是最后请求的状态。
%...t 时间,用普通日志时间格式(标准英语格式)
%...{format}t 时间,用strftime(3)指定的格式表示的时间。(默认情况下按本地化格式)
%...T 处理完请求所花时间,以秒为单位。
%...u 远程用户名(根据验证信息而来;如果返回status(%s)为401,可能是假的)
%...U 请求的URL路径,不包含查询字符串。
%...v 对该请求提供服务的标准ServerName
%...V 根据UseCanonicalName指令设定的服务器名称。
%...X 请求完成时的连接状态:
X = 连接在应答完成前中断。
+ = 应答传送完后继续保持连接。
- = 应答传送完后关闭连接。

(在1.3以后的版本中,这个指令是%...c,但这样就和过去的SSL语法:%...{var}c冲突了)

%...I 接收的字节数,包括请求头的数据,并且不能为零。要使用这个指令你必须启用mod_logio模块。
%...O 发送的字节数,包括请求头的数据,并且不能为零。要使用这个指令你必须启用mod_logio模块。

上表中的"..."在实际中可以什么也没有(例如:"%h %u %r %s %b"),也可以用来指定条目被包含的条件(如果条件不满足,它会被"-"来替换)。条件的格式是由一个HTTP状态码列表组成的,状态码前还可以加上"!"前缀。这样,格式串"%400,501{User-agent}i"只记录400错误(错误的请求)和501错误(没实现的功能)发生时的User-agent: ;"%!200,304,302{Referer}i"记录所有200,304,302以外的状态码发生时的Referer:

"<"和">"修饰符可以用来指定对于已被内部重定向的请求是选择原始的请求还是选择最终的请求。默认情况下,%s, %U, %T, %D, %r 使用原始请求,而所有其他的格式串则选择最终请求。例如,%>s 可以用于记录请求的最终状态,而%<u 则记录一个已经被内部重定向到非认证资源的请求的原始认证用户。

在2.0.46以前的版本中,%...r, %...i, %...o的内容会被完整的按原样记录,这主要是因为通用日志格式(Common Log Format)的需求。这种做法将导致客户端可以在日志中插入控制字符,所以你在处理这些日志文件的时候要特别小心。

出于安全考虑,从2.0.46版本开始,除了 "\\"\\ 进行转义、空白字符用C风格(\n, \t 等)进行转义以外,非打印字符和其他一些特殊字符将使用\xhh格式进行转义(hh是该字符的16进制编码)。

一些常见的格式串如下所示:

通用日志格式 (CLF)
"%h %l %u %t \"%r\" %>s %b"
带虚拟主机的通用日志格式
"%v %h %l %u %t \"%r\" %>s %b"
NCSA扩展/组合日志格式
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
Referer日志格式
"%{Referer}i -> %U"
Agent(Browser)日志格式
"%{User-agent}i"

注意,对该请求提供服务的服务器的正式主机名(ServerName)和侦听端口(Listen)分别由"%v"和"%p"来指定。这一点将忽略UseCanonicalName 指令的设置,因为否则日志分析程序会成倍地进行整个虚拟主机的匹配运算以决定实际上是哪个服务器在响应请求。

top

需要考虑的安全性问题

如果放置日志文件的目录对除了启动Apache服务以外的其他用户可写的话,可能会对系统的安全性造成威胁,具体的讨论请参见安全方面的提示

top

CookieLog 指令

说明设定针对cookies的日志文件名
语法CookieLog filename
作用域server config, virtual host
状态Base
模块mod_log_config
兼容性 反对使用本指令

CookieLog指令使用cookies作为日志文件名。文件是相对于ServerRoot目录的。包含本指令仅仅是为了保持与mod_cookies模块的兼容,并且反对使用。

top

CustomLog 指令

说明设定日志的文件名和格式
语法CustomLog file|pipe format|nickname [env=[!]environment-variable]
作用域server config, virtual host
状态Base
模块mod_log_config

CustomLog指令用来对服务器的请求进行日志记录。可以指定日志的格式,也可以使用环境变量根据请求的特征来自由地组织日志。

第一个参数指定了日志记录的位置,可以使用以下两种方式来设定:

file
相对于ServerRoot的日志文件名。
pipe
管道符"|"后面紧跟着一个把日志输出当作标准输入的处理程序路径。

安全:

如果这里用到了程序,那么这个程序是以启动httpd的用户来执行的。因此如果启动httpd的用户是root,那这个程序也是以root用户身份来启动;你需要确认这个程序是安全的。

注意

当在非UNIX平台上输入文件路径的时候,要特别注意即使平台本身是使用反斜杠来分隔路径的,在这里也只能使用正斜杠。通常在配置文件里只用正斜杠来分隔路径总是不会错的。

第二个参数指定了写入日志文件的内容。它既可以是由前面的LogFormat指令定义的nickname,也可以是直接按日志格式一节所描述的规则定义的format字符串。

例如:以下两组指令的结果是完全一样的:

# CustomLog with format nickname
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common

# CustomLog with explicit format string
CustomLog logs/access_log "%h %l %u %t \"%r\" %>s %b"

第三个参数是可选的,它根据服务器上特定的环境变量是否被设置来决定是否对某一特定的请求进行日志记录。如果这个特定的环境变量被设置(或者在"env=!name"的情况下,未被设置),那么这个请求就被日志所记录。

可以使用mod_setenvif和/或mod_rewrite模块来为每一个请求设置环境变量。例如:如果你想在服务器上将所有对GIF图片的请求记录在不同于主日志文件的另一个日志文件中,你可以使用下面的指令:

SetEnvIf Request_URI \.gif$ gif-image
CustomLog gif-requests.log common env=gif-image
CustomLog nongif-requests.log common env=!gif-image

或者为了复制旧有的RefererIgnore指令的行为,你可以使用下面的指令:

SetEnvIf Referer example\.com localreferer
CustomLog referer.log referer env=!localreferer

top

LogFormat 指令

说明 定义访问日志的记录格式
语法LogFormat format|nickname [nickname]
默认值LogFormat "%h %l %u %t \"%r\" %>s %b"
作用域server config, virtual host
状态Base
模块mod_log_config

本指令定义访问日志的记录格式。

LogFormat指令可以使用两种定义格式中的一种。在第一种格式中,指令只带一个参数,以定义后续的TransferLog指令定义的日志格式。这个唯一的参数可以按上述自定义日志格式小节所描述的format来定义。另外它也可以通过下述的方法使用nickname来引用之前的LogFormat某个定义的日志格式。

第二种定义LogFormat指令的格式中,将一个直接的format和一个nickname联系起来。这样在后续的LogFormatCustomLog指令中,就不用一再重复整个冗长的格式串。定义别名的LogFormat指令仅仅用来一个nickname,而不做其它任何事情--也就是说,它只是定义了这个nickname,它既没有实际应用这个别名,也不是把它设为默认的格式。因此,它不会影响后续的TransferLog指令。另外,LogFormat不能用一个nickname来定义另一个nickname。注意,别名不能包含百分号(%)。

例子

LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common

top

TransferLog 指令

说明指定日志文件的位置
语法TransferLog file|pipe
作用域server config, virtual host
状态Base
模块mod_log_config

本指令除不允许直接定义日志格式或根据条件进行日志记录外,与CustomLog指令有完全相同的参数和功能。实际应用中,日志的格式是由最近的非别名定义的LogFormat指令指定。如果没有定义任何日志格式,则使用通用日志格式。

例子

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
TransferLog logs/access_log