我正在使用python和flask制作一个webapp,它将通过电子邮件发送给我们。当他的网站出现故障时,向网站管理员发送推文。我正在考虑运行一个无限的while循环,等待10分钟,然后向网站发送一个请求进行检查并检查返回的响应是否为200.问题是脚本中是否可以插入此循环?关于如何实现这一目标的任何建议?
答案 0 :(得分:2)
尝试从垂死的应用程序报告问题并不是最可靠的方法。
您应该有一些外部独立应用,监控您的应用。
如果您居住在纯Python环境中,您可以编写一个脚本,该脚本将检查访问某些应用程序URL是否成功,如果不成功,则会提醒某人。如需提醒,您可以尝试例如logbook
通过电子邮件发送日志记录(请参阅MailHandler或GMailHandler)。
在生产环境中,最好运行一些监控应用,例如Nagios,只需按check_http
为了更好的可读性,内容被拆分为更多部分,真实脚本位于一个名为monitor_url.py
的文件中
monitor_url.py
:文档字符串,导入和MAIL_TEMPLATE Docstring解释了用法,最后由命令行解析器docopt
进口主要是logbook
相关
"""monitor_url.py - check GET access to a url, notify by GMail about problems
Usage:
monitor_url.py [options] <url> <from> <pswd> <to>...
monitor_url.py -h
Options:
-L, --logfile <logfile> Name of logfile to write to [default: monitor_url.log].
-N, --archives <archives> Number of daily logs to keep, use 0 for unlimited [default: 0]
The check is performed once a minute and does HTTP GET request to <url>.
If there is a problem, it sends an e-mail using GMail account.
There is a limit of 6 e-mails, which can be sent per hour.
"""
import time
from logbook import Logger, GMailHandler, StderrHandler, NestedSetup, TimedRotatingFileHandler, Processor
from logbook.more import JinjaFormatter
from datetime import timedelta
import requests
from requests.exceptions import ConnectionError
MAIL_TEMPL = """Subject: {{ record.level_name }} on {{ record.extra.url }}
{{ record.message }}
Url: {{ record.extra.url }}
{% if record.exc_info %}
Exception: {{ record.formatted_exception }}
{% else %}
Status: {{ record.extra.req.status_code }}
Reason: {{ record.extra.req.reason }}
{% endif %}
"""
monitor_url.py
:main
执行检查的功能此脚本在while
中循环,每分钟执行一次检查。
如果检测到问题或状态代码已更改,则GMailHandler配置为发送电子邮件。
def main(url, e_from, pswd, e_to, logfile, archives):
log = Logger("httpWatcher")
def inject_req(record):
record.extra.url = url
record.extra.req = req
processor = Processor(inject_req)
gmail_handler = GMailHandler(e_from, pswd, e_to,
level="WARNING", record_limit=6, record_delta=timedelta(hours=1), bubble=True)
gmail_handler.formatter = JinjaFormatter(MAIL_TEMPL)
setup = NestedSetup([StderrHandler(),
TimedRotatingFileHandler(logfile, bubble=True),
gmail_handler,
processor])
with setup.applicationbound():
last_status = 200
while True:
try:
req = requests.get(url)
if req.status_code != last_status:
log.warn("url was reached, status has changed")
if req.ok:
log.info("url was reached, status OK")
else:
log.error("Problem to reach the url")
last_status = req.status_code
except ConnectionError:
req = None
log.exception("Unable to connect")
last_status = 0
time.sleep(6)
montior_url.py
final if __name__ ...
这部分实际上解析命令行参数并调用main
if __name__ == "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
main(args["<url>"], args["<from>"], args["<pswd>"], args["<to>"], args["--logfile"],
int(args["--archives"]))
尝试不带参数调用它:
$ python monitor_url.py
使用方法: monitor_url.py [options] ... monitor_url.py -h
要获得完整帮助,请使用-h
$ python monitor_url.py -h
...the help is the same as script docstring...
将其用于实时监控,此处用于监控http://localhost:8000
$ python monitor_url.py -L mylog.log -N 2 http://localhost:8000 <yourmail>@gmail.com xxxpasswordxxx notified.person@example.com
{'--archives': '2',
'--logfile': 'mylog.log',
'-h': False,
'<from>': 'your.mail@gmail.com',
'<pswd>': 'xxxxxxx',
'<to>': ['notified.person@example.com'],
'<url>': 'http://localhost:8000'}
[2014-06-09 19:41] INFO: httpWatcher: url was reached, status OK
[2014-06-09 19:41] ERROR: httpWatcher: Unable to connect
Traceback (most recent call last):
....(shortened)...
raise ConnectionError(e, request=request)
ConnectionError: HTTPConnectionPool(host='localhost', port=8000): Max retries exceeded with url: / (Caused by <class 'socket.error'>: [Errno 111] Connection refused)
[2014-06-09 19:41] WARNING: httpWatcher: url was reached, status has changed
[2014-06-09 19:41] INFO: httpWatcher: url was reached, status OK
检查在本地文件夹中创建的日志文件。
检查您的Gmail收件箱(如果没有,您必须使用密码)。
logbook
也可以发布Twitter通知,但此处未显示。
要运行脚本,需要Python 2.7,您应该安装一些软件包:
$ pip install logbook jinja2 requests
从这样的脚本管理通知并不容易。在这方面考虑这个beta质量的脚本。
像Nagios
这样的解决方案的使用似乎更适合此目的。