【问题标题】:Python argparse errors to filePython argparse 错误文件
【发布时间】:2018-02-06 00:51:32
【问题描述】:

我正在尝试制作一个脚本,将所有错误记录到日志文件中。我想在这个文件中包含任何argparse 错误。我已经使用logging 包和sys.excepthook 来驱动日志文件的意外异常。

这是一个示例代码:

import argparse
import logging
import sys
import traceback

def log_uncaught_exceptions(ex_cls, ex, tb):
    logging.critical(''.join(traceback.format_tb(tb)))
    logging.critical('{0}: {1}'.format(ex_cls, ex))

logging.basicConfig(
    level=logging.DEBUG,
    filename='foo.log',
    filemode='w',
    format='%(asctime)s - %(levelname)s - %(message)s')

sys.excepthook = log_uncaught_exceptions

logging.debug('This is a typical debug line')

parser = argparse.ArgumentParser(description='Foo String')
parser.add_argument('foo',type=int)
args = parser.parse_args()
logging.debug('Input was %i'%(args.foo))

当我使用python logger_argparse.py 1 运行它时,一切正常。如果我运行python logger_argparse.py a,我会在控制台中得到输出,而不是日志文件:

usage: logger_argparse.py [-h] foo
logger_argparse.py: error: argument foo: invalid int value: 'a'

如何将这些信息写入日志文件?

【问题讨论】:

  • 它不起作用,因为logger_argparse.py: error: argument foo: invalid int value: 'a' 不是引发的异常,它只是来自argparse 的打印输出。
  • 有什么好的方法可以中断打印以使其进入文件吗?
  • argparse.py 文件中,查看errorexit 之类的方法(文档中也提到了它们)。大多数解析错误引发ArgumentError,然后被这些捕获,一条消息打印到stderr,然后它调用sys.exit
  • 在 [argparse] [logging] 上搜索时发现:stackoverflow.com/questions/29935283/…

标签: python logging argparse


【解决方案1】:

你可以在异常处理程序中使用logging.exception 吗? 编辑:那么从ArgumentParser.error() 登录怎么样?

import sys
import logging
import argparse

class argparse_logger(argparse.ArgumentParser):
    def error(self, message):
        logging.error(message)
        super().error(message)

logging.basicConfig(
    level=logging.DEBUG,
    filename='foo.log',
    filemode='w',
    format='%(asctime)s - %(levelname)s - %(message)s')

# parser = argparse.ArgumentParser(description="Foo")
parser = argparse_logger(description="Foo")
parser.add_argument('foo',type=int)
logging.debug("Start")

try:
    args = parser.parse_args(sys.argv[1:])
except:
    print("Error handling arguments")
    raise
logging.debug(f"Finish - {args.foo}")
print(f"Exiting! - {args.foo}")

这将显示以下内容:

J:\>python arg_parse_log.py 5
Exiting! - 5

J:\>more foo.log
2018-02-07 11:34:45,647 - DEBUG - Start
2018-02-07 11:34:45,648 - DEBUG - Finish - 5

J:\>python arg_parse_log.py
usage: arg_parse_log.py [-h] foo
arg_parse_log.py: error: the following arguments are required: foo
Error handling arguments

J:\>more foo.log
2018-02-07 11:34:54,577 - DEBUG - Start
2018-02-07 11:34:54,578 - ERROR - the following arguments are required: foo

【讨论】:

  • 是的...但我想捕获 argparse 打印错误以记录输入或遗漏的内容。错误只是说明出了点问题……控制台输出告诉我出了什么问题。
  • 感谢您的澄清,我已经更新了代码。
【解决方案2】:

我发现了一个我认为不是很好的解决方法。但它似乎正在工作:

import argparse
import logging
import sys
import traceback

class argparse_logger(argparse.ArgumentParser):
    def _print_message(self, message, file=None):
        if file is sys.stderr:
            logger.error('Arg Parse did something bad...see below:')
            logger.error(message)
        else:
            super()._print_message(message,file=file)

def log_uncaught_exceptions(ex_cls, ex, tb):
    logging.critical(''.join(traceback.format_tb(tb)))
    logging.critical('{0}: {1}'.format(ex_cls, ex))

logging.basicConfig(
    level=logging.DEBUG,
    filename='foo.log',
    filemode='w',
    format='%(asctime)s - %(levelname)s - %(message)s')

# logging.getLogger('root')
logger = logging.getLogger('root')

sys.excepthook = log_uncaught_exceptions

logger.debug('This is a typical debug line')

parser = argparse_logger(description='Foo String')
parser.add_argument('foo',type=int)
args = parser.parse_args()
logger.debug('Input was %i'%(args.foo))

【讨论】:

  • 我会修改parser.error。但由于它所写的所有内容都通过_print_message,因此您的方法同样出色。
猜你喜欢
  • 1970-01-01
  • 2013-10-05
  • 2014-06-03
  • 2014-11-03
  • 1970-01-01
  • 2013-06-06
  • 2017-08-20
  • 2018-07-21
  • 1970-01-01
相关资源
最近更新 更多