/var/log/study

つまり雑記

flaskのデフォルトのログを出力されないようにする

やりたいことはタイトルどおり。

注意

本記事ではデフォルトで出力されるログを握りつぶすことを主眼においている。

アプリケーションレイヤーできちんとログを出力すること。

動機

flaskのアプリケーションのロギングを自分で細かく設定したい手前、デフォルトで出力されるアクセスログをどの様に消したら良いかがイマイチ分かりづらかったから。

調査した結果としてわかったこと

flaskのデフォのログと書いているがタイトル詐欺で、flaskにデフォで設定されているログの設定はwerkzeug 側で設定されているもの。

つまり本記事を正確に言い表すならば、「werkzeugのデフォルトのログを出力させ無いようにする。」となる。

またwerkzeugが出力するデフォルトの形式を手軽に、程よく改造するのは面倒くさそうだった。

デフォだとApacheのログ形式で、アクセスログが設定されているのだけども、アプリケーション側のログをLTSVとかにし始めると、デフォルトで出力されるログも同じように...というのがお行儀が良いのだろうが、リクエスト自体はリバースプロキシサーバー側でもロギング出来るので一旦握りつぶす方針にした。

デフォルトのログ

深いことは考えずに、アプリケーションを書いて

from flask import Flask

app = Flask(__name__)

@app.route("/", methods=["GET"])
def root():
    return "hello world"


if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=5000)

サクッと動かして

python app.py

別ターミナルで

curl loclahost:5000

とかすると出力される

172.17.0.1 - - [03/Nov/2017 14:55:23] "GET / HTTP/1.1" 200 -

このアクセスログを握りつぶしたい。

ドキュメントを読む

Logging — Flask Documentation (0.13-dev)

なるほど。

pythonのloggingの設定のrootに何も設定していないと、StreamHandlerが設定されるとのこと。

じゃあStreamHandlerをみると?

16.8. logging.handlers — ロギングハンドラ — Python 3.6.3 ドキュメント

なるほど。stdoutに設定されているとのことらしい。

順番はめちゃくちゃだけど、werkzeugのコードを探すと

以下がloggerを設定している箇所

github.com

以下でログを出力するためのヘルパーメソッドとなる。

github.com

なるほど。

WSGIRequestHandler 内にある, log_request などが、 logメソッドを呼び、それは最終的に werkzeug/_internal.py にある、_log メソッドを経由してgetattrでloggingの持つメソッドを文字列で指定しながら呼び出している形となる模様。

つまり

きちんと取り組むなら、以下のファイル内にある WSGIRquesutHandler の logメソッドなどなどを継承したオブジェクトを作って... とかが考えられる。

github.com

が、前述したとおり一旦握りつぶせるだけで良いので、 /dev/null を向き先にしたFileHandlerで全てのログを握りつぶす。

import logging 
from flask import Flask

l = logging.getLogger()
l.addHandler(logging.FileHandler("/dev/null"))
app = Flask(__name__)

@app.route("/", methods=["GET"])
def root():
    return "hello world"


if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=5000)

上記を起動すると分かるが、flaskが出力する全てのデフォルトのログを握りつぶした状態となったはず。