Python - 使用正确的缩进记录字典以进行控制台

Python - Log dictionary to console with correct indentation

下面是对帮助我走到这一步的问题的引用:

我目前有这个:

# got from second reference link
class MultiLineFormatter(logging.Formatter):

    def get_header_length(self, record):
        # Get the header length of a given record
        return len(super().format(logging.LogRecord(name=record.name,
                                                    level=record.levelno,
                                                    pathname=record.pathname,
                                                    lineno=record.lineno,
                                                    msg='',
                                                    args=(),
                                                    exc_info=None)))

    def format(self, record):
        # Format a record with added indentation
        indent = ' ' * self.get_header_length(record)
        head, *trailing = super().format(record).splitlines(True)

        # return
        return head + ''.join(indent + line for line in trailing)



def report_logger(log_level: logging.INFO):
    # set format for logging style
    formatter = MultiLineFormatter(fmt='%(asctime)-8s - %(levelname)-8s - %(name)-30s  : %(message)s',
                                   datefmt='%y/%b/%Y %H:%M:%S', )

    # create console logger
    console = logging.StreamHandler()
    console.setLevel(log_level)

    # apply formatter to console logger
    console.setFormatter(formatter)

    # request logger
    final_logger = logging.getLogger(__name__)
    final_logger.setLevel(log_level)

    # prevent double logs in console
    final_logger.propagate = False

    # add handler
    final_logger.addHandler(console)

    # return
    return final_logger

def print_request(request_data):
    format_headers = lambda d: '\n                '.join(f'{k}: {v}' for k, v in d.items())

    request_body = json.dumps(request_data.req_body, indent=20, sort_keys=True, default=str)
    response_text = json.dumps(request_data.resp_text, indent=20, sort_keys=True, default=str)
    response_body = json.dumps(request_data.resp_as_dict, indent=20, sort_keys=True, default=str)

    msg_print = f'---------------- Request ----------------\n' \
                f'Headers     :   {format_headers(request_data.req_headers)}\n' \
                f'URL         :   {request_data.req_url}\n' \
                f'Method      :   {request_data.req_method}\n' \
                f'Body        :   {request_body}\n' \
                f'\n' \
                f'---------------- Response ----------------\n' \
                f'Headers     :   {format_headers(request_data.resp_headers)}\n' \
                f'Status Code :   {request_data.resp_status_code}\n' \
                f'Text        :   {response_text}\n' \
                f'Response    :   {response_body}\n'

    logger.info(msg_print)

目前,它与我想要实现的目标差不多,但是,我只是想让响应主体的输出更“好”一点。

在上面的最后一行 logger.info(msg_print) 我得到了这个输出:

22/Feb/2022 16:11:09 - INFO     - logger_function                 : ---------------- Request ----------------
                                                                    Headers     :   User-Agent: python-requests/2.25.1
                                                                                    Accept-Encoding: gzip, deflate
                                                                                    Accept: */*
                                                                                    Connection: keep-alive
                                                                                    authorization: AuthToken
                                                                    URL         :   my_url
                                                                    Method      :   GET
                                                                    Body        :   null
                                                                    
                                                                    ---------------- Response ----------------
                                                                    Headers     :   content-type: application/json
                                                                                    Content-Length: 119
                                                                                    x-envoy-upstream-service-time: 187
                                                                                    date: today
                                                                                    server: server
                                                                                    Via: 1.1 service
                                                                                    Alt-Svc: alt_service
                                                                    Status Code :   401
                                                                    Text        :   {
                                                                                        "code": 111111,
                                                                                        "component": "ABC",
                                                                                        "errorType": "DEF",
                                                                                        "message": "",
                                                                                        "traceId": UUID4
                                                                    }
                                                                    Response    :   {
                                                                                        "code": 111111,
                                                                                        "component": "ABC",
                                                                                        "errorType": "DEF",
                                                                                        "message": "",
                                                                                        "traceId": UUID4
                                                                    }

但我真的很想让那些词典变成这样:

22/Feb/2022 16:11:09 - INFO     - logger_function                 : ---------------- Response ----------------
                                                                    Text        :   {"code": 111111,
                                                                                     "component": "ABC",
                                                                                     "errorType": "DEF",
                                                                                     "message": "",
                                                                                     "traceId": UUID4}
                                                                    Response    :   {"code": 111111,
                                                                                     "component": "ABC",
                                                                                     "errorType": "DEF",
                                                                                     "message": "",
                                                                                     "traceId": UUID4}

编辑:

具有嵌套值的示例 dict

{
    "level1": {
        "myInt": "Original",
        "level2": {
            "myInt": "Original",
            "myBool": "Original",
            "level3": {
                "myBool": "Original"
            }
        }
    },
    "level4": [
        {
            "myList": "Original"
        },
        {
            "myList": "Original"
        }
        ,
        {
            "myList": "Original"
        }
    ]
}

虽然它看起来有点脆弱,但看起来您可以稍微调整缩进,然后使用 re 包去除前导和右花括号之间不需要的间距。

import json
import re

req_body = {"code": 111111, "component": "ABC", "errorType": "DEF", "message": "", "traceId": "UUID4"}
resp_text = {"code": 111111, "component": "ABC", "errorType": "DEF", "message": "", "traceId": "UUID4"}

request_body = json.dumps(req_body, indent=20, sort_keys=True, default=str)

response_text = json.dumps(resp_text, indent=17, sort_keys=True, default=str)
response_text = re.sub(r"^{\s*", "{", response_text)
response_text = re.sub(r"\s*}$", "}", response_text)

msg_print = f'---------------- Response ----------------\n' \
            f'Request     :   {request_body}\n' \
            f'Response    :   {response_text}\n'

print(msg_print)

看起来它可能会满足您的需求:

---------------- Response ----------------
Request     :   {
                    "code": 111111,
                    "component": "ABC",
                    "errorType": "DEF",
                    "message": "",
                    "traceId": "UUID4"
}
Response    :   {"code": 111111,
                 "component": "ABC",
                 "errorType": "DEF",
                 "message": "",
                 "traceId": "UUID4"}