やりたいこと
以下のようなFlask(version 1.1.2)のプログラムを作成し
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0')
実行してアクセスすると以下のようなログが出ますが、
127.0.0.1 - - [14/Apr/2020 19:13:43] "\x1b[37mGET / HTTP/1.1\x1b[0m" 200 -
このアクセスログは(私にとって)不要な文字列が入っている上、本文のメッセージに色がついていて、扱いにくいです。
なので、このログをカスタマイズする方法を説明します。
カスタマイズ方法
結論からいうと、Flaskが内部で利用しているWerkzeug (version 1.0.1) という名前のloggerが上記のログを出力しているため、以下のようにWerkzeugのloggerを取得してカスタマイズします。
例1)ログのレベルをERRORに変更する
from flask import Flask
import logging
# ロガーの取得
werkzeug_logger = logging.getLogger("werkzeug")
# レベルの変更
werkzeug_logger.setLevel(logging.ERROR)
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=4001)
例2)出力する文字列の変更
デフォルトでは (IPアドレス) - - [(日時)] (メッセージ(色付き))
というフォーマットで出力されますが、以下の例では、(メッセージ)
の部分を色無しで出力しています。
from flask import Flask
import logging
from werkzeug.serving import WSGIRequestHandler
from werkzeug.urls import uri_to_iri
werkzeug_logger = logging.getLogger("werkzeug")
def custom_log_request(self, code="-", size="-"):
try:
path = uri_to_iri(self.path)
msg = "%s %s %s" % (self.command, path, self.request_version)
except AttributeError:
msg = self.requestline
code = str(code)
werkzeug_logger.info('"%s" %s %s' % (msg, code, size))
# 関数の置き換え
WSGIRequestHandler.log_request = custom_log_request
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0')
出力されるログは以下のように色がなくシンプル
"GET / HTTP/1.1" 200 -
なぜこの方法でいいのか?
Flaskは内部でwerkzeugというパッケージを利用しています。
そのため、Flaskでは2つのloggerが登場します。
一つは logging.getLogger("app.flask")
で取得できるFlaskが使うlogger,
もう一つは logging.getLogger("werkzeug")
で取得できるwerkzeugが使うloggerです。
上記のログはwerkzeugのソースコードの↓の場所で出力しています。
なのでこの関数を置き換えてあげることで、カスタマイズ可能になります。
app.flask
のloggerをいくらいじってもこのログは消えないのでだいぶハマりました(笑)