日志管理(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目录下。可以简单测试一下:

#-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/

发表评论:

你的电子邮件地址将不会被公开.

24 ÷ 3 =