json-logging-python icon indicating copy to clipboard operation
json-logging-python copied to clipboard

Logging error in FastAPI implementation

Open gclements-chwy opened this issue 3 years ago • 2 comments

I am running into an issue with the logger implementation throwing the following error:

--- Logging error ---
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/logging/__init__.py", line 1083, in emit
    msg = self.format(record)
  File "/usr/local/lib/python3.9/logging/__init__.py", line 927, in format
    return fmt.format(record)
  File "/usr/local/lib/python3.9/site-packages/json_logging/__init__.py", line 243, in format
    log_object = self._format_log_object(record, request_util=_request_util)
  File "/app/./vet_onboarding_lambda/main.py", line 32, in _format_log_object
    json_log_object = super(JSONRequestLogFormatter, self)._format_log_object(record, request_util)
  File "/usr/local/lib/python3.9/site-packages/json_logging/__init__.py", line 276, in _format_log_object
    "remote_ip": request_adapter.get_remote_ip(request),
  File "/usr/local/lib/python3.9/site-packages/json_logging/framework/fastapi/implementation.py", line 108, in get_remote_ip
    return request.client.host
AttributeError: 'NoneType' object has no attribute 'host'

I'm using json-logging 1.3.0 and fastapi 0.80.0 (which uses Starlette 0.19.1) If you look in the source for Starlette it says that the property client on request can be None The getters in fastapi/implementation.py that use request.client need to make sure that client isn't None before using it.

Oh, I forgot to mention that my application is running in a Docker container.

gclements-chwy avatar Aug 26 '22 13:08 gclements-chwy

In case anyone else runs into this issue there is a work around. You do have to poke around in json-logging internals.

from json_logging import _framework_support_map
from json_logging.framework.fastapi import FastAPIRequestAdapter

class MyFastAPIRequestAdapter(FastAPIRequestAdapter):
    def get_remote_ip(self, request: starlette.requests.Request):
        if request.client:
            return request.client.host
        return '-'

    def get_remote_port(self, request: starlette.requests.Request):
        if request.client:
            return request.client.port
        return '-'

_framework_support_map['fastapi']['request_adapter_class'] = MyFastAPIRequestAdapter

json_logging.init_fastapi(enable_json=True)

gclements-chwy avatar Aug 26 '22 13:08 gclements-chwy

PR welcome to patch fastapi adapter

bobbui avatar Oct 04 '22 22:10 bobbui