返回介绍

通过电子邮件发送错误

发布于 2025-01-02 21:53:51 字数 4171 浏览 0 评论 0 收藏 0

Flask 提供的默认错误处理机制的另一个问题是没有通知机制,错误的堆栈跟踪只是被打印到终端,这意味着需要监视服务器进程的输出才能发现错误。 在开发时,这是非常好的,但是一旦将应用部署在生产服务器上,没有人会关心输出,因此需要采用更强大的解决方案。

我认为对错误发现采取积极主动的态度是非常重要的。 如果生产环境的应用发生错误,我想立刻知道。 所以我的第一个解决方案是配置 Flask 在发生错误之后立即向我发送一封电子邮件,邮件正文中包含错误堆栈跟踪的正文。

第一步,添加邮件服务器的信息到配置文件中:

class Config(object):
    # ...
    MAIL_SERVER = os.environ.get('MAIL_SERVER')
    MAIL_PORT = int(os.environ.get('MAIL_PORT') or 25)
    MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
    MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
    MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
    ADMINS = ['your-email@example.com']

电子邮件的配置变量包括服务器和端口,启用加密连接的布尔标记以及可选的用户名和密码。 这五个配置变量来源于环境变量。 如果电子邮件服务器没有在环境中设置,那么我将禁用电子邮件功能。 电子邮件服务器端口也可以在环境变量中给出,但是如果没有设置,则使用标准端口 25。 电子邮件服务器凭证默认不使用,但可以根据需要提供。 ADMINS 配置变量是将收到错误报告的电子邮件地址列表,所以你自己的电子邮件地址应该在该列表中。

Flask 使用 Python 的 logging 包来写它的日志,而且这个包已经能够通过电子邮件发送日志了。 我所需要做的就是为 Flask 的日志对象 app.logger 添加一个 SMTPHandler 的实例:

import logging
from logging.handlers import SMTPHandler

# ...

if not app.debug:
    if app.config['MAIL_SERVER']:
        auth = None
        if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
            auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
        secure = None
        if app.config['MAIL_USE_TLS']:
            secure = ()
        mail_handler = SMTPHandler(
            mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
            fromaddr='no-reply@' + app.config['MAIL_SERVER'],
            toaddrs=app.config['ADMINS'], subject='Microblog Failure',
            credentials=auth, secure=secure)
        mail_handler.setLevel(logging.ERROR)
        app.logger.addHandler(mail_handler)

如你所见,仅当应用未以调试模式运行,且配置中存在邮件服务器时,我才会启用电子邮件日志记录器。

设置电子邮件日志记录器的步骤因为处理安全可选项而稍显繁琐。 本质上,上面的代码创建了一个 SMTPHandler 实例,设置它的级别,以便它只报告错误及更严重级别的信息,而不是警告,常规信息或调试消息,最后将它附加到 Flask 的 app.logger 对象中。

有两种方法来测试此功能。 最简单的就是使用 Python 的 SMTP 调试服务器。 这是一个模拟的电子邮件服务器,它接受电子邮件,然后打印到控制台。 要运行此服务器,请打开第二个终端会话并在其上运行以下命令:

(venv) $ python -m smtpd -n -c DebuggingServer localhost:8025

要用这个模拟邮件服务器来测试应用,那么你将设置 MAIL_SERVER=localhostMAIL_PORT=8025

译者注:本段中去处了说明设置该端口需要管理员权限的部分,因为这和实际情况不符。原文如下: To test the application with this server, then you will set MAIL_SERVER=localhost and MAIL_PORT=8025 . If you are on a Linux or Mac OS system, you will likely need to prefix the command with sudo , so that it can execute with administration privileges. If you are on a Windows system, you may need to open your terminal window as an administrator. Administrator rights are needed for this command because ports below 1024 are administrator-only ports. Alternatively, you can change the port to a higher port number, say 5025, and set MAIL_PORT variable to your chosen port in the environment, and that will not require administration rights.

保持调试 SMTP 服务器运行并返回到第一个终端,在环境中设置 export MAIL_SERVER=localhostMAIL_PORT=8025 (如果使用的是 Microsoft Windows,则使用 set 而不是 export)。 确保 FLASK_DEBUG 变量设置为 0 或者根本不设置,因为应用不会在调试模式中发送电子邮件。 运行该应用并再次触发 SQLAlchemy 错误,以查看运行模拟电子邮件服务器的终端会话如何显示具有完整堆栈跟踪错误的电子邮件。

这个功能的第二个测试方法是配置一个真正的电子邮件服务器。 以下是使用你的 Gmail 帐户的电子邮件服务器的配置:

export MAIL_SERVER=smtp.googlemail.com
export MAIL_PORT=587
export MAIL_USE_TLS=1
export MAIL_USERNAME=<your-gmail-username>
export MAIL_PASSWORD=<your-gmail-password>

如果你使用的是 Microsoft Windows,记住在每一条语句中用 set 替换掉 export

Gmail 帐户中的安全功能可能会阻止应用通过它发送电子邮件,除非你明确允许“安全性较低的应用程序”访问你的 Gmail 帐户。 可以阅读 此处 来了解具体情况,如果你担心帐户的安全性,可以创建一个辅助邮箱帐户,配置它来仅用于测试电子邮件功能,或者你可以暂时启用允许不太安全的应用程序来运行此测试,完成后恢复为默认值。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文