disable_existing_loggersの挙動について

## まずは結論から
- disable_existing_loggers=Trueの時、
	+ その設定ファイルで設定の対象となったロガーはその設定が採用される
	+ その設定ファイルで設定の対象とならなかったロガーは無効化される
- disable_existing_loggers=Falseの時
 	+ その設定ファイルで設定の対象になったロガーはその設定が採用される
 	+ その設定ファイルで設定の対象とならなかったロガーはルートロガーの設定が採用される

## 実験してみる
logging_condig_dictConfig()で設定する内容を

- 特に設定しない
- 個別のロガーのみ
- ルートロガーのみ

の三種類について、disable_existing_loggersをTrue/Falseにした時の挙動を調べるため、

- 初期状態
- logging.config.dictConfigを実行した直後
- loggerを再定義した後

の三箇所でログを出力してみる。
用いたスクリプトは以下の通り。

```python:log_test.py
import logging.config
import json
import argparse

def output_logs(logger):
    # loggerとloggingを出力
    print("-"*20 + "logger"+ "-"*20)
    logger.debug("debug")
    logger.info("info")
    logger.warning("warning")
    logger.error("error")
    logger.critical("critical")

    print("-"*20 + "logging" + "-"*20)
    logging.debug("debug")
    logging.info("info")
    logging.warning("warning")
    logging.error("error")
    logging.critical("critical")

def logging_condig_dictConfig(conf):
    if conf is not None:
        logconfig = json.load(open(conf, 'r'))
        logging.config.dictConfig(logconfig)

    print("="*50)
    print("logging.config.dictConfig():")
    print("disable_existing_loggers = {}".format(logconfig["disable_existing_loggers"]))
    print("="*50)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--log_config")
    args = parser.parse_args()

    logger = logging.getLogger('example')
    output_logs(logger)
    logging_condig_dictConfig(args.log_config)
    output_logs(logger)
    logger = logging.getLogger('example')
    output_logs(logger)

if __name__ == "__main__":
    main()

```

## 特に設定しない時
```json:conf.json
{
  "version": 1,
  "disable_existing_loggers": true/false
}
```



### disable_existing_loggers=True
```実行結果
--------------------logger-------------------- # デフォルト
warning
error
critical
--------------------logging-------------------- # デフォルト
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
==================================================
logging.config.dictConfig():
disable_existing_loggers = True
==================================================
--------------------logger-------------------- # ロガーが無効になる
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
--------------------logger-------------------- # 再定義しても無効のまま
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
```

### disable_existing_loggers=False

```実行結果
--------------------logger-------------------- # デフォルト
warning
error
critical
--------------------logging-------------------- # デフォルト
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
==================================================
logging.config.dictConfig():
disable_existing_loggers = False
==================================================
--------------------logger-------------------- # 無効にはならないが、ロガーの設定が変わっている(なぜ？）
WARNING:example:warning
ERROR:example:error
CRITICAL:example:critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
--------------------logger-------------------- # 再定義しても変化しない
WARNING:example:warning
ERROR:example:error
CRITICAL:example:critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
```

いずれの場合もルートロガーの設定は変化しないので、loggingの出力は一貫して同じ

## 個別のロガーに設定を付与
```logger = getLogger("example")```に設定を付加する

```json:conf.json
{
  "version": 1,
  "disable_existing_loggers": true/false,

  "formatters": {
    "simple": {
      "format": "[%(asctime)s][%(module)s:%(lineno)s][%(name)s][%(levelname)s] %(message)s"
    }
  },

  "handlers": {
    "console": {
      "class": "logging.StreamHandler",
      "level": "DEBUG",
      "formatter": "simple",
      "stream": "ext://sys.stdout"
    },

    "info_file_handler": {
      "class": "logging.handlers.RotatingFileHandler",
      "level": "DEBUG",
      "formatter": "simple",
      "filename": "log/test.log",
      "maxBytes": 10485760,
      "backupCount": 20,
      "encoding": "utf8"
    }
  },

  "loggers": {
    "example": {
      "level": "ERROR",
      "handlers": ["console", "info_file_handler"]
    }
  }
}
```
### disable_existing_loggers=True

