【问题标题】:Easier way to enable verbose logging启用详细日志记录的更简单方法
【发布时间】:2012-12-15 08:16:59
【问题描述】:

如果我从命令行启用--verbose 并且脚本中有以下内容,我想添加一个调试打印语句测试。

logger.info("test")

我经历了以下问题,但无法得到答案...

【问题讨论】:

    标签: python python-2.7


    【解决方案1】:

    如果您想为不想(或不能)编辑的脚本启用 logging.DEBUG 级别,您可以自定义启动:

    jcomeau@aspire:~$ python -c "import site; site._script()"
    [snip]...
    USER_BASE: '/home/jcomeau/.local' (exists)
    USER_SITE: '/home/jcomeau/.local/lib/python2.7/site-packages' (exists)
    ENABLE_USER_SITE: True
    jcomeau@aspire:~$ mkdir -p ~/.local/lib/python2.7/site-packages
    jcomeau@aspire:~$ vi ~/.local/lib/python2.7/site-packages/usercustomize.py
    

    输入以下内容:

    import os, logging
    if os.getenv('DEBUGGING'):
        logging.basicConfig(level = logging.DEBUG)
    

    那么你可以:

    jcomeau@aspire:~$ mkdir -p /tmp/some/random/
    jcomeau@aspire:~$ echo 'import logging; logging.debug("test")' >> /tmp/some/random/script.py
    jcomeau@aspire:~$ DEBUGGING=1 python /tmp/some/random/script.py 
    DEBUG:root:test
    

    来自 Paul Ollis,http://nedbatchelder.com/blog/201001/running_code_at_python_startup.html


    2017-07-18:我已经改用另一种方法:

    logging.basicConfig(level=logging.DEBUG if __debug__ else logging.INFO)
    

    它的作用是,如果你在没有优化的情况下运行(如python script.py),你会得到调试级别的东西,而如果你使用python -OO script.py 运行,你不会。没有要设置的环境变量。

    【讨论】:

      【解决方案2】:

      这是一个更简洁的方法,它会进行边界检查,并会在帮助中列出有效值:

      parser = argparse.ArgumentParser(description='This is a demo.')
      parser.add_argument("-l", "--log", dest="logLevel", choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], help="Set the logging level")
      
      args = parser.parse_args()
      if args.logLevel:
          logging.basicConfig(level=getattr(logging, args.logLevel))
      

      用法:

      demo.py --log DEBUG
      

      【讨论】:

      • 不需要getattrlevel=logging.getLevelName(args.logLevel)
      • 更好的是在帮助文本中添加default='INFO'add_argument() 以及(default: %(default)s),然后删除if args.logLevel 并始终调用basicConfig()。然后用户可以知道默认值将始终是什么。
      【解决方案3】:

      这是另一个让 argparse 计算 -v 选项的方法,以将详细程度从默认的 WARNING 到 INFO (-v) 再到 DEBUG (-vv) 增加两个级别。这不会映射到logging定义的常量,而是直接计算值,限制输入:

      print( "Verbosity / loglevel:", args.v )
      logging.basicConfig( level=10*(3-max(0,min(args.v,3))) )
      logging.debug("debug") # 10
      logging.info("info") # 20
      logging.warning("warning") # 30 - The default level is WARNING, which means that only events of this level and above will be tracked
      logging.error("error") # 40
      logging.critical("critical") # 50
      

      【讨论】:

      • 注意 argparse 参数需要default=0,否则你会得到TypeError: '<' not supported between instances of 'int' and 'NoneType'。或者在上面加上args.v or 0...
      【解决方案4】:

      另一个变体是计算-v 的数量,并将该计数用作list 的索引,实际水平来自logging

      import argparse
      import logging
      
      parser = argparse.ArgumentParser()
      parser.add_argument('-v', '--verbose', action='count', default=0)
      args = parser.parse_args()
      
      levels = [logging.WARNING, logging.INFO, logging.DEBUG]
      level = levels[min(len(levels)-1,args.verbose)]  # capped to number of levels
      
      logging.basicConfig(level=level,
                          format="%(asctime)s %(levelname)s %(message)s")
      
      logging.debug("a debug message")
      logging.info("a info message")
      logging.warning("a warning message")
      

      这适用于-vvvv-vvv-vv-v-v -v 等,如果没有-v,则如果提供更多-v,则选择logging.WARNING,它将逐步执行INFODEBUG

      【讨论】:

      • 不错!请记住以python script.py -v [other_args] 运行您的脚本。如果您运行python -v script.py(在脚本之前运行-v),您将从Python 解释器本身获得大量调试输出,但不会从您的脚本中获得。 (答案不是问题,只是对其他读者的警告)。
      • 好一个!这是最灵活(多个日志记录级别)、干净(不污染参数命名空间)和直观(由其他几个工具使用)的解决方案。
      【解决方案5】:

      我发现--verbose(针对用户)和--debug(针对开发人员)都很有用。以下是我使用loggingargparse 的方法:

      import argparse
      import logging
      
      parser = argparse.ArgumentParser()
      parser.add_argument(
          '-d', '--debug',
          help="Print lots of debugging statements",
          action="store_const", dest="loglevel", const=logging.DEBUG,
          default=logging.WARNING,
      )
      parser.add_argument(
          '-v', '--verbose',
          help="Be verbose",
          action="store_const", dest="loglevel", const=logging.INFO,
      )
      args = parser.parse_args()    
      logging.basicConfig(level=args.loglevel)
      

      因此,如果设置了--debug,则日志记录级别设置为DEBUG。如果--verbose,日志记录设置为INFO。如果两者都不是,则缺少 --debug 会将日志记录级别设置为默认的 WARNING

      【讨论】:

      • 我真的很喜欢这种方法...让 argparse 完成所有工作,不要 ifs 或 parse_args 之后的任何内容
      • @MestreLion:谢谢。对我来说确实感觉很蟒蛇。
      • 有一个问题:logging 默认情况下将所有内容打印到 stderr 并且您真的希望将您的正常程序输出(来自--verbose 的那个)与仅用于开发的(来自--debug 的那个)分开
      • @MichałGóral:这听起来不错。我可以使用logging.basicConfiginfo() 消息发送到stdout 并将debug() 消息发送到stderr 吗?
      • @MatthewLeingang:为此,您必须使用多个handlers。这是示例:stackoverflow.com/a/16066513/1088577
      【解决方案6】:

      您可以在-v 标志之后将级别显式指定为整数:

      parser = argparse.ArgumentParser()
      parser.add_argument("-v", "--verbose", const=1, default=0, type=int, nargs="?",
                          help="increase verbosity: 0 = only warnings, 1 = info, 2 = debug. No number means info. Default is no verbosity.")
      args = parser.parse_args()
      
      logger = logging.getLogger()
      if args.verbose == 0:
          logger.setLevel(logging.WARN) 
      elif args.verbose == 1:
          logger.setLevel(logging.INFO) 
      elif args.verbose == 2:
          logger.setLevel(logging.DEBUG) 
      

      【讨论】:

        【解决方案7】:

        您需要将Argparse Tutorial 的智慧与Python's Logging HOWTO 结合起来。这是一个例子......

        > cat verbose.py 
        #!/usr/bin/env python
        
        import argparse
        import logging
        
        parser = argparse.ArgumentParser(
            description='A test script for http://stackoverflow.com/q/14097061/78845'
        )
        parser.add_argument("-v", "--verbose", help="increase output verbosity",
                            action="store_true")
        
        args = parser.parse_args()
        if args.verbose:
            logging.basicConfig(level=logging.DEBUG)
        
        logging.debug('Only shown in debug mode')
        

        运行帮助:

        > ./verbose.py -h
        usage: verbose.py [-h] [-v]
        
        A test script for http://stackoverflow.com/q/14097061/78845
        
        optional arguments:
          -h, --help     show this help message and exit
          -v, --verbose  increase output verbosity
        

        以详细模式运行:

        > ./verbose.py -v
        DEBUG:root:Only shown in debug mode
        

        默默运行:

        > ./verbose.py   
        > 
        

        【讨论】:

        • // ,我可以确认这是可行的。然而,“store_true”的工作原理仍然是一个谜。
        • 这意味着,如果指定了选项,则将值True 分配给args.verbose。不指定它意味着False
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-08
        • 1970-01-01
        • 2020-08-18
        • 1970-01-01
        • 1970-01-01
        • 2022-11-15
        相关资源
        最近更新 更多