研究学习 Linux Shell 的系列文章.
这篇文章主要讲使用 Shell 脚本进行日志分析.
1. 常见日志文件
1. 系统
/var/log/messages
:系统主日志文件/var/log/secure
:认证、安全/var/log/dmesg
:和系统启动相关
2. 应用
access.log
:nginx访问日志mysqld.log
:mysql运行日志xferlog
:和访问FTP服务器相关
3. 程序脚本
- 开发语言:C、C++、java、php
- 框架:Django、MVC、Servlet
- 脚本语言:Shell、Python
2. 相关知识
2.1 nginx 的 log_format 介绍
$ cat /usr/local/nginx/logs/access.log
$ cat /usr/local/nginx/conf/nginx.conf | grep -A 2 log_format
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
2.2 http 状态码介绍
- 1** 信息,服务器收到请求,需要请求者继续执行操作
- 2** 成功,操作被成功接收并处理
- 3** 重定向,需要进一步的操作以完成请求
- 4** 客户端错误,请求包含语法错误或无法完成请求
- 5** 服务器错误,服务器在处理请求的过程中发生了错误
2.3 脚本功能
本文以 nginx 的 access.log
为例,介绍日志文件分析脚本. 该脚本实现以下两个功能.
- 功能一:分析 HTTP 状态码在 100-200、200-300、300-400、400-500、500以上,这五个区间的请求条数.
- 功能二:分析日志中 HTTP 状态码为 404、500 的请求条数.
查看请求 IP 的访问次数,按降序排序:
$ cat /usr/local/nginx/logs/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | more
取 http 状态码,由于文本存在不对齐情况,难以取得完整数据:
$ tail -n 200 /usr/local/nginx/logs/access.log | awk '{print $9}'
取到所有请求的 http 协议类型和 http 状态码:
$ cat /usr/local/nginx/logs/access.log | grep -ioE "HTTP\/1\.[1|0]\"[[:blank:]][0-9]{3}"
3. 脚本实现
#!/bin/bash
#Program function: Nginx's log analysis
resettem=$(tput sgr0)
Logfile_path='/usr/local/nginx/logs/access.log'
Check_http_status()
{
Http_status=(`cat /usr/local/nginx/logs/access.log | grep -ioE "HTTP\/1\.[1|0]\"[[:blank:]][0-9]{3}" | awk -F"[ ]+" '{
if($2>100&&$2<200)
{i++}
else if($2>=200&&$2<300)
{j++}
else if($2>=300&&$2<400)
{k++}
else if($2>+400&&$2<500)
{n++}
else if($2>=500)
{p++}
}END{
print i?i:0,j?j:0,k?k:0,n?n:0,p?p:0,i+j+k+n+p
}'
`)
echo -e '\e[32m'"The number os http status[100+]:" ${resettem} ${Http_status[0]}
echo -e '\e[32m'"The number os http status[200+]:" ${resettem} ${Http_status[1]}
echo -e '\e[32m'"The number os http status[300+]:" ${resettem} ${Http_status[2]}
echo -e '\e[32m'"The number os http status[400+]:" ${resettem} ${Http_status[3]}
echo -e '\e[32m'"The number os http status[500+]:" ${resettem} ${Http_status[4]}
echo -e '\e[32m'"All request numbers:" ${resettem} ${Http_status[5]}
}
Check_http_code()
{
Http_code=(`cat /usr/local/nginx/logs/access.log | grep -ioE "HTTP\/1\.[1|0]\"[[:blank:]][0-9]{3}" | awk -v total=0 -F '[ ]+' '{
if ($2!="")
{code[$2]++;total++}
else
{exit}
}END{
print code[404]?code[404]:0,code[403]?code[403]:0,total
}'
`)
echo -e '\e[32m'"The number of http status [404]" ${resettem} ${Http_code[0]}
echo -e '\e[32m'"The number of http status [403]" ${resettem} ${Http_code[1]}
echo -e '\e[32m'"All request numbers:" ${resettem} ${Http_code[2]}
}
Check_http_status
Check_http_code