在烧瓶中的背景中运行一个过程

时间:2014-06-09 07:32:14

标签: python flask

我正在使用python和flask制作一个webapp,它将通过电子邮件发送给我们。当他的网站出现故障时,向网站管理员发送推文。我正在考虑运行一个无限的while循环,等待10分钟,然后向网站发送一个请求进行检查并检查返回的响应是否为200.问题是脚本中是否可以插入此循环?关于如何实现这一目标的任何建议?

1 个答案:

答案 0 :(得分:2)

士兵,告诉我你什么时候死了

尝试从垂死的应用程序报告问题并不是最可靠的方法。

使用外部流程观看应用

您应该有一些外部独立应用,监控您的应用。

如果您居住在纯Python环境中,您可以编写一个脚本,该脚本将检查访问某些应用程序URL是否成功,如果不成功,则会提醒某人。如需提醒,您可以尝试例如logbook通过电子邮件发送日志记录(请参阅MailHandlerGMailHandler)。

在生产环境中,最好运行一些监控应用,例如Nagios,只需按check_http

进行检查

使用Logbook

检查脚本示例

为了更好的可读性,内容被拆分为更多部分,真实脚本位于一个名为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.pymain执行检查的功能

此脚本在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这样的解决方案的使用似乎更适合此目的。