关于disable_existing_loggers的行为


首先,从结论

  • 当disable_existing_loggers = True时,

    • 记录器采用该设置,它是设置文件中设置的目标。
    • 未包含在配置文件中的记录器将被禁用
  • 当disable_existing_loggers = False时

    • 设置文件中作为设置目标的记录器将采用该设置
    • 根记录器的设置适用于不是设置文件中设置目标的记录器。

实验

设置要由logging_condig_dictConfig()设置的内容

  • 没有特别的设定
  • 仅个人记录器
  • 仅根记录器

若要调查将

三种类型的disable_existing_loggers设置为True / False时的行为

  • 初始状态
  • 运行logging.config.dictConfig后立即
  • 重新定义记录器之后

尝试在

的三个位置输出日志。
使用的脚本如下。

log_test.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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()

(未特别设置)

conf.json

1
2
3
4
{
  "version": 1,
  "disable_existing_loggers": true/false
}

disable_existing_loggers = True

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
--------------------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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
--------------------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

在两种情况下,根记录器的设置都不会更改,因此记录输出始终相同

为各个记录器提供设置

将设置添加到logger = getLogger("example")

conf.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
  "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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
--------------------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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
--------------------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

将设置提供给root logger

conf.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
  "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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--------------------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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
--------------------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