记录dictConfig不适用于多处理

时间:2017-06-13 15:13:10

标签: python python-2.7 logging

我的问题是:Python日志配置无法使用配置文件和多处理。

我正在使用python2.7。

实施例

这是我的 example.py

import json
import logging
import logging.config
import multiprocessing


def get_logger():
    with open("logging.conf") as fd:
        config_json_obj = json.load(fd)
    #logging.config.dictConfig(config_json_obj)
    logging.basicConfig(filename="my.log", level=logging.INFO)
    logger = logging.getLogger(__name__)
    return logger

def funSquare(num):
    logger = get_logger()
    # write logging info from process
    logger.info(num ** 2)
    return num ** 2


if __name__ == '__main__':
    logger = get_logger()

    logger.info("Start program")
    pool = multiprocessing.Pool()
    results = pool.map(funSquare, range(10))
    print(results)

这是我的 logging.conf 文件:

{
  "version": 1,
  "formatters":
  {
    "simple":
    {
      "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    },
    "verbose":
    {
      "format": "%(asctime)s %(thread)s %(levelname)s %(module)s [-] %(message)s"
    }
  },
  "handlers":
  {
    "console":
    {
      "class": "logging.StreamHandler",
      "level": "DEBUG",
      "formatter": "simple",
      "stream": "ext://sys.stdout"
    },
    "file":
    {
      "class": "logging.FileHandler",
      "formatter": "verbose",
      "level": "DEBUG",
      "filename": "mylog.log"
    }
  },
  "loggers":
  {
    "Main":
    {
      "level": "INFO",
      "handlers": ["console", "file"],
      "propagate": 0
    }
  },
  "root":
  {
    "level": "DEBUG",
    "handlers": ["file"]
  }
}

此时,example.py正在运行。您将从主程序和新进程中获取my.log文件记录行。

重现我的问题

现在,如果我换行:

#logging.config.dictConfig(config_json_obj)
logging.basicConfig(filename="my.log", level=logging.INFO)

通过

logging.config.dictConfig(config_json_obj)
#logging.basicConfig(filename="my.log", level=logging.INFO)

在my.log文件中,您将只看到来自主程序的日志行,而不是来自进程。

现在我的问题:

  1. 为什么会这样?
  2. 解决方案是什么?
  3. 感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

您不应期望从多个进程写入单个文件才能工作(它可能在某些情况下有效,但无法保证)。正确的方法是使用多处理Queue,并且所有文件都由单个进程完成,如2010年this blog post中所述(此处重现时间太长)。重要的是每个进程在创建之后配置记录。如果需要,您可以调整链接的示例以使用dictConfig而不是示例中显示的编程配置。

答案 1 :(得分:1)

问题是__name__会评估'__main__';你需要

  • :将配置文件中的"Main"重命名为"__main__"(对于记录器的名称)
  • 或(可能更健壮):主文件中的logger = logging.getLogger('Main')

您未使用logging.getLogger(__name__)获取的记录器。

答案 2 :(得分:0)

在logging.DictConfig中,根记录器由“”定义。因此,在词典中,您应该使用:

"":
{
  "level": "DEBUG",
  "handlers": ["file"]
}

正确设置根记录器(在.ini文件中,您使用“ root”,不要问我为什么)