やりたいことはタイトルどおり。
注意
本記事ではデフォルトで出力されるログを握りつぶすことを主眼においている。
アプリケーションレイヤーできちんとログを出力すること。
動機
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を設定している箇所
以下でログを出力するためのヘルパーメソッドとなる。
なるほど。
WSGIRequestHandler
内にある, log_request
などが、 log
メソッドを呼び、それは最終的に werkzeug/_internal.py
にある、_log
メソッドを経由してgetattrでloggingの持つメソッドを文字列で指定しながら呼び出している形となる模様。
つまり
きちんと取り組むなら、以下のファイル内にある WSGIRquesutHandler
の logメソッドなどなどを継承したオブジェクトを作って... とかが考えられる。
が、前述したとおり一旦握りつぶせるだけで良いので、 /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が出力する全てのデフォルトのログを握りつぶした状態となったはず。