
image.png
下面脚本中有提示,怀疑是管道过长,但是数据只有几百kb,感觉不应该
#!/bin/bash
# 统计日志名或目录名
export LogName=""
# 屏幕显示每项数据的最大数量
export NUM=10
# 保存数据文件的目录
export SaveDir=""
# 保存需要统计的时间(天)
export Time=1
#### Define color
Green() {
echo -e "\033[1;42m $* \033[0m"
}
Red() {
echo -e "\033[1;31m $* \033[0m"
}
Yellow() {
echo -e "\033[1;33m $* \033[0m"
}
# 负载统计
LBAnalyse(){
Green '负载统计:'
grep " TCP " $1 &> /dev/null
if [ $? -eq 0 ];then
awk -F \" '{
if($1~"TCP")
{
ip[$2]++
}
}
END{
if(length(ip)!=0)
{
for(i in ip)
{
print ip[i] "\t" i
}
}
else
{
print "No Data!"
}
}' $1 >> ./$SaveDir/${1##*/}-$FUNCNAME.log
head ./$SaveDir/${1##*/}-$FUNCNAME.log
else
echo "No Data!"
fi
}
# 日志中IP访问量统计,降序:
RemoteIPCount(){
Green "日志中IP访问量TOP${NUM}统计,降序:"
awk '{
if($1 ~ ",")
{
ip[$1" "$2]++
}
else
{
ip[$1]++
}
}
END{
if(length(ip)!=0)
{
for(i in ip)
{
print ip[i] "\t" i
}
}
else
{
print "No Data!"
}
}' $1 | sort -nr -k 1 >> ./$SaveDir/${1##*/}-$FUNCNAME.log
head -n $NUM ./$SaveDir/${1##*/}-$FUNCNAME.log
}
# 生成匹配日期
CreateMatchDays(){
Days[0]=`date "+%d/%b/%Y"`
if [ $1 -gt 1 ]; then
for i in `seq $(($1-1))`
do
Days[i]=`date -d "-${i} days" "+%d/%b/%Y"`
done
else
Red "错误天数!"
exit 18
fi
for i in ${Days[*]}
do
echo $i
done
}
# 生成最近一日的日志数据 $1 时间长度 $2 操作的日志文件
CreateXdaysLog(){
# 创建截取日志存储目录
[ -d ${SaveDir} ] && rm -rf ${SaveDir}
mkdir ${SaveDir}
for day in `CreateMatchDays $1 | sort`
do
grep "${day}" ${2} >> ${SaveDir}/${2##*/}
done
}
# 访问返回状态统计:
RequestResponse() {
Green '所有访问返回状态统计:'
awk '
BEGIN{
succ=0
sum=0
}
{
if($0~" HTTP")
{
for(i=7;i<NF;i++)
{
if($i~"HTTP/")
{
ip[$(i+1)]++
continue
}
}
}
else
{
if($0~"TCP")
{
ip[$5]++
}
else
{
ip[$8]++
}
}
}
END{
if(length(ip)!=0)
{
for(i in ip)
{
if(i<400)
{
succ=succ+ip[i]
sum=sum+ip[i]
}
else
{
sum=sum+ip[i]
}
print ip[i] "\t" i
}
print "总次数:" sum
print "成功数:" succ
print "成功率:" succ/sum*100 "%\t" "失败率:" (1-succ/sum)*100 "%"
}
else
{
print "No Data!"
}
}' $1 | sort -nr -k 1 >> ./$SaveDir/${1##*/}-$FUNCNAME.log
cat ./$SaveDir/${1##*/}-$FUNCNAME.log
}
# 访问资源统计:1、各个api的访问访问总数统计;2、各个api返回状态统计,成功率与失败率;
RequestAPIAnalyse() {
Green "资源访问TOP${NUM}统计:"
awk '{
if($0~" HTTP")
{
for(i=7;i<NF;i++)
{
if($i~"HTTP/")
{
src[gensub(/?.*/, "", "g", $(i-1))]++
}
}
}
}
END{
if(length(src)==0)
{
print "No Data!"
}
else
{
for(s in src)
{
print src[s] "\t" s
}
}
}' $1 |sort -nr -k 1 >> ./$SaveDir/${1##*/}-$FUNCNAME.log
head -n ${NUM} ./$SaveDir/${1##*/}-$FUNCNAME.log
### 奇怪问题,如果把 >> 改成tee,再在tee命令后面加上head,tee马上输出就不稳定,只是偶尔准确。是管道太多了?
# Yellow `wc -l ./$SaveDir/${1##*/}-$FUNCNAME.log `
awk '{
if($0~" HTTP")
{
for(i=7;i<NF;i++)
{
if($i~"HTTP/")
{
src[gensub(/?.*/, "", "g", $(i-1))]++
}
}
}
}
END{
if(length(src)==0)
{
print "No Data!"
}
else
{
for(s in src)
{
print src[s] "\t" s
}
}
}' $1 |sort -nr -k 1 >> ./$SaveDir/${1##*/}-$FUNCNAME.2.log
# Yellow `wc -l ./$SaveDir/${1##*/}-$FUNCNAME.2.log `
head -n $NUM ./$SaveDir/${1##*/}-$FUNCNAME.2.log
Yellow "接口访问分类统计中..."
# 每个接口访问状态统计:
while read i
do
echo "api统计:$i" >> ./$SaveDir/${1##*/}-API_RESPONSE_PERCENT.log
Api=`echo "$i" | awk '{print $2}'`
Api=${Api/$/\\\\$}
awk -v api=" ${Api}(?|[[:blank:]])" '
BEGIN{
sum=0;succ=0
}
{
if($0~api)
{
for(i=6;i<NF;i++)
{
if($i~"HTTP/")
{
ip[$(i+1)]++
continue
}
}
}
}
END{
for(i in ip)
{
if(i<400)
{
succ=succ+ip[i]
sum=sum+ip[i]
print ip[i] "\t" i
}
else{
sum=sum+ip[i]
print ip[i] "\t" i
}
}
{
print "成功数:"succ
print "成功率:" succ/sum*100"%\t" "失败率:" (1-succ/sum)*100 "%"
}
}' $1 |sort >> ./$SaveDir/${1##*/}-API_RESPONSE_PERCENT.log
echo -e "--------------------------------------------------------------------" >> ./$SaveDir/${1##*/}-API_RESPONSE_PERCENT.log
done < ./$SaveDir/${1##*/}-$FUNCNAME.log
}
# 访问客户端统计:
ClientBrower(){
Green "用户使用浏览器分类TOP${NUM}统计:"
awk -F \" '{
if($0~"HTTP")
{
client[$6]++
}
}
END{
if(length(client)!=0)
{
for(c in client)
{
print client[c] "\t" c
}
}
else
{
print "No Data!"
}
}' $1 |sort -nr -k 1 >> ./$SaveDir/${1##*/}-$FUNCNAME.log
head -n $NUM ./$SaveDir/${1##*/}-$FUNCNAME.log
}
# 分割线
Split(){
Yellow "-------END-------END-------END-------END-------END-------"
}
Usage(){
echo -e "Usage: $0 -f log_path [other options]
\t-f: path of log file
\t-t: how many days[default by 1 day]
\t-h: for help"
exit 5
}
# $1 Time $2 log
Analyse(){
Red "统计"$1"天的日志信息:" $2
CreateXdaysLog $1 $2
if [ -s ${SaveDir}/${2##*/} ];then
RemoteIPCount ${SaveDir}/${2##*/}
RequestResponse ${SaveDir}/${2##*/}
LBAnalyse ${SaveDir}/${2##*/}
RequestAPIAnalyse ${SaveDir}/${2##*/}
ClientBrower ${SaveDir}/${2##*/}
Split
else
Red ${SaveDir}/${2##*/} "文件不存在或者该时间段没有内容!"
Split
fi
}
# 获取日志名称或者目录
# t means days; f means logfile; h for help
GetOpts(){
while getopts :f:ht: opt
do
case "${opt}" in
f)
[ ! -e $LogName ] && Red "错误的路径!" && exit 19
LogName=${OPTARG}
Yellow "分析日志:${LogName}"
;;
t)
Time=${OPTARG}
Yellow "统计天数:${Time}"
;;
*)
Usage
;;
esac
done
# for test
# LogName="logs/forfaiting.access.log"
}
main(){
GetOpts $*
[ -L alogs ] && rm alogs
SaveDir="${Time}_days_tmp_logs-`date +%F_%H%M%S`"
ln -s ${SaveDir} alogs
# 分析谋具体日志
Analyse ${Time} ${LogName}
# 以下增加分析目录下所有access日志
# tag=${LogName##*/}
# Red "即将统计"${Time}"天以内的日志:" ${LogName}
# if [ "$tag" == "" ];then
# 分析目录内访问日志
# for LOG_NAME in `ls ${LogName%/*}/*acc*log`
# do
# Analyse ${Time} ${LOG_NAME}
# done
# else
# 分析指定名称日志
# Analyse ${Time} ${LogName}
# fi
Red "详情请见 ./alogs 目录"
}
main $*
验证统计数据用
#!/bin/bash
[ -L plogs ] && rm -f plogs
target_dir=`ls -1td */ |head -n 1`
ln -s ${target_dir} plogs
file=`ls plogs/*`
for f in ${file}
do
sum=0
for i in `awk '{print $1}' $f`
do
if [[ "$i" =~ ^[0-9]+$ ]];then
((sum = sum + i))
fi
done
echo $sum : $f
done