节选自《Apache源代码解析-基于Apache0.6.5》第四章。
4.1概述
我们开启Web服务后,我们可能关心几个事情,比如都有那些用户访问过我们的网站,都是在哪些时间段访问的,用户对我们的哪些页面感兴趣,我们网站的访问 量和流量如何,Apache运行过程中是否一切正常,都出过什么错误,当前Apache进程的进程号是多少等等。我们从何而知呢?这就需要Apache在 生命周期中对这些情况做一些记录。这就是Apache的日志文件。
Apache0.6.5共有三种日志:访问日志、错误日志和进程ID日志。其中访问日志以固定格式记录客户端的访问记录;错误日志记录了Apache运行过程中发生的各种错误信息;进程ID日志记录了最后一次运行Apache时,Apache进程的进程ID。
日志文件的相关操作通过源代码文件http_log.c完成。
4.2 背景知识
4.2.1 配置Apache
作为最为流行的Web服务器,Apache提供了丰富的配置选项方便管理员定制自己的Web服务器。这些配置选项默认保存在conf目录下的配置文件中。
本章以及后继几个章节围绕Apache的各个功能模块展开,而每个功能模块都和相应的配置指令相关,每个配置指令存在于约定俗成的配置文件中。
早期的(包括0.6.5版本)Apache拥有4个配置文件,各个配置文件的名字和功能如下所示:
httpd.conf 主配置文件,提供了最基本的服务器设置,如监听的端口,运行服务器所使用的用户角色等内容。
mime.types 用来标识不同文件对用的MIME类型。更多内容请参考第六章的描述。
srm.conf 服务器资源映射文件。设置如站点根目录位置等内容。
access.conf 服务器访问权限配置文件,用来控制不同用户和计算机对指定资源的访问控制。
这些配置文件内容可以分成两个部分,其中以井号(#)开头的行是注释行,Apache读取配置文件的时候会忽略这些行的内容;其它行为配置行,一般以配置指令开始。
一个典型的配置文件可能包含这样的内容:
# 我们配置Apache使用8181端口
Port 8181
现代的Apache把srm.conf、access.conf和httpd.conf三个配置文件的内容合并到了一个httpd.conf文件中,并在原有的配置指令基础上增加了很多新的配置指令,同时也兼容本书中描述的所有配置指令。
我们在这里对这些配置文件的功能先有一个大致的了解,在相关的章节里面会对各个配置文件的配置指令进行详细的描述。
4.2.2 HTTP状态码
当客户端向Apache请求资源的时候,Apache会给客户端一个3位数字的响应状态代码。称作HTTP状态码。状态码由RFC2616规范定义。
我们常见的状态码是200,表示服务器成功处理了请求。目前已经定义的状态码主要有5类,每类状态码的含义及其典型代表如下所示:
1 ××(临时响应)
如100,服务器返回此代码表示已经收到请求的一部分,正在等待其余部分
2 ××(成功)
如200,表示服务器成功处理了请求。
3 ××(重定向)
如304。一般浏览器都有缓存,如果浏览器请求的资源自上次请求后没有更改过,服务器会返回304状态码,浏览器使用本地缓存显示返回304状态码的资源。
4 ××(请求错误)
最常见的是401和404,401表示客户端请求的资源需要身份验证;404表示服务器未找到客户端请求的资源。
5 ××(服务器错误)
如500,表示服务器内部错误。
状态码的完整描述请参看:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Apache0.6.5可能返回9种状态码,它们的含义如下所示:
状态码 含义
200 服务器理解客户端请求意义并正确处理
302 客户端要请求的资源临时放到一个新地方了。应答中包含了资源的新地址
304 上次客户端获取数据后,数据没有改变,可以使用客户端本地缓存
400 错误请求 。请求的语法错误,服务器无法理解
401 未授权。客户端访问指定资源以前,必须通过服务器的授权
403 禁止访问 。不允许访问客户端请求的资源
404 找不到 找不到客户端请求的内容
500 服务器内部错误
501 服务器不支持实现请求所需要的功能。
503 服务器由于维护或者负载过重未能应答。
4.2.3 重定向
如果您做过网站开发,一定对重定向不陌生,您可以通过脚本语言来设置,让浏览器在不需要用户干预的情况下跳转到某个新的页面。
Apache也提供了针对重定向的设置选项(下节中将要描述的ErrorDocument指令),以便在特定的情况下让浏览器直接跳转到新的页面或者直接发送新的页面给浏览器。
网站管理员设置重定向有什么意义呢?
我们可以做一个实验,使用浏览器访问我们网站上并不存在的页面,这时服务器会发送一个404状态码给客户端浏览器,此时浏览器会按照自己预先定义的样式来显示一个错误页面,这个页面千篇一律,毫无新意,也没有太多的提示性,典型的样子类似于:
这个页面简单地说明了用户操作中发生的问题,但以现代的眼光连看,对用户不够友好,其实我们可以做出来更漂亮、更有个性或更有提示性的404错误页面给用户。如下图就是一个个性化的404页面:
这个404页面属于怀旧型,好像让我们有看到了经典的Windows蓝屏。
Apache在die函数中完成对重定向的处理,这个过程如下所述:
1. 管理员通过修改配置文件srm.conf设置在特定条件下要跳转的新位置
2. Apache读取配置文件并初始化在http_config.c中定义的response_code_strings字符串数组。
3. 在特定条件发生的时候(如用户请求的页面不存在的时候),Apache查看response_code_strings对应的错误信息是否是一个URL
4. 如果对应的信息是一个内部URL(指向本站内部资源的URL,以字符’/’开头,如/res/404.html),则Apache直接将客户端的请求转换成对这个内部URL的请求,将其内容发送给客户端。
5. 如果对应的信息是一个外部URL(指向本站外的资源,如http://www.otherwebsit.com /some.html),则向客户端发送302状态码,同时给出这个外部URL的地址。浏览器接收到302状态码和对应的URL地址时,一般会直接向服务 器发送一个新的、针对给定URL的资源请求。
6. 如果对应的信息是一个错误的URL,则给客户端发送服务器错误状态码
7. 如果response_code_strings中的信息不是一个URL,而是错误提示信息,则将错误提示信息作为页面内容发送给客户端。
Apache还有一个重定向指令Redirect,我们将在第五章中讲解。
4.3日志文件配置指令
这里面涉及到两个配置文件中的4个配置指令。分别是srm.conf文件中的ErrorDocument指令;httpd.conf文件中的ErrorLog指令、TransferLog指令和PidFile指令。下面分别介绍它们:
1. ErrorLog 指令
语法:ErrorLog
file
功能:指定错误日志文件的存放位置。一般设置成相对于SERVER_ROOT的路径
示例:ErrorLog logs/error_log
上例说明,错误日志文件为SERVER_ROOT/logs/error_log。
2. TransferLog 指令
语法:TransferLog
file
功能:指定访问日志文件的存放位置。一般设置成相对于SERVER_ROOT的路径
示例:TransferLog logs/access_log
上例说明,访问日志文件为SERVER_ROOT/logs/ access
_log。
3. PidFile 指令
语法:PidFile
filename
功能:指定进程 ID 记录文件的位置
示例: PidFile logs/httpd.pid
上例说明,进程 ID 日志文件为 SERVER_ROOT/logs/httpd.pid 。
4. ErrorDocument 指令
这个指令和服务器日志没有什么关系,但是作为http_log.c文件处理的一部分,我们也在这里说明一下。
语法:ErrorDocument
错误代码文档
功能:定义了当遇到错误的时候服务器将给客户端什么样的回应
示例:ErrorDocument 500 "The server made a boo boo.
上例说明,当服务器发生500错误的时候,客户端收到的信息里面将包含The server made a boo boo这段文字(也会有一些服务器已经定义的错误信息)。
当用户的请求遇到问题或错误的时候,Apache可以通过以下四种方式应答用户:
1.使用服务器本身的错误信息回应用户。
2.在1.的基础上附加配置文件定义的信息回应用户。
3.重定向到一个本地URL
4.重定向到一个外部URL
后面三种情况都是通过ErrorDocument
指令来配置的。如:
ErrorDocument 500
"The server made a boo boo %s
ErrorDocument 404 /error/404.html
ErrorDocument 503 http://www.yourdomain.com/error/503.html
在
"The server made a boo boo %s中%s将被设置成失败原因
4.4 配置实践
下面我们通过实例来分别验证上节中提到的4个设置指令。
1. ErrorLog
此指令在httpd.conf文件中设置:
ErrorLog logs/error_log
这条设置指令表示Apache的错误日志文件为/home/devel/apache_0.6.5/logs/error_log。运行以下指令集来查看该日志文件的输出:
[devel@RIZI src]$ pwd
/home/devel/apache_0.6.5/src
[devel@RIZI src]$ ps x
PID TTY STAT TIME COMMAND
5010 ? S 0:00 sshd: devel@pts/1
5011 pts/1 Ss 0:00 -bash
5178 ? Ss 0:00 ./httpd
5204 pts/1 R+ 0:00 ps x
[devel@RIZI src]$ kill 5178
[devel@RIZI src]$ tail /home/devel/apache_0.6.5/logs/error_log
[Mon May 4 15:59:32 2009] httpd: caught SIGTERM, shutting down
[devel@RIZI src]$
从上面我们可以看到,当我们Kill掉Apache的时候,Apache接受到了系统发给它的SIGTERM信号,关闭服务并记录了一条错误日志。
2. TransferLog
此指令在httpd.conf文件中设置:
TransferLog logs/access_log
这条指令表示Apache的访问日志文件为/home/devel/apache_0.6.5/logs/ access_log,运行您的Apache,打开浏览器,在地址栏输入您的Apache提供服务的站点首页,如http://11.22.33.44:81/index.html。可以在Linux命令行中查看该日志文件的内容:
[devel@RIZI apache_0.6.5]$ tail /home/devel/apache_0.6.5/logs/ access_log
222.131.235.66 - - [04/May/2009 16:02:17 +0800] "GET /index.html HTTP/1.1" 200 44
[devel@RIZI apache_0.6.5]$
从上面的操作我们可以看出,当我们访问站点首页的时候,Apache在给客户端发送其请求内容的同时记录了一条访问日志。包括客户端的IP、访问时间、访问方法、访问内容、使用的协议版本、状态码和发送的字节数等信息。
3. PidFile
此指令在httpd.conf文件中设置:
PidFile logs/httpd.pid
这条指令表示Apache的进程ID日志文件为/home/devel/apache_0.6.5/logs/httpd.pid,运行您的Apache,在Linux命令行中输入如下的指令序列:
[devel@RIZI apache_0.6.5]$ tail /home/devel/apache_0.6.5/logs/ httpd.pid
2905
[devel@RIZI apache_0.6.5]$ps x
PID TTY STAT TIME COMMAND
2905 ? Ss 0:00 ./httpd
10248 pts/2 R+ 0:00 ps x
……
4. ErrorDocument
该指令在srm.conf文件中设置,我们在srm.conf文件最后添加如下内容:
ErrorDocument 404 http://www.google.cn
打开浏览器,在地址栏输入http://www.yourdomain.com:port/~usernotexit ,我们可以看到,浏览器实际打开的地址是我们设定的http://www.google.cn 。
注意:请将www.yourdomain.com 替换成您服务器的域名或IP,port部分填写您的Apache服务器监听的端口号。
4.5 代码注释
限于篇幅,注释代码部分请参看本书官网。
节选自《Apache源代码解析-基于Apache0.6.5》第四章。