適当おじさんの適当ブログ

技術のことやゲーム開発のことやゲームのことなど自由に雑多に書き連ねます

いまさらながら Flask についてまとめる 〜Logging〜

はじめに

いまさらながら Flask について整理していきます。「Flaskとかいうやつを使って、試しにアプリ開発にトライしてみたい」くらいの感覚の人を対象にしています。

Flaskのバージョンは 0.12.2 です。

この記事では、Logging について紹介していきます。

Logging

Flaskのloggerを使うことで、Python標準のloggingLoggerを取得できます。パッケージ名を名前に持つLoggerが取得されます。

# log_test.py
from flask import Flask                                                         
                                                                                  
app = Flask(__name__)                                                                                                                          
                                                                            
@app.route('/')                                                                 
def index():                                                                    
    app.logger.debug('debug')                                                   
    app.logger.info('info')                                                     
    app.logger.warn('warn')                                                     
    app.logger.error('error')                                                   
    app.logger.critical('critical')                                                                                                                         
    return "logging"                                                            
                                                                                                                                                    
if __name__ == '__main__':                                                      
    app.run(debug=True)              

上記アプリケーションにアクセスすると、コンソールに各種ログが出力されていることが確認できると思います。

デフォルトで登録されているHandler

app.loggerには、DebugHandlerProductionHandler が登録されています。debug=True(デバッグモード)で実行した場合はDebugHandlerで、そうでない場合はProductionHandlerでログが出力されます。それぞれのHandlerは異なるログレベルとログフォーマットが設定されています。

つまり、デバッグモードで実行するか否かでログレベルとログフォーマットが変化します。ログレベルについてはこちらを参照ください。

デバッグモードで実行した場合

DEBUG以上 のログレベルのログが出力されます。また、このときのログフォーマットは以下になります。

--------------------------------------------------------------------------------
%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:
%(message)s
--------------------------------------------------------------------------------
デバッグモードでない場合

ERROR以上 のログレベルのログが出力されます。ログのフォーマットは以下になります。

[%(asctime)s] %(levelname)s in %(module)s: %(message)s

ログの出力先を変更する

Python標準のLoggerは、Handler によって出力先を変更します。そして先述した通り、app.loggerで得られるLoggerはPython標準のものです。つまり、Flaskアプリケーションでも同様に、LoggerにHandlerを追加/削除することでログの出力先を変更できます。

Pythonには様々なHandlerが標準で用意されています。これらのHandlerを追加すれば良いです。ちなみに、コンソールに出力しているHandlerは StreamHandler です。

RotatingFileHandler

RotatingFileHandler は、ログをファイルに出力し、かつ、サイズに応じてローテーションしてくれる便利なHandlerです。これを例にFlaskのLoggerにHandlerを追加します。

from flask import Flask                                                         
                                                                                  
app = Flask(__name__)     

# Add RotatingFileHandler to Flask Logger
handler = logging.handlers.RotatingFileHandler("test.log", "a+", maxBytes=3000, backupCount=5)
handler.setLevel(logging.INFO) 
handler.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)s in %(module)s: %(message)s'))
app.logger.addHandler(handler)

@app.route('/')                                                                 
def index():                                                                    
    app.logger.debug('debug')                                                   
    app.logger.info('info')                                                     
    app.logger.warn('warn')                                                     
    app.logger.error('error')                                                   
    app.logger.critical('critical')                                                                                                                         
    return "logging"                                                            
                                                                                                                                                    
if __name__ == '__main__':                                                      
    app.run(debug=True)                                 

同様にアプリケーションにアクセスすると、test.logが生成され、ログメッセージが書かれていることが確認できます。 このようにして、Python標準のLoggerと同じようにHandlerを追加できます。

Python標準のLoggerのみを使いたい場合

FlaskのLoggerを使わず、それらを無効にしたい場合もあるかもしれません。そのときの設定方法です。アプリケーションのできるだけ早い段階で無効化処理をしておかないと、思わぬところでログが出力されてしまう可能性があります。

from flask import Flask                                                         
                                                                                  
app = Flask(__name__)   
# FlaskのLoggerを無効化する
app.logger.disabled = True  
# werkzeugのLoggerを無効化する
werkzeug_logger = logging.getLogger('werkzeug')   
werkzeug_logger.disabled = True  

また、FlaskのLoggerにデフォルトで登録されているHandlerを削除したい場合は以下です。

app.logger.handlers.clear()

ただ、すべてのHandlerを削除するくらいなら、上記の方法で無効化してPython標準のLoggerにHandlerを登録したほうがわかりやすくて良い気がします。