Below references to questions that have helped me get this far:
- How to print out a dictionary nicely in Python?
- how to indent multiline message printed by python logger?
- Python requests - print entire http request (raw)?
- Log all requests from the python-requests module
I currently have this:
# 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)
At the moment, it's pretty much on par for what I'm trying to achieve, however, I'm just trying to get the output of the response bodies a little more "nice".
In the last line above logger.info(msg_print) I get this output:
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
                                                                    }
But I'd really like to get those dictionaries to be like this:
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}
Edit:
Sample dict with nested values:
{
    "level1": {
        "myInt": "Original",
        "level2": {
            "myInt": "Original",
            "myBool": "Original",
            "level3": {
                "myBool": "Original"
            }
        }
    },
    "level4": [
        {
            "myList": "Original"
        },
        {
            "myList": "Original"
        }
        ,
        {
            "myList": "Original"
        }
    ]
}
 
    