1

I am using logtail.com and for some reason it wont log ONLY in my FastAPI/UVICORN app, I tried using the package in an a different test python file and it worked? I dont understand what I am missing. I call the logger and it should work but it does not, additionally I even do a log INSTANTLY after I instantiate the logger and it does not work. Code below.

#
# Logger.py
#

from logtail import LogtailHandler
import logging

class Logger:
    def __init__(self):
        handler = LogtailHandler(source_token="XXXXXXX")
        logger = logging.getLogger(__name__)
        logger.handlers = []
        logger.setLevel(logging.DEBUG) # Set minimal log level
        logger.addHandler(handler) # asign handler to logger
        logger.debug('I am using Logtail!')

    def info(self, message):
        self.log.info(message)
        
    def error(self, message):
        self.log.error(message)
    
    def debug(self, message):
        self.log.debug(message)
        
    def warning(self, message):
        self.log.warning(message)
        
    def critical(self, message):
        self.log.critical(message)
        
    def exception(self, message):
        self.log.exception(message)
#
# __init__ 
#

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from abe.routes import main, bc_handler

app = FastAPI(title="ABE-Backend", openapi_url="/openapi.json")
app.include_router(main.router)
app.include_router(bc_handler.router)

from abe.utils.logger import Logger

logger = Logger()

#create tables
# models.Base.metadata.create_all(bind=engine)

origins = [
    
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

if __name__ == "__main__":
    # Use this for debugging purposes only
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000, log_level="debug")
    logger.info("Starting server on port 8000, with cors origins: "+str(origins))
vvvvv
  • 25,404
  • 19
  • 49
  • 81
Oze
  • 61
  • 8
  • Does this answer your question? [How do I get my FastAPI application's console log in JSON format with a different structure and different fields?](https://stackoverflow.com/questions/70891687/how-do-i-get-my-fastapi-applications-console-log-in-json-format-with-a-differen) – Chris Nov 28 '22 at 19:04

2 Answers2

1

It should work, but only after you shutdown the API.

Logging inside the main function before calling uvicorn.run() and inside endpoint routes should work as you expected.

uvicorn.run() is a sync function. So the interpreter waits until the function has finished (API has shutdown) and executes the following statements afterwards.

Admin
  • 91
  • 5
  • I tried this but it did not work? Also do you mean to say that anything that is "logged" after I call run wont log until after I call shutdown? – Oze Nov 30 '22 at 03:50
  • What did you try exactly? Yes, anything within the main function that is called after run() is logged only after you shut down the service, . Anything logged within the run operation (e. g. logging within routes) should appear in the console. – Admin Nov 30 '22 at 10:24
0

I've found the problem and kinda fixed it. Will see how it will behave in the long term.

If you see the source code of handler.py of Logtail there is this part:


    def _is_main_process(self):
        return multiprocessing.current_process()._parent_pid == None

    def emit(self, record):
        try:
            if self._is_main_process() and not self.flush_thread.is_alive():
                self.flush_thread.start()
            message = self.format(record)

The problem is that self._is_main_process() is always False

I monkey patched it the following way and now I receive the logs:

handler = LogtailHandler(source_token=LOGTAIL_TOKEN)
handler._is_main_process = lambda: True