```実行結果
--------------------logger--------------------
warning
error
critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
==================================================
logging.config.dictConfig():
disable_existing_loggers = True
==================================================
--------------------logger-------------------- # 設定を付与すると、以前に生成したロガーであっても有効になる
[2017-10-05 11:33:05,821][log_test:11][example][ERROR] error
ERROR:example:error
[2017-10-05 11:33:05,822][log_test:12][example][CRITICAL] critical
CRITICAL:example:critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
--------------------logger-------------------- # 再定義しても変化なし
[2017-10-05 11:33:05,823][log_test:11][example][ERROR] error
ERROR:example:error
[2017-10-05 11:33:05,823][log_test:12][example][CRITICAL] critical
CRITICAL:example:critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
```

### disable_existing_loggers=False
```実行結果
--------------------logger--------------------
warning
error
critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
==================================================
logging.config.dictConfig():
disable_existing_loggers = False
==================================================
--------------------logger-------------------- # 設定した通りのログが出力
[2017-10-05 11:29:49,830][log_test:11][example][ERROR] error
ERROR:example:error
[2017-10-05 11:29:49,831][log_test:12][example][CRITICAL] critical
CRITICAL:example:critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
--------------------logger-------------------- # 再定義しても変化しない
[2017-10-05 11:29:49,832][log_test:11][example][ERROR] error
ERROR:example:error
[2017-10-05 11:29:49,832][log_test:12][example][CRITICAL] critical
CRITICAL:example:critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
```


## ルートロガーに設定を付与
```json:conf.json
{
  "version": 1,
  "disable_existing_loggers": true/false,
  "formatters": {
    "simple": {
      "format": "[%(asctime)s][%(module)s:%(lineno)s][%(name)s][%(levelname)s] %(message)s"
    }
  },
  "handlers": {
    "console": {
      "class": "logging.StreamHandler",
      "level": "DEBUG",
      "formatter": "simple",
      "stream": "ext://sys.stdout"
    },
    "info_file_handler": {
      "class": "logging.handlers.RotatingFileHandler",
      "level": "DEBUG",
      "formatter": "simple",
      "filename": "log/test.log",
      "maxBytes": 10485760,
      "backupCount": 20,
      "encoding": "utf8"
    }
  },
  "root": {
    "level": "ERROR",
    "handlers": [
      "console",
      "info_file_handler"
    ]
  }
}
```
### disable_existing_loggers=True

```実行結果
--------------------logger--------------------
warning
error
critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
==================================================
logging.config.dictConfig():
disable_existing_loggers = True
==================================================
--------------------logger-------------------- # ロガーは無効化される
--------------------logging-------------------- # ルートロガーに設定が付与される
[2017-10-05 11:41:21,581][log_test:18][root][ERROR] error
[2017-10-05 11:41:21,582][log_test:19][root][CRITICAL] critical
--------------------logger-------------------- # ロガーを再定義しても無効化されたまま
--------------------logging--------------------
[2017-10-05 11:41:21,582][log_test:18][root][ERROR] error
[2017-10-05 11:41:21,583][log_test:19][root][CRITICAL] critical
```

### disable_existing_loggers=False

```実行結果
--------------------logger--------------------
warning
error
critical
--------------------logging--------------------
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
==================================================
logging.config.dictConfig():
disable_existing_loggers = False
==================================================
--------------------logger-------------------- # ルートロガーの設定が付与される(なるほど)
[2017-10-05 11:45:06,287][log_test:11][example][ERROR] error
[2017-10-05 11:45:06,288][log_test:12][example][CRITICAL] critical
--------------------logging-------------------- # ルートロガーの設定が付与される
[2017-10-05 11:45:06,288][log_test:18][root][ERROR] error
[2017-10-05 11:45:06,288][log_test:19][root][CRITICAL] critical
--------------------logger-------------------- # 再定義しても変化なし
[2017-10-05 11:45:06,288][log_test:11][example][ERROR] error
[2017-10-05 11:45:06,289][log_test:12][example][CRITICAL] critical
--------------------logging--------------------
[2017-10-05 11:45:06,289][log_test:18][root][ERROR] error
[2017-10-05 11:45:06,289][log_test:19][root][CRITICAL] critical
```