【问题标题】:Disable boto logging without modifying the boto files在不修改 boto 文件的情况下禁用 boto 日志记录
【发布时间】:2010-12-12 06:55:10
【问题描述】:

我正在使用 Boto 库与 AWS 通信。我想禁用日志记录。 (或重定向到 /dev/null 或其他文件)。我找不到明显的方法来做到这一点。我试过了,但这似乎没有帮助:

import boto
boto.set_file_logger('boto', 'logs/boto.log')

这说明这是可能的,http://developer.amazonwebservices.com/connect/thread.jspa?messageID=52727&#52727 但据我所知,文档并没有说明如何。

【问题讨论】:

    标签: python logging amazon-web-services boto


    【解决方案1】:

    如果您正在处理 boto3,可以通过在 basicConfig 中设置通用日志记录级别来完成。在下面的示例中,我们尝试检查 S3 服务的存储桶中是否存在文件:

    import boto3
    import botocore
    import logging
    
    logging.basicConfig(..., level=logging.INFO) # ***** HERE IS THE SOLUTION *****
    
    s3 = boto3.resource('s3', ...) # credetials
    my_bucket = s3.Bucket('bucket_name')
    
    logging.info('INFO TEST')
    logging.error('ERROR TEST')
    logging.warning('WARNING TEST')
    
    try:
        my_bucket.Object('test/test.txt').load() # it will send some https requests and DEBUG them in logging
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == "404":
            print('The object does not exist.')
    else:
        print('The object does exist.')
    

    【讨论】:

      【解决方案2】:

      请注意,此解决方案还将禁用非 boto 日志。 请参阅mchlfchr's answer


      不幸的是,对我来说,发布的解决方案都没有奏效。可能是由于同时 boto 本身的变化。

      But sometimes a look into the manual does help..

      import logging
      import boto3
      boto3.set_stream_logger('', logging.CRITICAL)
      

      【讨论】:

      • 如果您正在使用它,那么所有其他相关日志 (!= boto*) 也会消失
      • 他们为什么会消失?
      • 查看我的扩展答案:stackoverflow.com/a/60008283/1654284
      • 我还是不明白为什么python的根记录器会被它触动。但你的例子表明。干得好,伙计 :) 点赞。
      【解决方案3】:

      python 中的日志记录模块还有另一个烦人的属性:如果再次导入日志记录(例如,因为从导入日志记录的文件中导入函数)在为代码设置日志级别之后,设置级别可能没有任何效果。我不知道为什么会这样的确切细节,但我只是在实现如下所示之后才设法为导入的库设置正确的日志级别,并且总是使用由该函数创建的记录器。定义此记录器创建函数的文件是我的代码库中唯一导入记录的文件。

      import logging
      
      def get_logger_by_name(logger_name: str, log_filepath: str = "/training.log") -> logging.Logger:
          """
          Function that reloads logging module to store logs into a file and creates logger
          :param logger_name: Name of the logger that is returned
          :param log_filepath: filepath to log_file to store all logs
          :return: logger object
          """
          reload(
              logging
          )  # we need to import logging again to configure log file. https://stackoverflow.com/a/53553516/11758585
          logging.basicConfig(
                  level=logging.DEBUG,
                  format="%(asctime)s %(levelname)-8s %(name)-10s %(message)s",
                  datefmt="%Y-%m-%d %H:%M:%S",
                  handlers=[logging.FileHandler(log_filepath), logging.StreamHandler()],
              )
          logger = logging.getLogger(logger_name)
          logger.setLevel(logging.DEBUG)
      
          # clean messy log output by setting log level to WARNING for unimportant loggers
          logging.getLogger("botocore").setLevel(logging.WARNING)
          logging.getLogger("boto3").setLevel(logging.WARNING)
          logging.getLogger("boto").setLevel(logging.WARNING)
          logging.getLogger("s3transfer").setLevel(logging.WARNING)
          return logger
      

      【讨论】:

        【解决方案4】:

        此答案适用于使用logging.config.dictConfig 的人。

        建议禁用所有外部包的DEBUG和INFO消息,不限于botocoreboto3

        LOGGING_CONFIG = { # Add your preexisting logging config here.
            "loggers": { # Add your preexisting loggers here.
                "": {"level": "WARNING", "handlers": ["console"], "propagate": False},  # Root logger.
             }
        

        或者,禁用来自botocoreboto3 但不是来自所有外部包的调试消息:

        LOGGING_CONFIG = { # Add your preexisting config here too.
            "loggers": { # Add your preexisting loggers here too.
                "botocore": {"level": "WARNING", "handlers": ["console"], "propagate": False},
                "boto3": {"level": "WARNING", "handlers": ["console"], "propagate": False},
             }
        

        假设您的日志记录配置字典名为 LOGGING,接下来运行:

        logging.config.dictConfig(LOGGING)
        

        上面必须在导入boto3之前运行,不管是直接导入还是间接导入!如果在 boto3 已经导入后运行,它不会完全工作。您可以选择将上面的"WARNING"替换为"INFO""ERROR""CRITICAL"

        【讨论】:

        • 可能是最干净的选项,考虑到日志记录配置仅适用于依赖日志记录模块的所有包。
        【解决方案5】:

        这是从今天(2020 年 1 月 31 日)开始对我有效的唯一解决方案:

        for name in ['boto', 'urllib3', 's3transfer', 'boto3', 'botocore', 'nose']:
            logging.getLogger(name).setLevel(logging.CRITICAL)
        logger = logging.getLogger(__name__)
        

        解决办法

        boto3.set_stream_logger('', logging.CRITICAL)
        

        正在杀死我的整个非 boto 日志。 它从 python 操作标准日志记录的根记录器。

        自己试试吧:

        import logging
        import boto3
        import sys
        logger = logging.getLogger(__name__)
        boto3.set_stream_logger('', logging.CRITICAL)
        logging.basicConfig(level=logging.DEBUG, stream=sys.stdout,
                            format='%(asctime)s - %(levelname)s - %(message)s')
        
        
        if __name__ == '__main__':
            s3_client = boto3.client('s3')
            response = s3_client.list_buckets()
            logger.info(f'bucket list: {response}')
        

        无论logger 的初始化发生在哪里,它都不会显示输出。 去掉boto3.set_stream_logger('', logging.CRITICAL)这一行,非boto3的日志又会重新出现! 因此,唯一可行的解​​决方案是使用boto3.set_stream_logger() 的方法并按照我的建议应用它。

        【讨论】:

          【解决方案6】:

          我将 boto3 答案从 cmets(即 charneykaye 和gene_wood)移至正确答案:

          import logging
          
          logger = logging.getLogger()
          logger.addHandler(logging.StreamHandler()) # Writes to console
          logger.setLevel(logging.DEBUG)
          logging.getLogger('boto3').setLevel(logging.CRITICAL)
          logging.getLogger('botocore').setLevel(logging.CRITICAL)
          logging.getLogger('s3transfer').setLevel(logging.CRITICAL)
          logging.getLogger('urllib3').setLevel(logging.CRITICAL)
          
          import boto3
          
          s3 = boto3.resource('s3')
          
          for bucket in s3.buckets.all():
              print(bucket.name)
          

          要获取所有记录器,请关注response from leobarcellos

          import logging
          loggers_dict = logging.Logger.manager.loggerDict
          

          【讨论】:

          • 我从“boto”看到的大多数日志记录实际上来自 s3transfer,如 @Iony 列表中所述。 (boto 1.9.28 和 s3transfer 0.1.13)。请注意,在 使用了 boto3 之前,s3transfer 不会加载(即在加载 boto3 时不会加载),因此应该在禁用 s3transfer 记录器之前导入 s3transfer
          • 开发应用程序和 botocore 杀死了我想要删除的日志记录。
          【解决方案7】:

          更好的是,为 boto 禁用 propagate

          import boto
          boto.set_file_logger('boto', 'logs/boto.log')
          logging.getLogger('boto').propagate = False
          

          【讨论】:

          • 我不确定这是否是一个新功能,但这应该是当今公认的答案。
          • 我必须使用logging.getLogger("botocore").propagate = False
          • 为什么这个“更好”?
          • 如果我没记错的话(我在 5 多年前写过这个),通过将传播设置为 False 它可以防止它被其他记录器处理。我的示例中的第二行表示“对于 'boto' 记录器,将消息直接发送到 logs/boto.log”,第三行表示“......然后停止,不要将其传递给任何其他日志处理程序”
          【解决方案8】:

          你可以试试

          import logging
          logging.getLogger('boto').setLevel(logging.CRITICAL)
          

          这将抑制所有(除了 CRITICAL)错误。

          Boto 使用日志记录配置文件(例如,/etc/boto.cfg~/.boto),所以看看您是否可以按照自己的需要进行配置。

          set_file_logger 调用只是将用户定义的文件添加到日志记录设置中,因此您不能使用它来关闭日志记录。

          【讨论】:

          • 谢谢。出于某种原因,我无法让 boto 配置文件关闭日志记录。 code.google.com/p/boto/issues/detail?id=476
          • 使用boto3,我不得不logging.getLogger('botocore').setLevel(logging.INFO)
          • 我用过; logging.getLogger('boto3').setLevel(logging.CRITICAL)
          • 正如上面提到的@charneykaye 和@Gerard,因为boto3 实际上是两个不同的模块,boto3botocore,你需要通过两个这样的调用来抑制两者:@987654330 @和logging.getLogger('boto3').setLevel(logging.CRITICAL))
          • @DmitryVerhoturov - 不知道你为什么将 nose 归类为 boto 记录器 - nose 是一个独立项目,恰好用于测试 boto,对吗?跨度>
          猜你喜欢
          • 1970-01-01
          • 2016-09-02
          • 1970-01-01
          • 1970-01-01
          • 2016-09-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多