社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

有福了!六步使用Python写一个小小的自动化项目监控

马哥Linux运维 • 8 年前 • 869 次点击  

本文由马哥教育Python自动化实战班5期学员推荐,转载自互联网,作者为 Defshine,内容略经小编改编和加工,观点跟作者无关,最后感谢作者的辛苦贡献与付出。


在公司里做的一个接口系统,主要是对接第三方的系统接口,所以,这个系统里会和很多其他公司的项目交互。随之而来一个很蛋疼的问题,这么多公司的接口,不同公司接口的稳定性差别很大,访问量大的时候,有的不怎么行的接口就各种出错了。

这个接口系统刚刚开发不久,整个系统中,处于比较边缘的位置,不像其他项目,有日志库,还有短信告警,一旦出问题,很多情况下都是用户反馈回来,所以,我的想法是,拿起python,为这个项目写一个监控。如果在调用某个第三方接口的过程中,大量出错了,说明这个接口有有问题了,就可以更快的采取措施。

项目的也是有日志库的,所有的info,error日志都是每隔一分钟扫描入库,日志库是用的mysql,表里有几个特别重要的字段:

level 日志级别

message 日志内容

file_name Java代码文件

log_time 日志时间

有日志库,就不用自己去线上环境扫日志分析了,直接从日志库入手。由于日志库在线上时每隔1分钟扫,那我就去日志库每隔2分钟扫一次,如果扫到有一定数量的error日志就报警,如果只有一两条错误就可以无视了,也就是短时间爆发大量错误日志,就可以断定系统有问题了。报警方式就用发送邮件,所以,需要做下面几件事情:

1. 操作MySql。

2. 发送邮件。

3. 定时任务。

4. 日志。

5. 运行脚本。

明确了以上几件事情,就可以动手了。

一、操作数据库

使用MySQLdb这个驱动,直接操作数据库,主要就是查询操作。

获取数据库的连接:

defget_con():

host="127.0.0.1"

port=3306

logsdb="logsdb"

user="root"

password="never tell you"

con=MySQLdb.connect(host=host,user=user,passwd=password,db=logsdb,port=port,charset="utf8")

returncon

从日志库里获取数据,获取当前时间之前2分钟的数据,首先,根据当前时间进行计算一下时间。之前,计算有问题,现在已经修改。

defcalculate_time():

now=time.mktime(datetime.now().timetuple())-60*2

result=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now))

returnresult

然后,根据时间和日志级别去日志库查询数据

defget_data():

select_time=calculate_time()

logger.info("select time:"+select_time)

sql="select file_name,message from logsdb.app_logs_record "\

"where log_time >"+"'"+select_time+"'"\

"and level="+"'ERROR'"\

"order by log_time desc"

conn=get_con()

cursor=conn.cursor()

cursor.execute(sql)

results=cursor.fetchall()

cursor.close()

conn.close()

returnresults

二、发送邮件

使用python发送邮件比较简单,使用标准库smtplib就可以

这里使用163邮箱进行发送,你可以使用其他邮箱或者企业邮箱都行,不过host和port要设置正确。

defsend_email(content):

sender="sender_monitor@163.com"

receiver=["rec01@163.com","rec02@163.com"]

host='smtp.163.com'

port=465

msg=MIMEText(content)

msg['From']="sender_monitor@163.com"

msg['To']="rec01@163.com,rec02@163.com"

msg['Subject']="system error warning"

try:

smtp=smtplib.SMTP_SSL(host,port)

smtp.login(sender,'123456')

smtp.sendmail(sender,receiver,msg.as_string())

logger.info("send email success")

exceptException,e:

logger.error(e)

三、定时任务

使用一个单独的线程,每2分钟扫描一次,如果ERROR级别的日志条数超过5条,就发邮件通知。

deftask():

whileTrue:

logger.info("monitor running")

results=get_data()

ifresultsisnotNoneandlen(results)>5:

content="recharge error:"

logger.info("a lot of error,so send mail")

forrinresults:

content+=r[1]+'\n'

send_email(content)

sleep(2*60)

四、日志

