繁体   English   中英

在Flask的后台运行进程

[英]Running A Process In the Background In Flask

我正在用python和flask创建一个webapp,当他的网站关闭时,它会通过电子邮件和tweet通知网站管理员。 我正在考虑运行一个无限的while循环,该循环等待10分钟,然后将请求发送到要检查的网站,并检查返回的响应是否为200。问题在于脚本中是否可以插入此循环? 关于如何实现此目标的任何建议?

士兵,你死后告诉我

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

使用外部流程观看应用

您将拥有一些外部独立应用程序,以监视您的应用程序。

如果您生活在纯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.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__ ... 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收件箱(如果没有,则必须使用密码进行播放)。

结论

使用logbook也可以进行Twitter通知,但此处未显示。

要运行该脚本,应使用Python 2.7,并且应安装一些软件包:

$ pip install logbook jinja2 requests

从这样的脚本管理通知并不容易。 考虑一下这方面的beta质量脚本。

使用Nagios之类的解决方案似乎更适合此目的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM