Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 限制用于日志记录的项目数/json长度_Python_Json_Logging - Fatal编程技术网

Python 限制用于日志记录的项目数/json长度

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

我正在开发一个返回JSON的API。我正在记录我的响应,有时候JSON太长了,基本上会阻塞我的日志文件。有没有一种简单的方法可以减少JSON的长度,仅仅是为了直观地记录数据?(生产中未生效)

基本方法是将长度为5的数组缩减为[first 2,“…”,last 2],将长度超过4项的词典缩减为{first 4,“…:”}

下面的代码很难看。我知道这应该是一个递归解决方案,它以相同的方式减少任意深度JSON的项-目前它只对深度2这样做

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
非常感谢你们两位,这完全符合预期谢谢你们两位,这完全符合预期