为这个小小的脚本配置一下日志log.py,让日志可以输出到文件和控制台中。

# coding=utf-8

importlogging

logger=logging.getLogger('mylogger')

logger.setLevel(logging.DEBUG)

fh=logging.FileHandler('monitor.log')

fh.setLevel(logging.INFO)

ch=logging.StreamHandler()

ch.setLevel(logging.INFO)

formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

fh.setFormatter(formatter)

ch.setFormatter(formatter)

logger.addHandler(fh)

logger.addHandler(ch)

所以,最后,这个监控小程序就是这样的app_monitor.py

# coding=utf-8

importthreading

importMySQLdb

fromdatetimeimportdatetime

importtime

importsmtplib

fromemail.mime.textimportMIMEText

fromlogimportlogger

defget_con():

host="127.0.0.1"

port=3306

logsdb="logsdb"

user="root"

password="never tell you"

con=MySQLdb.connect(host=host,user=user,passwd=password,db=logsdb,port=port,charset="utf8")

returncon

defcalculate_time():

now=time.mktime(datetime.now().timetuple())-60*2

result=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now))

returnresult

defget_data():

select_time=calculate_time()

logger.info("select time:"+select_time)

sql="select file_name,message from logsdb.app_logs_record "\

"where log_time >"+"'"+select_time+"'"\

"and level="+"'ERROR'"\

"order by log_time desc"

conn=get_con()

cursor=conn.cursor()

cursor.execute(sql)

results=cursor.fetchall()

cursor.close()

conn.close()

returnresults

defsend_email(content):

sender="sender_monitor@163.com"

receiver=["rec01@163.com","rec02@163.com"]

host='smtp.163.com'

port=465

msg=MIMEText(content)

msg['From']="sender_monitor@163.com"

msg['To']="rec01@163.com,rec02@163.com"

msg['Subject']="system error warning"

try:

smtp=smtplib.SMTP_SSL(host,port)

smtp.login(sender,'123456')

smtp.sendmail(sender,receiver,msg.as_string())

logger.info("send email success")

exceptException,e:

logger.error(e)

deftask():

whileTrue:

logger.info("monitor running")

results=get_data()

ifresultsisnotNoneandlen(results)>5:

content="recharge error:"

logger.info("a lot of error,so send mail")

forrinresults:

content+=r[1]+'\n'

send_email(content)

time.sleep(2*60)

defrun_monitor():

monitor=threading.Thread(target=task)

monitor.start()

if__name__=="__main__":

run_monitor()

五、运行脚本

脚本在服务器上运行,使用supervisor进行管理。

在服务器(centos6)上安装supervisor,然后在/etc/supervisor.conf中加入一下配置:

[program:app-monitor]

command=python/root/monitor/app_monitor.py

directory=/root/monitor

user=root

然后在终端中运行supervisord启动supervisor。

在终端中运行supervisorctl,进入shell,运行status查看脚本的运行状态。

六、总结

这个小监控思路很清晰,还可以继续修改,比如:监控特定的接口,发送短信通知等等。

因为有日志库,就少了去线上正式环境扫描日志的麻烦,所以,如果没有日志库,就要自己上线上环境扫描,在正式线上环境一定要小心哇~



————开班喜讯————


温馨提醒:马哥教育Python自动化开发班将于8月28日在北京海淀上地开班,小班制魔鬼式授课,钜惠限时抢位中。

马哥教育2017年Python自动化运维开发实战班,马哥联合BAT、豆瓣等一线互联网Python开发达人,根据目前企业需求的Python开发人才进行了深度定制,加入了大量一线互联网公司:大众点评、饿了么、腾讯等生产环境真是项目,课程由浅入深,从Python基础到Python高级,让你融汇贯通Python基础理论,手把手教学让你具备Python自动化开发需要的前端界面开发、Web框架、大监控系统、CMDB系统、认证堡垒机、自动化流程平台六大实战能力,让你从0开始蜕变成Hold住年薪20万的Python自动化开发人才


Python学习免费交流QQ群:542679406(千人群)



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/kPgMiNCq9W
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/2673
 
869 次点击