背景:公司项目中需要将客户端访问日志进行监控,并实时将更新内容开放给测试同事进行查询。
早期由于时间缺乏的因此,直接采用了一个效率特别低的方法进行监控。最近刚好尝试了Redis Python客户端,因此有了一个初步的想法:Log-->Redis-->Fetch,相当于。可以分解成:
1. 使用Python将Log内容存储到Redis(可以使用任何语言,采用Python只是个人的喜好)
2. 创建某个接口获取日志文件内容
话不多说,直接上代码:
#!/bin/python
# update.py
import redis
import json
import datetime
import sys
import time
import subprocess
import shlex
import pdb
r = redis.StrictRedis(host=<your host>, port=<port>, db=0, password=<your pass>) # 设置Redis服务器
if r.ping()
def main():
cnt = 1
for line in sys.stdin:
r.set(++cnt, line)
main()
使用的方法: tail -f ~/log.log | python update.py。运行后,发现能够更新一些数据,但是无法更新运行后期加入的文件内容。这个问题,到现在自己也没有明白,按道理,管理作为Python输入是可以生效的。有明白的同学,麻烦告诉我下!
第一次尝试失败后,自己就思考:如何能在Python中监控新加入的内容,是否就可以解决自己的问题?于是Google后,发现另外一个方法:subprocess.Popen。在仔细地阅读后,自己发现这个方法和上面代码中用到的方法没什么差别,只不过是用Python代码来表现而已。直接上代码:
#!/bin/python
# update_sec.py
import redis
import json
import datetime
import sys
import time
import subprocess
import shlex
import pdb
r = redis.StrictRedis(host=<your host>, port=<port>, db=0, password=<your pass>)
r.ping()
def main():
cmd = "tail -f ~/test.log"
cmd = shlex.split(cmd)
curr_day = datetime.date.today()
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
print cmd
while True:
line = process.stdout.readline()
if line == '' and process.poll() is not None:
break;
if line:
# add line process logic
r.set(cnt, line)
rc = process.poll()
print "return code :" , rc
main()
说明:
1. subprocess.Popen相当于创建一个子进程,并将子进程的输出通过管道输入到主进程;
2. subprocess.poll()用于判断子进程是否停止,process.stdout为子进程的输出文件描述符
开启python update_sec.py后,向~/test.log追加内容,发现能够实时更新日志数据到Redis了,问题解决!
当然了,这只是解决问题的一个方法。这个方法无法监控某个文件夹内符合一定格式的文件内容,一个想法就是采用pyinotify监控某文件夹内文件的创建,如果文件名符合目标格式,就开始采用上面的处理流程。
如果大家有更好的方法,可以留言告诉我!
完-------------------