日誌

Flask 使用標準 Python logging 模組。關於您的 Flask 應用程式的訊息會使用 app.logger 記錄,其名稱與 app.name 相同。此記錄器也可以用來記錄您自己的訊息。

@app.route('/login', methods=['POST'])
def login():
    user = get_user(request.form['username'])

    if user.check_password(request.form['password']):
        login_user(user)
        app.logger.info('%s logged in successfully', user.username)
        return redirect(url_for('index'))
    else:
        app.logger.info('%s failed to log in', user.username)
        abort(401)

如果您未設定日誌,Python 的預設日誌層級通常為 ‘warning’。低於設定層級的任何訊息都將不可見。

基本設定

當您想要為您的專案設定日誌時,您應該在程式啟動時儘快進行設定。如果在設定日誌之前存取 app.logger,它將新增一個預設處理器。如果可能,請在建立應用程式物件之前設定日誌。

此範例使用 dictConfig() 來建立一個與 Flask 預設設定相似的日誌設定,但適用於所有日誌。

from logging.config import dictConfig

dictConfig({
    'version': 1,
    'formatters': {'default': {
        'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
    }},
    'handlers': {'wsgi': {
        'class': 'logging.StreamHandler',
        'stream': 'ext://flask.logging.wsgi_errors_stream',
        'formatter': 'default'
    }},
    'root': {
        'level': 'INFO',
        'handlers': ['wsgi']
    }
})

app = Flask(__name__)

預設設定

如果您未自行設定日誌,Flask 將自動新增一個 StreamHandlerapp.logger。在請求期間,它會寫入 WSGI 伺服器在 environ['wsgi.errors'] 中指定的串流(通常是 sys.stderr)。在請求之外,它將記錄到 sys.stderr

移除預設處理器

如果您在存取 app.logger 之後設定了日誌,並且需要移除預設處理器,您可以匯入並移除它

from flask.logging import default_handler

app.logger.removeHandler(default_handler)

以電子郵件將錯誤發送給管理員

當在遠端伺服器上執行生產環境的應用程式時,您可能不會經常查看日誌訊息。WSGI 伺服器可能會將日誌訊息發送到檔案,而且只有在使用者告訴您發生錯誤時,您才會檢查該檔案。

為了積極主動地發現和修正錯誤,您可以設定一個 logging.handlers.SMTPHandler,以便在記錄錯誤及更高等級的訊息時發送電子郵件。

import logging
from logging.handlers import SMTPHandler

mail_handler = SMTPHandler(
    mailhost='127.0.0.1',
    fromaddr='server-error@example.com',
    toaddrs=['admin@example.com'],
    subject='Application Error'
)
mail_handler.setLevel(logging.ERROR)
mail_handler.setFormatter(logging.Formatter(
    '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
))

if not app.debug:
    app.logger.addHandler(mail_handler)

這需要您在同一伺服器上設定 SMTP 伺服器。請參閱 Python 文件以取得有關設定處理器的更多資訊。

注入請求資訊

查看更多關於請求的資訊,例如 IP 位址,可能有助於偵錯某些錯誤。您可以子類別化 logging.Formatter 以注入您自己的欄位,這些欄位可以用於訊息中。您可以變更 Flask 預設處理器、上面定義的郵件處理器或任何其他處理器的格式器。

from flask import has_request_context, request
from flask.logging import default_handler

class RequestFormatter(logging.Formatter):
    def format(self, record):
        if has_request_context():
            record.url = request.url
            record.remote_addr = request.remote_addr
        else:
            record.url = None
            record.remote_addr = None

        return super().format(record)

formatter = RequestFormatter(
    '[%(asctime)s] %(remote_addr)s requested %(url)s\n'
    '%(levelname)s in %(module)s: %(message)s'
)
default_handler.setFormatter(formatter)
mail_handler.setFormatter(formatter)

其他函式庫

其他函式庫可能會大量使用日誌,而您也希望看到來自這些日誌的相關訊息。最簡單的方法是將處理器新增到根記錄器,而不僅僅是應用程式記錄器。

from flask.logging import default_handler

root = logging.getLogger()
root.addHandler(default_handler)
root.addHandler(mail_handler)

根據您的專案,分別設定您關心的每個記錄器可能比僅設定根記錄器更有用。

for logger in (
    logging.getLogger(app.name),
    logging.getLogger('sqlalchemy'),
    logging.getLogger('other_package'),
):
    logger.addHandler(default_handler)
    logger.addHandler(mail_handler)

Werkzeug

Werkzeug 將基本的請求/回應資訊記錄到 'werkzeug' 記錄器。如果根記錄器沒有設定任何處理器,Werkzeug 會將 StreamHandler 新增到其記錄器。

Flask 擴充套件

根據情況,擴充套件可能會選擇記錄到 app.logger 或其自己的具名記錄器。請查閱每個擴充套件的文件以了解詳細資訊。