Fastapi: Unable to overwrite gunicorn logging with python logging with FastAPI app hosted on docker

Created on 20 Aug 2020  路  4Comments  路  Source: tiangolo/fastapi

I have a fastapi app on which I want to add python logging. I followed the basic tutorial and added this, however this doesn't add API Endpoints logging but just guvicorn HTTP logging.
So I have a local server hosted using docker build so running server using docker-compose up and testing my endpoints using api client (Insomnia, similar to postman).

Also, I am using gunicorn.conf that looks like this:

[program:gunicorn]
command=poetry run gunicorn -c /etc/gunicorn/gunicorn.conf.py foodgame_api.main:app
directory=/var/www/
autostart=true
autorestart=true
redirect_stderr=true

And gunicorn.conf.py as

import multiprocessing
bind = "unix:/tmp/gunicorn.sock"
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = "uvicorn.workers.UvicornWorker"
loglevel = "debug"
errorlog = "-"
capture_output = True
chdir = "/var/www"
reload = True
reload_engine = "auto"

Below is the code where no HELLO is printed.

My project str is as follows:

project/
  docker/
      rootfilesystem/
         etc/
            gunicorn/
                gunicorn.conf.py
             supervisor/
                available.d/
                   gunicorn.conf
         entrypoint.sh
      ecs/
            ...
  src/ 
    api/
      models/ 
        users.py
      routers/
        users.py
      main.py
      logging.conf
"""
main.py Main is the starting point for the app.
"""

import logging.config
from fastapi import FastAPI
from msgpack_asgi import MessagePackMiddleware
import uvicorn

from api.routers import users


logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

app = FastAPI(debug=True)
app.include_router(users.router)


@app.get("/check")
async def check():
    """Simple health check endpoint."""
    logger.info("HELLO")
    return {"success": True}


app = MessagePackMiddleware(app)

This is the output screenshot:
Screen Shot 2020-08-20 at 9 30 19 AM

Could anyone please guide me here? I am new to FastApi so some help will be appreciated.

answered question

Most helpful comment

This is because, by default, the logging module logs the messages with a severity level of WARNING or above.
With your example if you did logger.error("bla") it would print out to console.

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

logger.info('yeye')
logger.error('yoyo')
test_1          | 2020-08-20 07:54:24 INFO info:6 yeye
test_1          | 2020-08-20 07:54:24 ERROR info:7 yoyo

All 4 comments

This is because, by default, the logging module logs the messages with a severity level of WARNING or above.
With your example if you did logger.error("bla") it would print out to console.

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

logger.info('yeye')
logger.error('yoyo')
test_1          | 2020-08-20 07:54:24 INFO info:6 yeye
test_1          | 2020-08-20 07:54:24 ERROR info:7 yoyo

@ArcLightSlavik I tried above but nothing prints on terminal. Is there a way to output in file, if not on docker console?

PFA the screenshot of my run:
Screen Shot 2020-08-20 at 9 30 19 AM

Here is my updated code:

"""
Main is the starting point for the app.
"""

import logging.config
from fastapi import FastAPI

import uvicorn

from api.routers import users


logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.info("Starting server")

app = FastAPI(debug=True)
app.include_router(users.router)


@app.get("/check")
async def check():
    """Simple health check endpoint."""
    logger.debug("logging from the root logger")
    return {"success": True}

app = FastAPI()

logging.basicConfig(level=logging.INFO)
name_logger = logging.getLogger(__name__)
name_logger.setLevel(logging.INFO)


@app.get("/")
def hello():
    name_logger.info('yo')
    name_logger.error('ye')
    return "Hello Cherry World!"
cherry_1  | INFO:cherry.main:yo
cherry_1  | ERROR:cherry.main:ye



md5-276a0c30a9dd9114a0356c04adf615b0



import logging


def create_logger():
    logging.basicConfig(level=logging.INFO)
    name_logger = logging.getLogger(__name__)
    name_logger.setLevel(logging.INFO)
    return name_logger


logger = create_logger()

debug = logger.debug
info = logger.info
warning = logger.warning
error = logger.error
critical = logger.critical
exception = logger.exception



md5-9547164ab339f65f040d26b1232b2d20



from fastapi import FastAPI

from .custom_logger import info, error

app = FastAPI()


@app.get("/")
def hello():
    info('yo')
    error('ye')
    return "Hello Cherry World!"



md5-52380ffed3822c39b98a2100ff0555a5



cherry_1  | INFO:cherry.custom_logger:yo
cherry_1  | ERROR:cherry.custom_logger:ye

It prints the wrong file, but i will leave that to you 馃槢

Thanks for the help here @ArcLightSlavik ! :clap: :bow:

If that solves the original problem, then you can close this issue @AkshitaGupta :heavy_check_mark:

Was this page helpful?
0 / 5 - 0 ratings