python - 使用 python 记录为 JSON 行
问题描述
我开发了一个函数来使用 python 创建日志文件到 JSON 行文件中:
import logging
import sys
from datetime import datetime
def log_start(log_prefix):
now = datetime.now()
log_id = str(now).replace(':', '').replace(' ', '').replace('.', '').replace('-', '')[:14]
log_name = '/mnt/jarvis/logs/{}_{}.txt'.format(log_prefix, log_id)
root = logging.getLogger()
if root.handlers:
root.handlers = []
logging.basicConfig(level=logging.INFO, filename=log_name, filemode='a+',
format='''{{"log_id":"{}", "created_date":"%(asctime)s.%(msecs)03d", "action_text":"%(message)s"}}'''.format(
log_id),
datefmt="%Y-%m-%dT%H:%M:%S")
root = logging.getLogger()
root.setLevel(logging.INFO)
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.INFO)
formatter = logging.Formatter(
'''{{"log_id":"{}", "created_date":"%(asctime)s.%(msecs)03d", "action_text":"%(message)s"}}'''.format(
log_id),
datefmt="%Y-%m-%dT%H:%M:%S")
handler.setFormatter(formatter)
root.addHandler(handler)
return log_name, log_id
它工作得很好。但是,如果日志消息中有换行符或双引号之类的消息,我会遇到问题,它不再是有效的 JSON。有没有办法让%(message)
be 字符串成为“有效的 JSON 字符串”,而无需我每次都对其进行更正?
编辑
这个问题的一个例子是,我想在日志中查看回溯,所以像这样的回溯会因为引号和 \n 字符而导致问题:
Traceback (most recent call last):
File "/var/task/lego/bricks/tableau/workbook.py", line 65, in refresh_extracts
output = subprocess.check_output(command, shell=True)
File "/var/lang/lib/python3.6/subprocess.py", line 356, in check_output
**kwargs).stdout
File "/var/lang/lib/python3.6/subprocess.py", line 438, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '***REDACTED***' returned non-zero exit status 1.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/task/jarvis/event_triggered/refresh_dashboard.py", line 21, in refresh_dashboard
workbook.refresh_extracts()
File "/var/task/lego/bricks/tableau/workbook.py", line 73, in refresh_extracts
traceback.format_exc()))
File "/var/task/lego/power_functions/error_handling/graceful_fail.py", line 16, in graceful_fail
raise RuntimeError('This is a graceful fail, notifications sent based on attributes.')
RuntimeError: This is a graceful fail, notifications sent based on attributes.
解决方案
您可以根据需要有条件地测试和格式化您的字符串到/来自 JSON。在这里,我正在检查JSONDecodeError
在这种情况下经常抛出的具体情况,但您可以捕获任何您喜欢的异常,或者其中的许多异常。考虑使用这样的检查来构建您的消息字符串:
import json
bad_json = '''
Traceback (most recent call last):
File "/var/task/lego/bricks/tableau/workbook.py", line 65, in refresh_extracts
output = subprocess.check_output(command, shell=True)
File "/var/lang/lib/python3.6/subprocess.py", line 356, in check_output
**kwargs).stdout
File "/var/lang/lib/python3.6/subprocess.py", line 438, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '***REDACTED***' returned non-zero exit status 1.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/task/jarvis/event_triggered/refresh_dashboard.py", line 21, in refresh_dashboard
workbook.refresh_extracts()
File "/var/task/lego/bricks/tableau/workbook.py", line 73, in refresh_extracts
traceback.format_exc()))
File "/var/task/lego/power_functions/error_handling/graceful_fail.py", line 16, in graceful_fail
raise RuntimeError('This is a graceful fail, notifications sent based on attributes.')
RuntimeError: This is a graceful fail, notifications sent based on attributes.
'''
try:
test_message = json.loads(bad_json) # this fails in the above case
except json.decoder.JSONDecodeError:
good_json = json.dumps({"message": bad_json})
test_message = json.loads(good_json)
print(test_message)
json.dumps(your_message_string)
结果(如果您愿意,可以将其转储为更具可读性的文本):
{'message': '\nTraceback (most recent call last):\n File "/var/task/lego/bricks/tableau/workbook.py", line 65, in refresh_extracts\n output = subprocess.check_output(command, shell=True)\n File "/var/lang/lib/python3.6/subprocess.py", line 356, in check_output\n **kwargs).stdout\n File "/var/lang/lib/python3.6/subprocess.py", line 438, in run\n output=stdout, stderr=stderr)\nsubprocess.CalledProcessError: Command \'***REDACTED***\' returned non-zero exit status 1.\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File "/var/task/jarvis/event_triggered/refresh_dashboard.py", line 21, in refresh_dashboard\n workbook.refresh_extracts()\n File "/var/task/lego/bricks/tableau/workbook.py", line 73, in refresh_extracts\n traceback.format_exc()))\n File "/var/task/lego/power_functions/error_handling/graceful_fail.py", line 16, in graceful_fail\n raise RuntimeError(\'This is a graceful fail, notifications sent based on attributes.\')\nRuntimeError: This is a graceful fail, notifications sent based on attributes.\n'}
这可能是您通过日志格式化程序传递的函数、lambda 等。
推荐阅读
- java - 如何使用 Spring Integration 中的 File Watcher 仅用于等待,而不用于移动?
- java - 我的排序方法没有正确排序字符串(Java)
- python - 使用 lxml 和 xmlfile 从 python 创建漂亮打印的增量生成的 XML
- python - Python:如何为一个键存储多个值
- elasticsearch - 使用脚本的弹性 NEST SumAggregation
- javascript - 子行数据表
- android - 一次在android studio中将多个svgs转换为xml
- javascript - 有没有在 wagtail-admin 中打开模式窗口的正确方法?
- python - 如何将 anaconda 添加到 PATH?
- c# - 我将如何模拟 UserPrincipal?