一、解析访问日志
apache 的访问日志记载着大量的信息,学会高效快捷的读出其中关键信息对我们的工作有极大帮助。
如果Apache的安装方式是默认安装,服务器一运行就会有两个日志文件生成。
这两个文件是 access_log(在Windows上是access.log)
error_log (在Windows上是error.log)
采用默认安装方式时,这些文件可以在/usr/local/apache/logs下找到;对于Windows系统,这些日志文件将保存在Apache安装目录的logs子目录。不同的包管理器会把日志文件放到各种不同的位置,所以你可能需要找找其他的地方,或者通过配置文件查看这些日志文件配置到了什么地方。
正如其名字所示,访问日志access_log记录了所有对Web服务器的访问活动。下面是访问日志中一个典型的记录
218.19.140.242 - - [03/Feb/2015:23:14:24 +0800] "GET / HTTP/1.1" 200 2*
分为7个部分:
(1)第一项信息是远程主机的地址,即它表明访问网站的究竟是谁。(可以要求apache查出所有的主机名字,并在日志文件中用主机名字来替代IP地址,但这种做法会极大的影响服务器记录日志的速度,从而降低整个网站的效率,不值得推荐)。
然而,如果确实有必要让apache找出远程主机的名字,可以使用如下指令:
HostNameLookups on
如果HostNameLookups设置成double而不是on,日志记录程序将对它找到的主机名字进行反向查找,验证该主机名字确实指向了原来出现的IP地址。
(2)上例日志记录的第二项是空白,用一个“-”占位符替代。实际上绝大多数时候这一项都是如此。这个位置用于记录浏览者的标识,这不只是浏览者的登录名字,而是浏览者的email地址或者其他唯一标识符。这个信息由identd返回,或者直接由浏览器返回。(为了避免用户的邮箱被垃圾邮件骚扰,第二项就用“-”取代了)。
(3)日记记录的第三项也是空白。这个位置用于记录浏览者进行身份验证时提供的名字。当然,如果网站的某些内容要求用户进行身份验证,那么这项信息室不会空白的。但是,对于大多数网站来说,日志文件的大多数记录中这一项仍旧是空白的。
(4)日志记录的第四项是请求的时间。这个信息用方括号包围,而且采用“公用日志格式”或者“标准英文格式”。因此,时间信息最后的“-0400”表示服务器所处时区位于UTC之前的4小时。
(5)日志记录的第五项信息或许是整个日志记录中最有用的信息,它告诉我们服务器受到的是一个什么样的请求。该项信息的典型格式是“METHOD RESOURCE PROTOCOL”即“方法 资源 协议”(我们通常进行日志监控的时候,主要也是看这项内容)。例子中METHOD是GET,还有POST、HEAD等其他类型,主要是这三种。
RESOURCE是指浏览者向服务器请求的文档或者URL。在这个例子中,浏览者请求的是“/”,即网站的根或者主页。大多数情况下,“/”指向DocumentRoot目录的index.html文档,但根据服务器配置的不同也可能指向其他文件。
PROTOCOL通常是HTTP,然后再加上版本号。
(6)日志的第六项信息室状态代码。它告诉我们请求是否成功,或者遇到了什么样的错误。大多数时候这项是200,它表示服务器已经成功的响应浏览器的请求,一切正常。(以2开头的状态码表示成功,以3开头的状态码表示由于各种不同的原因用户请求被重定向到了其他位置,以4开头的状态代码表示客户端存在某种错误,以5开头的状态代码表示服务器遇到了某个错误)。
(7)日志记录的第七项表示发送客户端的总字节数。它告诉我们传输是否被打断(即该数值是否和文件的大小相同)
这里可以使用linux 命令 分析 access日志1.以url进行分析
一般的日志格式
10.0.7.99 - - [28/Dec/2015:22:36:10 -0800] "GET /install/ HTTP/1.1" 200 512
1 2 3 4 5 6 7 8 9 (以空格分段)
1.以url进行分析
统计某url xxx/index ,一天的访问次数
直接查找、统计
# cat access_log |grep xxx/index | wc -l
两次精确查找、统计
# cat access_log |grep 'xxx/index' | grep '/images/index/e1.gif'|wc|awk '{print $1}'
统计日志中访问超过100次的页面
#cat access_log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less
#cat access_log |awk '{print $7}'| sort | uniq -c | awk '{if($1>100) print $0}' | less
查看最近1万条访问中最高的页面
#cat access_log |tail -10000|awk '{print $7}'|sort|uniq -c|sort -nr|less
?前五天的访问次数最多的网页
#cat access_log|awk '{print $7}'|uniq -c |sort -n -r|head -20
或者
awk '{print $11}' access_log | sed 's/^.*cn.∗.∗\"/\1/g' | sort | uniq -c | sort -rn | head
awk 首先将每条日志中的访问页面抓出来,如日志格式被自定义过,可以 -F 定义分隔符和 print指定列;
sed 's/^.*cn.∗.∗\"/\1/g' 将 .*cn.∗.∗\" 字符串用 \1 字符串替代,末端的g表示在行内进行全局替换,即某行 出现多个要替换字符,则全部替换;
用sed的替换功能将”http://www.a.cn/common/index.php”替换成括号内的内容 ”http://www.a.cn(/common/index.php)”
sed 's/^.*cn/(.*/)/"//1/g'
sort进行初次排序,为的使相同的记录排列到一起;
upiq -c 合并重复的行,并记录重复次数;
sort -nr按照数字进行倒叙排序;
?当前WEB服务器中连接次数最多的ip地址
#netstat -ntu |awk '{print $5}' |sort | uniq -c| sort -nr
?查看日志中访问次数最多的前10个IP
以空格分段取第一字段 去重复统计总数
#cat access_log |cut -d ' ' -f 1 |sort |uniq -c | sort -nr | awk '{print $0 }' | head -n 10 |less
查看文件名 升序 按数字降序 打印整行 查看前十 分页显示
或者
awk '{print $1}' access_log | sort | uniq -c | sort -nr | head -n 10
awk 首先将每条日志中的IP抓出来,如日志格式被自定义过,可以 -F 定义分隔符和 print指定列;
sort进行初次排序,为的使相同的记录排列到一起;
upiq -c 合并重复的行,并记录重复次数。
sort -nr按照数字进行倒叙排序。
head进行前十名筛选;
?查看日志中出现100次以上的IP
# cat access_log |cut -d ' ' -f 1 |sort |uniq -c | awk '{if ($1 > 100) print $0}' | sort -nr |less
第一字段大于100 则输出整行
? 某页面 某段时间 访问次数
cat access_log |grep '/yunshu.php?r=register/index' |awk '{if($4 ~"02/Nov/2016:15:") print $1}'| wc -l
?从日志里查看该ip在干嘛
#cat access_log | grep 218.66.36.119| awk '{print $1"\t"$7}' | sort | uniq -c | sort -nr | less
?列出传输时间超过 30 秒的文件
#cat access_log|awk '($NF > 30){print $7}' |sort -n|uniq -c|sort -nr|head -20
NF表示最后一个域,当其大于30时 输出第七字段 (需要修改access 日志记录格式 增加 时间字段)
?列出最最耗时的页面(超过60秒的)
#cat access_log |awk '($NF > 60 && $7~/\.php/){print $7}' |sort -n|uniq -c|sort -nr|head -100
? 访问次数最多的几个分钟
awk '{print $4}' access_log | cut -c 14-18 | sort|uniq -c | sort -nr | head
awk 首先将每条日志中的 访问页面 抓出来 [29/Sep/2014:10:45:43
cut -c 14-18 再次将字符串中 14-18值抓出 10:45
这里再来演示一种分析日志方法
日志格式:
222.163.80.18 - - [06/Jun/2016:00:01:27 +0800] "GET http://www.iyunshu.com/ HTTP/1.1" 200 62341 "-" "Mozilla/5.0 (Macintosh; Intel Mac
ip 时间 方法 URL 协议 状态 大小 来源 客户端信息
OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36 JianKongBao Monitor 1.1" "NONE" "NONE"
攻击类似 攻击判定
通过linux命令来过滤,把这个日志文件导入到Linux系统下,然后
?查看哪些ip访问的多
zcat 文件名 |grep http://www.xxx.com | awk '{print $1}' | sort |uniq -c |sort -rn|head
?查 某个IP对应的User-Agent
zcat 文件名 |grep 网址|awk '{if($1~" 66.249.64.243")print $0}' |awk -F \" '{print $6}'|sort|uniq -c|sort -rn|head
如果匹配第一个域 是 66.249.64.243 则输出整行 以“为分隔 输出第六个域
二、配置访问日志
apache中日志记录格式主要有两种,普通型和复合型,安装时默认使用common类型日志记录访问信息,
1. 配置访问日志格式主要有两个参数 即LogFormat指令和CustomLog指令
LogFormat指令 定义格式并为格式指定一个名字,以后我们就可以直接引用这个名字。
CustomLog指令 设置日志文件,并指明日志文件所用的格式(通常通过格式的名字)。
2. 在apache的配置文件httpd.conf中,有几行是这么配置的:
LogFormat "%h %l %u %t "%r" %>s %b" common 定义格式 和 名字
CustomLog "logs/access.log" common 使用此格式 存放位置(普通文件记录)
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 定义格式 和 名字
CustomLog logs/access_log combined 使用此格式 存放位置(复合日志记录)
指定了日志的目录路径./logs/,指定了日志的格式,默认common。
common格式是通过:LogFormat "%h %l %u %t \"%r\" %>s %b" 定义的。
%h %l %u %t \"%r\" %>s %b
远端主机 远端登录名 远程用户名 时间 请求第一行 状态 传送字节
combined格式通过:LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""定义的
%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"
远端主机 远端登录名 远程用户名 时间 请求第一行 状态 传送字节 请求来源
客户端浏览器提供的浏览器识别信息
这里看两个实例
common型记录:
10.0.7.99 - - [31/May/2016:11:34:12 +0800] "GET / HTTP/1.1" 200 144
combined型记录:
10.0.7.99 - - [31/May/2016:14:33:30 +0800] "GET / HTTP/1.1" 200 144 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.6.2000 Chrome/30.0.1599.101 Safari/537.36"
common型记录:
123.160.94.29 - - [03/Jun/2016:22:05:39 +0800] "GET /114/static/images/search/baidu.gif HTTP/1.1" 200 10383
combined型记录:
123.160.94.29 - - [03/Jun/2016:22:05:39 +0800] "GET /114/static/images/search/baidu.gif HTTP/1.1" 200 10383 "http://120.76.121.147/114/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.9.2.1000 Chrome/39.0.2146.0 Safari/537.36"
这里具体分析一下浏览器标识信息:
User-Agent是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA。用较为普通的一点来说,是一种向访问网站提供你所使用的 浏览器类型 、 操作系统 及版本、CPU 类型、浏览器渲染引擎、浏览器语言、浏览器插件等信息的标识。 UA字符串 在每次浏览器 HTTP 请求时发送到服务器!
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit /537.36 (KHTML, like Gecko) Maxthon/4.4.6.2000
64位操作系统 排版引擎 浏览器类型
Chrome/30.0.1599.101 Safari/537.36"
Mozilla/5.0: 历史太长,就是标识浏览器用的(多数浏览器都这样标识自己,几乎无意义)
(Windows NT 6.1; WOW64):
Windows NT 6.1 对应操作系统windows 7
Windows NT 6.0 对应操作系统 windows vista
Windows NT 5.2 对应操作系统 windows 2003
Windows NT 5.1 对应操作系统 windows xp
Windows NT 5.0 对应操作系统 windows 2000
双引号里面的格式字符串代表特定的信息。
apache格式字符串及其含义:
有时候我们只想在日志中记录某些特定的、已定义的信息,这时就要用到“…”。如果在“%”和变量之间放入了一个或者多个HTTP状态代码,则只有当请 求返回的状态代码属于指定的状态代码之一时,变量所代表的内容才会被记录。例如,如果我们想要记录的是网站的所有无效链接,那么可以使用:
LogFormat %404{Referer}i BrokenLinks
反之,如果我们想要记录那些状态代码不等于指定值的请求,只需加入一个“!”符号即可:
LogFormat %!200U SomethingWrong
符号解析:
%% 百分号(Apache2.0.44或更高的版本)
%a 远端IP地址
%A 本机IP地址
%B 除HTTP头以外传送的字节数
%b 以CLF格式显示的除HTTP头以外传送的字节数,也就是当没有字节传送时显示'-'而不是0。
%{Foobar}C 在请求中传送给服务端的cookieFoobar的内容。
%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的取值范围为:pid和tid(2.0.46及以后版本)以及hextid(需要APR1.2.0及以上版本)
%q 查询字符串(若存在则由一个"?"引导,否则返回空串)
%r 请求的第一行
%s 状态。对于内部重定向的请求,这个状态指的是原始请求的状态,---%>s则指的是最后请求的状态。
%t 时间,用普通日志时间格式(标准英语格式)
%{format}t 时间,用strftime(3)指定的格式表示的时间。(默认情况下按本地化格式)
%T 处理完请求所花时间,以秒为单位。
%u 远程用户名(根据验证信息而来;如果返回status(%s)为401,可能是假的)
%U 请求的URL路径,不包含查询字符串。
%v 对该请求提供服务的标准ServerName。
%V 根据UseCanonicalName指令设定的服务器名称。
</span><span style="font-size:18px;">
CustomLog logs/referer_log referer 也可以使用分开 来源与代理 的格式来记录
CustomLog logs/agent_log agent
可以简单地在配置文件中用多个CustomLog指令来建立多文件访问日志。如下例,既记录基本的CLF信息,又记录提交网页和浏览器的信息,最后两行CustomLog示范了如何模拟ReferLog和AgentLog指令的效果。
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common
CustomLog logs/referer_log "%{Referer}i -> %U"
CustomLog logs/agent_log "%{User-agent}i"
apache日志管理
web服务器日志轮循比较好的方式有三种:
第一种方法是利用Linux系统自身的日志文件轮循机制:logrotate;
第二种方法是利用apache自带的日志轮循程序rotatelogs;
第三种是使用在apache的FAQ中推荐发展已经比较成熟的一个日志轮循工具cronolog。
rotatelogs
相关说明:按照设定格式生成 日志文件
rotatelogs [ -l ] logfile [ rotationtime [ offset ]] | [ filesizeM ]
选项:
-l 使用本地时间代替GMT时间作为时间基准。
注意:在一个改变GMT偏移量(比如夏令时)的环境中使用-l会导致不 可预料的结果。
logfile 它加上基准名就是日志文件名。如果logfile中包含"%",则它会被视为用于strftime()的格式字符串;否则 它会被自动加上以秒为单位的".nnnnnnnnnn"后缀。这两种格式都表示新的日志开始使用的时间。
rotationtime 日志文件滚动的以秒为单位的间隔时间。
offset 相对于UTC的时差的分钟数。如果省略,则假定为"0"并使用UTC时间。
比如,要指定UTC时差为"-5小时"的地区的当地时间,则此参数应为"-300"。
中国的时差要比美国多8个小时也就是480分钟,所以要加上480分钟
filesizeM 指定以filesize M文件大小滚动,而不是按照时间或时差滚动。
举例:
CustomLog "|/usr/sbin/cronolog /logs/access_www_%Y%m%d.log" combined
日志文件名称
CustomLog "|/usr/bin/rotatelogs /logs/access_www_%Y%m%d%H%M.log 86400" combined
日志文件名称年、月、日、时、分 分割时间 86400=1天
CustomLog "|/usr/sbin/rotatelogs /var/log/accesslog.%Y%m%d%H 7200 480" common
每7200秒 生成一个日志 设置时差
CustomLog "|/usr/sbin/rotatelogs /var/log/accesslog.%Y%m%d%H 5M" common
以5m大小 生成一个日志
组合方式:
CustomLog "|/usr/local/bin/rotatelogs /var/log/access_log 86400 400M" combined
86400 ---日志滚动的时间是一天
400 ---日志文件最大400M就滚动
combined ---采用复合格式
定期删除日志:
然后建立清除日志文件的shell脚本,文件名为clean_log
#! /bin/bash
logdir=/var/log/httpd
cd ${logdir}
declare -i filesum=`ls access_log.* | wc -l`
declare -i delnum=$filesum-3
if [ "${delnum}" -ge 1 ];then
rm -rf `ls -tr access_log.* | head -${delnum}`
fi
chmod 755 clean_log
这样就保留了最近3天的日志文件。
建立自动化任务
01 04 * * * /usr/local/crontab/clean_log
ok,搞定,就这么简单。这样你就不用不必为日见增大的日志文件烦恼了!