logging ログ出力 その5

yaml形式による設定

ログの設定使用できる設定ファイルにはyaml形式(辞書形式)とini形式があり、今回はyaml形式について説明します。

最低限設定する必要がある項目は以下のとおりとなります。ini形式との違いは、フォーマッター、ハンドラー、ロガーを別途列挙する必要が無いこと、rootロガーの設定が必須であることが挙げられます。

項目 説明
version スキーマのバージョンを表す整数値に設定されます。現在有効な値は1だけです。
formatters フォーマッターの設定を記述します。
handlers ハンドラーの設定を記述します。
loggers ロガーの設定を記述します。
root rootロガーの設定を記述します。

yaml形式で使用するにはyamlパーサが必要となります。以下でインストールしましょう。

pip install PyYAML

ではサンプルです。

# logconf.yml
version: 1

formatters:
  fmt1:
    format: '%(asctime)s %(name)s %(levelname)s %(message)s [fmt1]'
    
handlers:
  h1:
    class: logging.StreamHandler    
    level: DEBUG
    formatter: fmt1 
    stream: ext://sys.stdout
  h2: 
    class: logging.FileHandler
    level: DEBUG
    formatter: fmt1
    filename: sample.log

loggers:     
  sample:
    handlers: [h2]
    level: DEBUG
    qualname: console
    propagate: no

root:
  level: DEBUG
  handlers: [h1]

使用する側のpythonファイルは以下のようになります。

import yaml
from logging import config,getLogger
config.dictConfig(yaml.load(open("logconf.yml", encoding='UTF-8').read()))
logger = getLogger(__name__)
logger.error("エラーが発生しました")

yaml.loadでyaml形式を辞書型に変換して、config.dictConfigに読み込ませます。上のコードでは、h1というハンドラーをrootロガーに、h2というハンドラーをsampleという名前のロガーに設定しています。また、fmt1というフォーマッターをh1、h2に設定しています。なお、上のサンプルはあくまでも説明用なので、実運用では働きがわかるような名前を設定したほうが良いでしょう。なお、ロガーに複数のハンドラーを指定したい場合は、以下のようにカンマ区切りで列挙します。

handlers: [h1, h2]

json形式による設定

dictConfigで指定しているのは辞書型なので、実はyaml形式以外であっても辞書型であれば何でも使用可能です。参考として、上のコードをjsonに書きなおしたものも掲載します。

{
  "version": 1,
  "formatters": {
    "fmt1": {
      "format": "%(asctime)s %(name)s %(levelname)s %(message)s [fmt1]"
    }   
  },  
  "handlers": {
    "h1": {
      "class": "logging.StreamHandler",
      "level": "DEBUG",
      "formatter": "fmt1",
      "stream": "ext://sys.stdout"
    },
    "h2": {
      "class": "logging.StreamHandler",
      "level": "DEBUG",
      "formatter": "fmt1",
      "stream": "ext://sys.stdout"
    }
  },  
  "loggers": {
    "console": {
      "handlers": [
        "h2"
      ],  
      "level": "DEBUG",
      "qualname": "sample",
      "propagate": "no"
    }   
  },  
  "root": {
    "level": "DEBUG",
    "handlers": [
      "h1"
    ]   
  }
}
from logging import config,getLogger
import json

config.dictConfig(json.loads(open("logconf.json", encoding='UTF-8').read()))
logger = getLogger(__name__)
logger.error("エラーが発生しました")