dockerfastapiuvicorn

Docker log stores only log error with uvicorn fastAPI


I have the fastAPI application wrapped inside the docker but now having problem with the logging. Below is how I setup the log file.

logger.py

import logging
from fastapi.logger import logger

gunicorn_logger = logging.getLogger('gunicorn.error')
logger.handlers = gunicorn_logger.handlers
logger.setLevel(logging.DEBUG)

def get_logger(name):
    return logger

Dockerfile

FROM python:3.11-slim

ENV REGISTRY_LOG_LEVEL=debug

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 80

CMD ["python3.11", "-m", "uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"]

Here is a minimal test code for the logging


app = FastAPI()
log = get_logger(__file__)

@app.get("/api/v1/log")
async def run_log():
    log.info("Info log")
    log.error("Failed")

When I call the log api endpoint, and check with the log file inside the docker, it captures only the log.error() item which is the "Failed" statement in this case. It captures also the stdout/stderr from uvicorn which contains the api endpoint calling and HTTP status but log.info statement.


Solution

  • Eventually I still have no idea why, but looks like the docker doesn't capture the log.info (stdout) by default in my case.

    So the approach was to just add stdout stream handler to the logger hence docker will capture the statement from log.info().

    Updated code snippet:

    import logging
    import sys
    from fastapi.logger import logger
        
    # gunicorn logging settings
    gunicorn_logger = logging.getLogger('gunicorn.error')
    logger.handlers = gunicorn_logger.handlers
    logger.setLevel(logging.DEBUG)
        
    # create custom handler for INFO msg
    stdout_handler = logging.StreamHandler(sys.stdout)
    stdout_handler.setLevel(logging.DEBUG)
        
    logger.addHandler(stdout_handler)
        
    def get_logger(name):
        return logger