Python - 使用正确的缩进记录字典以进行控制台
Python - Log dictionary to console with correct indentation
下面是对帮助我走到这一步的问题的引用:
- how to indent multiline message printed by python logger?
- Log all requests from the python-requests module
我目前有这个:
# 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"}
下面是对帮助我走到这一步的问题的引用:
- how to indent multiline message printed by python logger?
- Log all requests from the python-requests module
我目前有这个:
# 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"}