介绍怎样用scribe收集各台服务器上nginx和php程序运行时自身产生的日志(error.log、access_log等),实现的方法很简单——用logrotate切日志,将读取的日志通过scribe_cat送给中心的日志服务器。而正常业务产生的日志由开发自己编写代码直接送给scribe不在讨论的范畴,收集nginx和php程序产生日志的方法也可以发散到其它程序日志的收集如mysql。
1、scribe_cat脚本
scribe_cat是scribe源码包提供的一个python脚本,用来将标准输入的信息送给scribe服务器,在源码包的examples目录下。可以简单测试一下:
#-h参数用来指定scribe服务器的ip和端口
#1_test是日志类别表示,跟scribe配置相关,是必要的参数
[root@TestHost ~]
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脚本:
#导入新的模块用于正则匹配
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的日志可以写成一个迭代,为了简介清晰还是分开写的好。
#!/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、添加定时任务
* * * * * root sh
/tool/pushscribe
.sh >
/dev/null
2>&1
|
关于怎样切割php和nginx的日志在《日志管理(2) 用logrotate切割php和nginx日志》中已经介绍了,不过要注意的是已经在脚本中对日志进行切割后,就不要再将切割日志的动作放到定时任务里,避免重复切割造成不必要的麻烦。
文章出处:http://www.xiaomastack.com/2014/11/11/scribe-nginx-php/