【问题标题】:Python: How to logging.setLevel verbosity from OptionParser type='count'?Python:如何从 OptionParser type='count' 记录.setLevel 详细程度?
【发布时间】:2013-08-06 06:17:10
【问题描述】:

所以我想将日志记录添加到我一直在维护的一个小的内部命令行实用程序中。 (实际上,我正在将其相当难看的手动编码日志转换为使用 Python 的 logging 模块;并在此过程中清理一些缺陷)。

首先,我想保留现有的行为、缺陷和所有内容,以供遗留使用。任何可能依赖于它已经发出的无关警告的脚本都不应该因为我正在做的事情而中断。新功能应该通过-v 开关,在OptionParser 中实现为type=count(根据古老的Unix/Linux 约定)。这里的问题是单个 -v 将详细程度从 -1 设置为 0(零)......具有讽刺意味的是,至少抑制了来自 Paramiko 库的一条警告消息(没有处理程序可以 为记录器“paramiko.transport”找到)。从那里我想支持最多四个额外的-v 选项,并使用带有logging.setLevel() 的选项来逐渐变得更详细,从logging.CRITICALlogging.DEBUG

问题来了!

我可以很容易地使用类似的东西:

if opts.verbosity == 0: # default is -1 do NOTHING
    # 0 ironically makes it slightly quieter
    logging.getLogger().addHandler(logging.NullHandler())
elif opts.verbosity > 0:
    logging.basicConfig()
    logging.getLogger().setLevel(50 - min(40, 10*opts.verbosity))
    # UGLY BUT IT WORKS.
    # logging.CRITICAL is 50, 
    # each -v reduces log filter by 10 down to 10

换句话说,我将我的-v 开关数转换为十的倍数,然后从最不冗长的到最冗长的部分减去。 (这是Python2.7.x)。

我注意到logging.basicConfig() 消除了“未找到句柄”警告,并暴露了一些潜在的错误消息,只要该实用程序投入生产(多年),这些错误消息就一直(无害地)发生。 (所以,如果我像预期的那样从默认值 0 开始,那么我就会向用户引入令人担忧的噪音。

但我的问题是:是否有更“正确”的方式将数字详细设置转换为 logging.setLevel()?使用这个实现细节(与logging.CRITICAL, logging.ERROR, logging.WARN,... 等相关的数值)似乎很脏。

当然,我不可能是唯一一个使用 -vvv 和 Python 标准 OptionParserlogging 模块的人。但是阅读docs 和谷歌搜索并没有找到任何关于此的“最佳实践”。

【问题讨论】:

    标签: python logging verbosity optionparser


    【解决方案1】:

    至少更干净:

    level = {
        1: logging.ERROR,
        2: logging.WARNING,
        3: logging.INFO,
        4: logging.DEBUG
    }.get(opts.verbosity, logging.DEBUG)
    

    (我建议也将 optparse 转换为 argparse。)

    【讨论】:

      【解决方案2】:

      (是的,恢复旧帖子)

      我最近也想要这样的东西,但我不想使用dict。这是我的实现:

      def logging_level(verbosity):
          """ Converts a verbosity number to a logging level
      
          Args:
              verbosity - a number, possibly collected from ``argparse``'s ``count``
              action. If ``verbosity`` is out of the range of possible logging levels
              it will be normalized to the nearest level. Does not take into
              consideration custom levels.
          """
          levels = [
              logging.CRITICAL,
              logging.ERROR,
              logging.WARNING,
              logging.INFO,
              logging.DEBUG
          ]
      
          return levels[max(min(len(levels) - 1, verbosity), 0)]
      

      【讨论】:

        猜你喜欢
        • 2016-10-25
        • 2019-09-08
        • 1970-01-01
        • 1970-01-01
        • 2017-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-23
        相关资源
        最近更新 更多