Python 限制用于日志记录的项目数/json长度
我正在开发一个返回JSON的API。我正在记录我的响应,有时候JSON太长了,基本上会阻塞我的日志文件。有没有一种简单的方法可以减少JSON的长度,仅仅是为了直观地记录数据?(生产中未生效) 基本方法是将长度为5的数组缩减为[first 2,“…”,last 2],将长度超过4项的词典缩减为{first 4,“…:”} 下面的代码很难看。我知道这应该是一个递归解决方案,它以相同的方式减少任意深度JSON的项-目前它只对深度2这样做Python 限制用于日志记录的项目数/json长度,python,json,logging,Python,Json,Logging,我正在开发一个返回JSON的API。我正在记录我的响应,有时候JSON太长了,基本上会阻塞我的日志文件。有没有一种简单的方法可以减少JSON的长度,仅仅是为了直观地记录数据?(生产中未生效) 基本方法是将长度为5的数组缩减为[first 2,“…”,last 2],将长度超过4项的词典缩减为{first 4,“…:”} 下面的代码很难看。我知道这应该是一个递归解决方案,它以相同的方式减少任意深度JSON的项-目前它只对深度2这样做 def log_reducer(response_log): o
def log_reducer(response_log):
original_response_log = response_log
try:
if type(response_log) == dict:
if len(response_log) >= 4: # {123456}
response_log = dict(list(response_log.items())[:4])
response_log.update({"...": "..."}) # {1234...}
for key, value in response_log.items():
if type(value) == list:
if len(value) >= 5: # {key:[123456]}
new_item = value[:2] + ['...'] + value[-2:] # {[12...56]}
response_log.update({key: new_item})
if type(value) == dict:
if len(value) >= 4: # {key:{123456}}
reduced_dict = dict(list(value.items())[:4])
reduced_dict.update({"...": "..."})
response_log.update({key: reduced_dict}) # {{1234...}}
elif type(response_log) == list:
if len(response_log) >= 5: # [123456]
response_log = response_log[:2] + ['...'] + response_log[-2:] # [12...56]
for inner_item in response_log:
if type(inner_item) == list:
if len(inner_item) >= 5: # [[123456]]
reduced_list = inner_item[:2] + ['...'] + inner_item[-2:] # [[12...56]]
response_log.remove(inner_item)
response_log.append(reduced_list)
if type(inner_item) == dict:
if len(inner_item) >= 4: # [{123456}]
reduced_dict = dict(list(inner_item.items())[:4])
reduced_dict.update({"...": "..."}) # [{1234...}]
response_log.remove(inner_item)
response_log.append(reduced_dict)
except Exception as e:
return original_response_log
return response_log
然后使用logger.info(str(response_log))记录返回的响应日志
正如您所看到的,每个级别都可以有数组或字典这一事实使得这项任务更加复杂,我正在努力寻找一个库或任何类型的代码片段,以简化这项任务。如果有人想试一试,我会非常感激
您可以使用这样的测试JSON来查看它的效果:
test_json = {"works": [1, 2, 3, 4, 5, 6],
"not_affected": [{"1": "1", "2": "2", "3": "3", "4": "4", "5": "5"}],
"1": "1", "2": "2", "3": "3",
"removed": "removed"
}
print("original", test_json)
reduced_log = log_reducer(test_json)
print("reduced", reduced_log)
print("original", test_json)
reduced_log = log_reducer([test_json]) # <- increases nesting depth
print("reduced", reduced_log)
test_json={“works”:[1,2,3,4,5,6],
“不受影响”:[{“1”:“1”、“2”:“2”、“3”:“3”、“4”:“4”、“5”:“5”}],
"1": "1", "2": "2", "3": "3",
“已删除”:“已删除”
}
打印(“原件”,test_json)
reduced_log=log_reducer(test_json)
打印(“减少”,减少的日志)
打印(“原件”,test_json)
reduced_log=log_reducer([test_json])#您可以使用def_ustr_u():方法覆盖python中dict和列表的字符串表示形式。使用这个函数只是递归地调用所有元素上的print函数。它可以有这样一个简单的样板:
def custom_print(obj):
log_str = ''
if type(obj) == list:
for item in obj:
log_str += custom_print(item)
elif type(obj) == dict:
for k, item in obj.items():
custom_print(item)
使用此自定义日志函数可以按照日志文件格式打印到日志文件中。您可以使用def\uu str\uu():方法覆盖python中dicts和list的字符串表示形式。使用这个函数只是递归地调用所有元素上的print函数。它可以有这样一个简单的样板:
def custom_print(obj):
log_str = ''
if type(obj) == list:
for item in obj:
log_str += custom_print(item)
elif type(obj) == dict:
for k, item in obj.items():
custom_print(item)
使用此自定义日志功能,按照日志文件格式打印到日志文件中。此答案使用@calceamenta的想法,但实现了实际的缩减逻辑:
def recursive_reduce(obj):
if isinstance(obj, (float, str, int, bool, type(None))):
return obj
if isinstance(obj, dict):
keys = list(sorted(obj))
obj['...'] = '...'
if len(keys) > 5:
new_keys = keys[:2] + ["..."] + keys[-2:]
else:
new_keys = keys
new_dict = {x:obj[x] for x in new_keys}
for k, v in new_dict.items():
new_dict[k] = recursive_reduce(v)
return new_dict
if isinstance(obj, list):
if len(obj) > 5:
new_list = obj[:2] + ["..."] + obj[-2:]
else:
new_list = obj
for i, v in enumerate(new_list):
new_list[i] = recursive_reduce(v)
return new_list
return str(obj)
test_json = {"works": [1, 2, 3, 4, 5, 6],
"not_affected": [{"1": "1", "2": "2", "3": "3", "4": "4", "5": "5"}],
"1": "1", "2": "2", "3": "3",
"removed": "removed"
}
print("original", test_json)
reduced_log = recursive_reduce(test_json)
print("reduced", reduced_log)
输出:
original {'works': [1, 2, 3, 4, 5, 6], 'not_affected': [{'1': '1', '2': '2', '3': '3', '4': '4', '5': '5'}], '1': '1', '2': '2', '3': '3', 'removed': 'removed'}
reduced {'1': '1', '2': '2', '...': '...', 'removed': 'removed', 'works': [1, 2, '...', 5, 6]}
希望这有帮助:)这个答案使用了@calceamenta的想法,但实现了实际的缩减逻辑:
def recursive_reduce(obj):
if isinstance(obj, (float, str, int, bool, type(None))):
return obj
if isinstance(obj, dict):
keys = list(sorted(obj))
obj['...'] = '...'
if len(keys) > 5:
new_keys = keys[:2] + ["..."] + keys[-2:]
else:
new_keys = keys
new_dict = {x:obj[x] for x in new_keys}
for k, v in new_dict.items():
new_dict[k] = recursive_reduce(v)
return new_dict
if isinstance(obj, list):
if len(obj) > 5:
new_list = obj[:2] + ["..."] + obj[-2:]
else:
new_list = obj
for i, v in enumerate(new_list):
new_list[i] = recursive_reduce(v)
return new_list
return str(obj)
test_json = {"works": [1, 2, 3, 4, 5, 6],
"not_affected": [{"1": "1", "2": "2", "3": "3", "4": "4", "5": "5"}],
"1": "1", "2": "2", "3": "3",
"removed": "removed"
}
print("original", test_json)
reduced_log = recursive_reduce(test_json)
print("reduced", reduced_log)
输出:
original {'works': [1, 2, 3, 4, 5, 6], 'not_affected': [{'1': '1', '2': '2', '3': '3', '4': '4', '5': '5'}], '1': '1', '2': '2', '3': '3', 'removed': 'removed'}
reduced {'1': '1', '2': '2', '...': '...', 'removed': 'removed', 'works': [1, 2, '...', 5, 6]}
希望这有帮助:)对不起,我不熟悉这个,函数会调用自定义打印函数吗?或者我会把它放在哪里?我得到了TypeError:只能将str(而不是“NoneType”)连接到str
对不起,我不熟悉这一点,\uuuu str\uuuu函数会调用自定义打印函数吗?或者我会把它放在哪里?我得到了TypeError:只能将str(而不是“NoneType”)连接到str
非常感谢你们两位,这完全符合预期谢谢你们两位,这完全符合预期