コンソール画面に出力しているログのうち、INFOレベル以下はstdoutに、WARNINGレベル以上をstderrに出力するサンプルを紹介します。
一般的なコンソールはstderrの出力を強調表示してくれるので見落としが減ります。この設定はしないよりはしておいた方がいいです。

ロギングの細かい解説は長期戦になるのでしないことにして、ここで紹介したサンプルの一部をコピペして流用するのに最低限の最低限、必要かなと感じる部分だけサラッと解説するスタンスでいきます。
よくわからない部分は雰囲気でなんとかしてもらうスタンスで。(笑)
このページの内容
Pythonプログラム内で設定
Pythonプログラム内で全ての設定をするサンプルです。(次の章では同じことを設定ファイルでする方法を紹介します)
実際の設定はinit_logging()関数内でしています。
出力先をstdoutとstderrに分けないといけないので、INFOレベルまでのログだけをstdoutに出力するハンドラと、WARNINGレベル以上のログだけをstderrに出力するハンドラの2つを作っています。
from logging import getLogger, StreamHandler, \ Filter , Formatter, DEBUG, INFO, WARNING from sys import stdout, stderr root = getLogger() class LevelFilter( Filter ): """ max_levelで指定されたログレベルまでしか出力しなくするフィルタを自作 """ def __init__( self , max_level = INFO): self .max_level = max_level def filter ( self , record): """ このメソッドはログ出力メソッドがコールされた時に呼び出されます。 役割は、0か1を戻り値として返すことです。 戻り値が0の場合はログが出力されず、それ以外の場合はログ出力されます。 """ return record.levelno < = self .max_level def init_logging(): global root formatter = Formatter( '{asctime} {name:<8s} {levelname:<8s} {message}' , style = '{' ) out_handler = StreamHandler(stdout) out_handler.setFormatter(formatter) # WARNING以上がstdoutに出力されないように自作したフィルタをセット out_handler.addFilter(LevelFilter(INFO)) err_handler = StreamHandler(stderr) err_handler.setLevel(WARNING) err_handler.setFormatter(formatter) root.addHandler(out_handler) root.addHandler(err_handler) root.setLevel(DEBUG) def main(): global root root.debug( 'これはデバッグログ' ) root.info( 'これは情報ログ' ) root.warning( 'これは警告ログ' ) root.error( 'これはエラーログ' ) root.critical( 'これはめっちゃヤバい状況のログ' ) if __name__ = = '__main__' : init_logging() main() |
実行結果:

設定ファイルで設定
ログ出力などの設定は、プログラムに直接書かずに設定ファイルに記述するのが一般的です。
まずはconfig.ymlを作成し、設定をYAML形式で記述します。
version: 1 formatters: default: format: '{asctime} {name:<8s} {levelname:<8s} {message}' style: '{' filters: at-most-info: '()' : filter.LevelFilter max_level: INFO handlers: stdout: class: logging.StreamHandler stream: ext : //sys.stdout formatter: default filters: - at-most-info stderr: class: logging.StreamHandler stream: ext : //sys.stderr formatter: default level: WARNING root: level: DEBUG handlers: - stdout - stderr |
config.ymlからfilter.LevelFilterとして参照しやすいように、フィルタークラスはメインプログラムとは分けてfilter.pyに定義しました。
from logging import Filter , INFO, getLevelName class LevelFilter( Filter ): def __init__( self , max_level = INFO): if isinstance (max_level, str ): max_level = getLevelName(max_level) self .max_level = max_level def filter ( self , record): return record.levelno < = self .max_level |
設定ファイルを読み込んでDict形式にするために、ruamel.yamlパッケージをインストールします。
$ pip install ruamel.yaml |
そして設定ファイルから読み込んでロギング設定を反映するPythonプログラムconsole_output.pyを書きます。
from logging import getLogger from ruamel.yaml import YAML from pathlib import Path from logging.config import dictConfig def init_logging(): config_path = Path( 'config.yml' ) config_content = YAML().load(config_path) dictConfig(config_content) def main(): root = getLogger() root.debug( 'これはデバッグログ' ) root.info( 'これは情報ログ' ) root.warning( 'これは警告ログ' ) root.error( 'これはエラーログ' ) root.critical( 'これはめっちゃヤバい状況のログ' ) if __name__ = = '__main__' : init_logging() main() |
設定をするためのinit_logging()関数の中身がかなりスッキリしました。
それぞれのファイルは同じフォルダに入っている状態です。
project_dir |- config.yml |- filter.py |- console_output.py |
実行結果:
