【问题标题】:Python module structure and loggingPython 模块结构和日志记录
【发布时间】:2016-03-26 11:20:09
【问题描述】:

我正在尝试从主流程和子模块登录到同一个文件:

/proxy
/proxy/proxy/network.py
/proxy/proxy.py

network.py:

import logging
print __name__
...

logging.getLogger(__name__).warning("test warn")

proxy.py:

import logging
print __name__
logging.basicConfig(filename="console", format="%(message)s", disable_existing_loggers=False)
logging.warning("test main")

然后我看到登录 proxy.py 有效,而在 network.py 中无效,显然是因为他们的 name 是:

proxy.network
__main__

分别。

如果我将它们放在同一个文件夹中,它们的名称将是:

network
__main__

这也行不通。看起来我必须以某种方式告诉我我的项目根目录相对于 proxy.py (无论它在哪里)高一级,在这种情况下,它们都将具有名称“proxy.*”。

如何将项目根文件夹指向解释器? 如何统一它们的模块结构名称,以启用日志记录(在任一模块结构中)?

【问题讨论】:

    标签: python logging module


    【解决方案1】:

    将所有日志信息保存到同一个文件的最简单方法是,不要在 getLogger() 中提供参数 [而不是您现在使用的,getLogger(name)]

    但请记住,如果您正在使用其他一些使用日志记录的模块(在您的项目之外,可能是某些第三方,例如 httplib),他们最终可能会使用这种方法将数据保存在您的日志文件中

    【讨论】:

      【解决方案2】:

      编辑:这里是对与整个包相关的文件名的访问:

      filepath = __file__ if __name__ == '__main__' else __name__
      

      对于以下结构,它给出:

      mypack
      ├── __main__.py   # -> mypack.__main__
      └── sub
          ├── __init__.py
          └── sub.py  # -> mypack.sub.sub
      

      这是一个sn-p:

      def logger(name=None, root_name=PACKAGE_NAME):
          if name:
              return logging.getLogger(root_name + '.' + name)
          else:
              return logging.getLogger(root_name)
      

      我通常在commons.pyutils.py 中定义这个函数,由我的包的所有模块导入。

      利用 sublogger 系统,这允许包使用包的主日志记录:

      import utils
      logger = utils.logger()
      logger.info('module xxx started')
      

      或专门用于特定概念的子记录器:

      import utils
      logger = utils.logger('vm')
      logger.info('module vm.xxx started')
      

      文件路径和日志配置现在已解耦并显式绑定。 每个模块都可以自动化:

      import utils
      logger = utils.logger(__file__)
      logger.info('module ' + __file__ + ' started')
      

      由于 sublogger 系统,logger 'pk.vm' 将(默认情况下)继承 'pk' 配置,即使用相同的处理程序,从而写入相同的日志文件。 但是,为任何 sublogger 定义一些特定的行为或处理程序会很有用:

      logging.config.dictConfig({
          'version': 1,
          'disable_existing_loggers': True,
          'formatters': {
              'verbose': {
                  'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s',
              },
              'simple': {
                  'format': '%(levelname)s %(message)s',
              },
          },
          'handlers': {
              'console':{
                  'level':LOG_LEVEL,
                  'class':'logging.StreamHandler',
                  'formatter': 'simple',
              },
              'logfile': {
                  'level': LOG_LEVEL,
                  'class': 'logging.handlers.RotatingFileHandler',
                  'filename': DIR_LOGS + LOGGER_NAME + '.log',
                  'mode': 'w',
                  'maxBytes': LOGFILE_MAX_SIZE,
                  'formatter': 'verbose',
              },
              'logfile' + SUBLOGGER_SEPARATOR + SUBLOGGER_VM: {
                  'level': LOG_LEVEL,
                  'class': 'logging.handlers.RotatingFileHandler',
                  'filename': DIR_LOGS + LOGGER_NAME + '.' + SUBLOGGER_VM + '.log',
                  'mode': 'w',
                  'maxBytes': LOGFILE_MAX_SIZE,
                  'formatter': 'verbose',
              },
          },
          'loggers': {
              PACKAGE_NAME: {
                  'handlers':['console', 'logfile'],
                  'propagate': True,
                  'level':LOG_LEVEL,
              },
              PACKAGE_NAME + SUBLOGGER_SEPARATOR + SUBLOGGER_VM: {
                  'handlers':['logfile' + SUBLOGGER_SEPARATOR + SUBLOGGER_VM],
                  'level':LOG_LEVEL,
              },
          }
      })
      

      【讨论】:

      • 应该可以,但是您对 name 的使用反映模块结构有何看法?在不同的答案/手册中,他们总是说“文件 network.py 位于相对于 proxy.py (main.py) 的子模块中”,但如果其中一个文件位于顶层,我无法意识到如何使用它。跨度>
      • 据我所知,这需要模块知道它在包架构中的位置。这可能不是一个好的解决方案。
      • 我已经编辑了我的答案:_name_ 和 _file_ 可用于检索架构中的文件位置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 2011-11-29
      • 2021-11-23
      • 1970-01-01
      • 2020-08-11
      • 2015-01-13
      • 1970-01-01
      相关资源
      最近更新 更多