|
一 应用场景描述
应开发同事需求,需要对各个游戏区服的Redis库中查看bi这个key的长度,如果长度大于100,就发送报警通知。这款游戏采用的是一台服务器上部署多个区服的模式,每个区服有一个配置文件app.conf.php,每个配置文件中关于redis的配置信息如下:
'normal' => array(
'host' => '127.0.0.1',
'port' => 6402,
'db' => 8
),
现在需要定期去从各个区服配置中去获取redis的信息,然后连接redis,查看各个库中bi key的长度
如:redis-cli -p 6402 -n 8 llen bi
最初是打算采用shell来写的,但是无奈一时没有调试出来。就请一哥们帮忙解决怎么解决,他用python写了程序,但是我对python不是很懂,于是就边写边学,最后写成了如下的脚本。
二 解决思路
先查找出所有的redis配置信息
find /data/zhanguo_app/ -name app.conf.php -exec sed -n '/normal/,+4p' {} \;
显示如下类似信息
'normal' => array(
'host' => '127.0.0.1',
'port' => 6402,
'db' => 7
),
'normal' => array(
'host' => '127.0.0.1',
'port' => 6379,
'db' => 10
),
'normal' => array(
'host' => '127.0.0.1',
'port' => 6402,
'db' => 2
),
'normal' => array(
'host' => '127.0.0.1',
'port' => 6379,
'db' => 9
),
然后需要对显示的结果进行处理循环去读取host , port ,db的值,然后根据这三个值去连接redis。这里就需要用到python处理字符串的一些知识。在以下的脚本中对字符串的处理过程如下:
使用python字符串的replace()将以上的字符形式变成如下的形式
normal=>arrayhost=>127.0.0.1,port=>6379,db=>11normal=>arrayhost=>127.0.0.1,port=>6402,db=>1normal=>arrayhost=>127.0.0.1,port=>6379,db=>14normal=>arrayhost=>127.0.0.1,port=>6379,db=>1normal=>arrayhost=>127.0.0.1,port=>6405,db=>6normal=>arrayhost=>127.0.0.1,port=>6405,db=>
然后在使用python字符串的split()将字符串变成如下的形式
['', 'host=>127.0.0.1,port=>6379,db=>11', 'host=>127.0.0.1,port=>6402,db=>1', 'host=>127.0.0.1,port=>6379,db=>14', 'host=>127.0.0.1,port=>6379,db=>1', 'host=>127.0.0.1,port=>6405,db=>6', 'host=>127.0.0.1,port=>6405,db=>1', 'host=>127.0.0.1,port=>6379,db=>8', 'host=>127.0.0.1,port=>6402,db=>8']
然后循环读取以上列表中的元素如 host=>127.0.0.1,port=>6379,db=>11 通过split()变成如下的形式
['host=>127.0.0.1', 'port=>6379', 'db=>11']
然后将以上列表变成
{'host': '127.0.0.1', 'db': '11', 'port': '6379'}
然后变成
[{'host': '127.0.0.1', 'db': '11', 'port': '6379'}, {'host': '127.0.0.1', 'db': '1', 'port': '6402'}, {'host': '127.0.0.1', 'db': '14', 'port': '6379'}, {'host': '127.0.0.1', 'db': '1', 'port': '6379'}, {'host': '127.0.0.1', 'db': '6', 'port': '6405'}, {'host': '127.0.0.1', 'db': '1', 'port': '6405'}, {'host': '127.0.0.1', 'db': '8', 'port': '6379'}]
三 Python脚本
#/usr/bin/python
import os
import subprocess
import redis
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
import socket
#get the localhost name
hostname=socket.gethostname()
mail_server='smtp.exmail.qq.com'
mail_server_port=25
mail_user='xxxx'
mail_password='xxxx'
from_addr='xxxx'
to_addr=['xxxx','xxxxx','xxxxx']
#define send_email function for reuse
def send_email(sub,content):
m=MIMEMultipart()
m["To"]=";".join(to_addr)
m["From"]=from_addr
m["Subject"]=sub
m.attach(MIMEText(content))
s=smtplib.SMTP(mail_server,mail_server_port)
s.sendmail(from_addr,to_addr,m.as_string())
s.quit()
#get redis configuration
args="find /data/zhanguo_app/ -name app.conf.php -exec sed -n '/normal/,+4p' {} \;"
redis_content=subprocess.Popen(args,shell=True,stdout=subprocess.PIPE).communicate()[0]
#check if redis_content file exists
if os.path.isfile("redis_content.txt"):
print "redis_content.txt file exists"
else:
print "redis_content.txt not exists"
#write content into file
redis_array_file=file('redis_content.txt','w')
redis_array_file.write(redis_content)
redis_array_file.close
redis_array_file=file('redis_content.txt','r')
content=redis_array_file.read()
redis_array_file.close
#hanle string
redis_string_list=redis_string.split("normal=>array")
redis_config_dic_list=[]
for i in redis_string_list:
redis_config_list=i.split(",")
if len(redis_config_list)==3:
redis_config_dic={}
for j in redis_config_list:
redis_config=j.split("=>")
if len(redis_config)==2:
redis_config_dic[redis_config[0]]=redis_config[1]
redis_config_dic_list.append(redis_config_dic)
#connect to redis and check bi key's length
for k in redis_config_dic_list:
redis_host=k['host']
redis_port=k['port']
redis_db=k['db']
try:
r=redis.StrictRedis(host=redis_host, port=redis_port, db=redis_db,socket_timeout=1)
bi_length=r.llen('bi')
if bi_length > 100:
warning_subject="BI KEY WARING ON "+hostname
warning_message=redis_host + ':' + redis_port + ' ' + redis_db + " The bi key's length is greater than 100"
send_email(warning_subject,warning_message)
except redis.exceptions.ConnectionError:
connect_subject="Connect to redis server on "+hostname+" error"
connect_error="Connect to redis server " + redis_host + ":" + redis_port + " error"
send_email(connect_subject,connect_error)
以上脚本中使用socket模块获取本机的主机名,使用smtplib模块发送邮件。使用redis模块操作redis数据库,使用try ... except 作异常处理,使用subprocess模块调用shell命令
|
|