我正在用 python 和 Flask 制作一个网络应用程序,当网站管理员的网站出现故障时,它会通过电子邮件和推文发送给网站管理员。我正在考虑运行一个无限 while 循环,等待 10 分钟,然后向要检查的网站发送请求,并检查返回的响应是否为 200。问题是在脚本中我可以插入这个循环吗?关于如何实现这一目标有什么建议吗?
最佳答案
士兵,你死后告诉我
尝试报告死机应用程序的问题并不是最可靠的方法。
使用外部进程观看应用
您应该有一些外部独立应用程序来监控您的应用程序。
如果你生活在纯Python环境中,你可以编写一个脚本,它会检查访问某个应用程序的url是否成功,如果不成功,它会提醒某人。对于警报,您可以尝试例如日志
,包含通过电子邮件发送的日志记录(请参阅 MailHandler 或 GMailHandler )。
在生产环境中,最好运行一些监控应用程序,例如 Nagios只需通过 check_http
进行检查
使用日志检查脚本示例
为了更好的可读性,内容被分成更多部分,真正的脚本位于一个名为 monitor_url.py
monitor_url.py
:文档字符串、导入和 MAIL_TEMPLATE
Docstring解释了用法,最终被命令行解析器使用docopt
进口主要与日志
相关
"""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
最终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 [选项] ... 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收件箱(如果没有任何内容,你就得玩密码了)。
结论
Twitter 通知也可以通过日志
实现,但此处未显示。
要运行该脚本,需要 Python 2.7,并且您应安装一些软件包:
$ pip install logbook jinja2 requests
管理来自这样的脚本的通知并不容易。在这方面考虑这个测试质量的脚本。
使用 Nagios
等解决方案似乎更适合此目的。
关于python - 在 Flask 中后台运行进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24115650/