日志管理(4) 用scribe收集nginx和php日志

介绍怎样用scribe收集各台服务器上nginx和php程序运行时自身产生的日志(error.log、access_log等),实现的方法很简单——用logrotate切日志,将读取的日志通过scribe_cat送给中心的日志服务器。而正常业务产生的日志由开发自己编写代码直接送给scribe不在讨论的范畴,收集nginx和php程序产生日志的方法也可以发散到其它程序日志的收集如mysql。

1、scribe_cat脚本 scribe_cat是scribe源码包提供的一个python脚本,用来将标准输入的信息送给scribe服务器,在源码包的examples目录下。可以简单测试一下:

1
2
3
#-h参数用来指定scribe服务器的ip和端口 
#1_test是日志类别表示,跟scribe配置相关,是必要的参数
$ echo "hello world" | /usr/local/scribe/examples/scribe_cat -h 192.168.186.135:2463 1_test

这条命令执行后,如果scribe配置中有1_test相关的store那么就会在相关目录下生成一个文件且文件的内容有一行信息是”hello workd”
用echo、sed、awk等作为scribe_cat的标准输入最后都会带上一个换行符”\n”,这样就带来一个困扰就是会发现scribe收集的日志会有很多空行。
解决空行的方法就是将标准输入信息最后一行的换行符去掉,编辑scribe_cat脚本:

1
2
3
4
5
6
#导入新的模块用于正则匹配 
from re import sub
#新增的语句,用来接收标准输入的信息
sendMessage=sys.stdin.read()
#修改的语句,将标准输入信息最后一个换行符删除
log_entry = scribe.LogEntry(category=category, message=sub(r"\n$", '', sendMessage))

2、编写收集日志脚本pushscribe.sh 脚本功能: 每天23点59分对nginx和php的日志切割一次(切割目的主要是减轻每次读取日志的压力),每分钟累计采集数次nginx、php日志内容并将读取的内容由scribe_cat送给中心的scribe达到收集日志的功能,每条日志文件在server落地的时候加上对应主机的主机名用来标识日志的来源。 脚本的内容如下,其实nginx和php的日志可以写成一个迭代,为了简介清晰还是分开写的好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/bin/bash 

npath='/var/log/nginx/'
ppath='/var/log/php-fpm/'
countfile='.count'
host=`hostname`
date=`date +'-%Y%m%d'`
dflag=`date +'%H%M'`

#每分钟读取日志的次数,一天的最后一分钟只读取一次
if [[ $dflag == '2359' ]];then
count=1
else
count=2
fi
for((i=0; i<$count; i++))
{
#nginx
cd $npath
if [[ $dflag == '2359' ]];then
/usr/sbin/logrotate /etc/logrotate_hd.conf #每天23:59切割日志
for fname in `ls | grep -E ".com$|.log$"`
do
startnum=`grep "^$fname" $countfile | awk '{print $2}'`
if [ -e $fname$date ];then
sed -i "s/^$fname $startnum/$fname 1/" $countfile
endnum=`awk 'END{print NR}' $fname$date`
awk -v h=" $host" "{if((NR>=$startnum)&&(NR<=$endnum))print \$0 h}" $fname$date | /usr/local/scribe/examples/scribe_cat -h 127.0.0.1:2463 "10_$fname"
else
endnum=`awk 'END{print NR}' $fname`
if [ $endnum -gt $startnum ];then
sed -i "s/^$fname $startnum/$fname $endnum/" $countfile
awk -v h=" $host" "{if((NR>=$startnum)&&(NR<$endnum))print \$0 h}" $fname | /usr/local/scribe/examples/scribe_cat -h 192.168.186.135:2463 "10_$fname"
fi
fi
done
else
for fname in `ls | grep -E ".com$|.log$"`
do
startnum=`grep "^$fname" $countfile | awk '{print $2}'`
if [[ -z $startnum ]];then
echo "$fname 1" >> $countfile startnum=1
fi
endnum=`awk 'END{print NR}' $fname`
if [ $endnum -gt $startnum ];then
sed -i "s/^$fname $startnum/$fname $endnum/" $countfile
awk -v h=" $host" "{if((NR>=$startnum)&&(NR<$endnum))print \$0 h}" $fname | /usr/local/scribe/examples/scribe_cat -h 192.168.186.135:2463 "10_$fname"
fi
done
fi

#php-fpm
cd $ppath
if [[ $dflag == '2359' ]];then
for fname in `ls | grep -E ".slow$|.log$"`
do
startnum=`grep "^$fname" $countfile | awk '{print $2}'`
if [ -e $fname$date ];then
sed -i "s/^$fname $startnum/$fname 1/" $countfile
endnum=`awk 'END{print NR}' $fname$date`
awk -v h=" $host" "{if((NR>=$startnum)&&(NR<=$endnum))print \$0 h}" $fname$date | /usr/local/scribe/examples/scribe_cat -h 192.168.186.135:2463 "11_$fname"
else
endnum=`awk 'END{print NR}' $fname` if [ $endnum -gt $startnum ];then sed -i "s/^$fname $startnum/$fname $endnum/" $countfile
awk -v h=" $host" "{if((NR>=$startnum)&&(NR<$endnum))print \$0 h}" $fname | /usr/local/scribe/examples/scribe_cat -h 192.168.186.135:2463 "11_$fname"
fi
fi
done
else
for fname in `ls | grep -E ".slow$|.log$"`
do
startnum=`grep "^$fname" $countfile | awk '{print $2}'`
if [[ -z $startnum ]];then
echo "$fname 1" >> $countfile startnum=1
fi
endnum=`awk 'END{print NR}' $fname`
if [ $endnum -gt $startnum ];then
sed -i "s/^$fname $startnum/$fname $endnum/" $countfile
awk -v h=" $host" "{if((NR>=$startnum)&&(NR<$endnum))print \$0 h}" $fname | /usr/local/scribe/examples/scribe_cat -h 192.168.186.135:2463 "11_$fname"
fi
done
fi
sleep 10
}

3、添加定时任务

1
* * * * * root sh /tool/pushscribe.sh > /dev/null 2>&1

关于怎样切割php和nginx的日志在《日志管理(2) 用logrotate切割php和nginx日志》中已经介绍了,不过要注意的是已经在脚本中对日志进行切割后,就不要再将切割日志的动作放到定时任务里,避免重复切割造成不必要的麻烦。

----------------本文结束 感谢阅读----------------