基于淘宝Tengine和Scribe的WEB日志收集方案

公司在迁移Hadoop到新的集群,涉及到原数据流的迁移,以前是用syslog-ng去push日志,但是配置起来比较麻烦。正好淘宝开发了一个新的tengine,拿过来尝尝鲜,正好利用其pipe功能,可以将日志发送到scribe进行汇总收集,然后就可以舍弃syslog-ng了。反正syslog也是要被Linux抛弃的。


按说应该是直接把Scribe的API直接嵌套在程序中,但由于scribe是刚刚开始推广应用,而以前的日志分析都是基于weblog,大规模改造程序,成本太大,需要逐步推进,为了快速切换,只能这样用了。


安装scribe以前已经写过两个文章了,不再赘述。这次只讲讲是如何将nginx的日志通过scribe收集起来的。


说明:

配置tengine的服务器IP是192.168.1.14,远端的收集服务器IP是192.168.1.33。

scribe在192.168.1.14上的配置是发送一份日志到远端,再保存一份日志在本机。

scribe在远端服务器的配置就是默认就可以了。


Tengine在这里下载。然后安装配置


./configure --prefix=/opt/modules/tengine --with-file-aio --with-syslog --with-http_sub_module --with-http_gzip_static_module --with-http_stub_status_module --with-pcre && make && make install


加上--with-syslog主要是为了将syslog作为备用方案,万一scribe全挂了,可以用syslog接上。


如果是用我以前发布的linux rpm在CentOS下安装scribe,默认是不好用的,所以需要在centos下改一下。


chkconfig --del scribe

echo "scribed -c /etc/scribe.conf &" >> /etc/rc.local


然后到/opt/modules/tengine下编辑conf/nginx.conf


server {
                listen                    80;
                server_name    192.168.1.14;

                access_log "pipe:/opt/modules/tengine/sbin/scribe_ngx -h 192.168.1.14:1463 collect-vv-175" main;

        }


红色部分,是淘宝新开发出的pipe日志的功能。用这种办法,在nginx进程里调用一个收集用户输入的脚本


然后是scribe_ngx,其实就是scribe自带的scribe_cat改造了一下,从获取stdin改成了获取用户输入。但是用户输入是放到一个死循环里的,只要nginx不退出,scribe_ngx进程就不会退出。


#!/usr/bin/Python
import sys
from scribe import scribe
from thrift.transport import TTransport, TSocket
from thrift.protocol import TBinaryProtocol

if len(sys.argv) == 2:
    category = sys.argv[1]
    host = '127.0.0.1'
    port = 1463
elif len(sys.argv) == 4 and sys.argv[1] == '-h':
    category = sys.argv[3]
    host_port = sys.argv[2].split(':')
    host = host_port[0]
    if len(host_port) > 1:
        port = int(host_port[1])
    else:
        port = 1463
else:
    sys.exit('usage (message is stdin): scribe_cat [-h host[:port]] category')

#log_entry = scribe.LogEntry(category=category, message=sys.stdin.read())
message = '%s'%raw_input()
while True:
                log_entry = scribe.LogEntry(category=category, message=message)

                socket = TSocket.TSocket(host=host, port=port)
                transport = TTransport.TFramedTransport(socket)
                protocol = TBinaryProtocol.TBinaryProtocol(trans=transport, strictRead=False, strictWrite=False)
                client = scribe.Client(iprot=protocol, oprot=protocol)

                transport.open()
                result = client.Log(messages=[log_entry])
                transport.close()
                message = '%s'%raw_input()


然后将程序放到/opt/modules/tengine/sbin,然后启动nginx,你将会在进程里看到一个python的进程。


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/pxzxy.html