Python作为字典或JSON登录到文件中
我正在尝试设置日志记录,在那里我可以同时登录标准输出和文件。我已使用以下代码完成了此操作:Python作为字典或JSON登录到文件中,python,logging,Python,Logging,我正在尝试设置日志记录,在那里我可以同时登录标准输出和文件。我已使用以下代码完成了此操作: logging.basicConfig( level=logging.DEBUG, format='%(asctime)-15s %(levelname)-8s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', handlers=[logging.FileHandler(path), logging.StreamHandler()
logging.basicConfig(
level=logging.DEBUG, format='%(asctime)-15s %(levelname)-8s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S', handlers=[logging.FileHandler(path), logging.StreamHandler()])
这个函数的输出如下所示:
2018-05-02 18:43:33,295 DEBUG Starting new HTTPS connection (1): google.com
2018-05-02 18:43:33,385 DEBUG https://google.com:443 "GET / HTTP/1.1" 301 220
2018-05-02 18:43:33,389 DEBUG Starting new HTTPS connection (1): www.google.com
2018-05-02 18:43:33,490 DEBUG https://www.google.com:443 "GET / HTTP/1.1" 200 None
我试图完成的是将此输出记录到一个文件中,而不是作为打印到标准输出,而是作为类似于这样的字典或JSON对象(同时保持标准输出目前的状态):
[{'time':'2018-05-02 18:43:33295','level':'DEBUG','message':'Starting new HTTPS connection(1):google.com'},{…},{…}]
这可行吗?我知道我可以在我的过程完成后对这个日志文件进行后期处理,但我正在寻找一个更优雅的解决方案,因为我正在记录的某些东西本身就是相当大的对象 因此,基于@abarnert,我发现这提供了一条很好的途径,使这个概念在大部分情况下都能发挥作用。目前的准则是:
logger=logging.getLogger()
logger.setLevel(logging.DEBUG)
file_handler=logging.FileHandler('foo.log')
stream_handler=logging.StreamHandler()
stream_formatter=logging.Formatter(
'%(asctime)-15s %(levelname)-8s %(message)s')
file_formatter=logging.Formatter(
"{'time':'%(asctime)s', 'name': '%(name)s', \
'level': '%(levelname)s', 'message': '%(message)s'}"
)
file_handler.setFormatter(file_formatter)
stream_handler.setFormatter(stream_formatter)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
虽然它不完全满足要求,但它不需要任何预处理,并允许我创建两个日志处理程序
之后,我可以使用以下内容:
with open('foo.log') as f:
logs = f.read().splitlines()
for l in logs:
for key, value in eval(l):
do something ...
拉取dict
对象,而不是使用格式不正确的JSON来完成我的目标
我仍然希望有一个更优雅的解决方案 通过这段代码,您可以将完整的回溯、时间戳和级别添加到所选的json文件中
导入json
导入回溯
从日期时间导入日期时间
def添加日志记录(logDict:dict):
loggingsFile='loggings.json'
打开(日志文件)作为f:
data=json.load(f)
data.append(logDict)
打开(日志文件“w”)作为f:
json.dump(数据,f)
def currentTimeUTC():
return datetime.now().strftime(“%d/%m/%Y%H:%m:%S”)
尝试:
打印(5/0)
除零误差外:
fullTraceback=str(traceback.format_exc())
addLogging({'timestamp':currentTimeUTC(),'level':'error','traceback':fullTraceback})
输出:
[
{
"timestamp": "09/06/2020 17:38:00",
"level": "error",
"traceback": "Traceback (most recent call last):\n File \"d:testFullTraceback.py\", line 19, in <module>\n print(5/0)\nZeroDivisionError: division by zero\n"
}
]
[
{
“时间戳”:“09/06/2020 17:38:00”,
“级别”:“错误”,
“回溯”:“回溯(最近一次调用):\n文件\“d:testFullTraceback.py\”,第19行,打印(5/0)\n错误:除零\n”
}
]
我考虑过@Sphinx,但这不起作用,因为它将以json模式打印到stdout。您要做的是创建一个自定义的格式化程序,它接受日志记录,并对其进行json编码(当然可能先对其进行预处理)。然后创建一个使用默认格式化程序的标准输出处理程序和一个使用自定义格式化程序的文件处理程序。这并不是很简单,但是应该让您开始,并且有一些相关的ish示例代码。我不知道哪些是好的,或者每个都有哪些功能,但是如果有一个可以通过一点小配置而不是编写一堆代码来实现您想要的功能,我也不会感到惊讶。最后一件事:您不能只是“将JSON写入文件”。可以(只要顶级文本始终是对象或数组),但大多数JSON解析代码不会在单个文件中处理任意JSON文本流。您希望使用类似或两种几乎相同的格式中的一种,这稍微限制了JSON编码中允许的内容,因此您可以保证文本文件的每一行上都有一个JSON文本。@abarnert我现在正在探索烹饪书的高级部分。看来这是可行的。大概我不确定它将如何处理我已经记录的一个大的JSON对象,但这里尝试一下。谢谢不幸的是,输出数据不是有效的json数据json.load(“{'time':'2020-11-04 15:42:30193','name':'Jack\'s'))
小心点。如果消息只有一个引号,您的解决方案将中断。