diff --git a/Dockerfile b/Dockerfile index d452c54..38cc44c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,8 +28,8 @@ ENV \ PYTHONDONTWRITEBYTECODE=1 \ HOME="/srv/rfam-batch-search" -# create folders -RUN mkdir -p $HOME && mkdir /var/log/gunicorn +# create folder and log file +RUN mkdir -p $HOME && touch /var/log/gunicorn.log # create user RUN useradd -m -d $HOME -s /bin/bash rfam @@ -43,10 +43,10 @@ RUN pip install --no-cache-dir -r requirements.txt # copy project COPY . . -RUN chown -R rfam:rfam /srv && chown -R rfam:rfam /var/log/gunicorn +RUN chown -R rfam:rfam /srv && chown rfam:rfam /var/log/gunicorn.log # set user USER rfam # run the FastAPI app -CMD [ "gunicorn", "-c", "gunicorn/gunicorn_conf.py", "-b", "0.0.0.0:8000", "main:app"] +CMD [ "gunicorn", "-k", "uvicorn.workers.UvicornWorker", "-w", "4", "-b", "0.0.0.0:8000", "--capture-output", "--access-logfile", "-", "--error-logfile", "/var/log/gunicorn.log", "main:app"] diff --git a/main.py b/main.py index bf68ecc..e2e9b5e 100755 --- a/main.py +++ b/main.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 import aiosmtplib import asyncio +import logging import os import typing as ty +import uvicorn from dotenv import load_dotenv from email.mime.multipart import MIMEMultipart @@ -18,7 +20,7 @@ ) from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import PlainTextResponse -import uvicorn +from logging.handlers import RotatingFileHandler from rfam_batch import job_dispatcher as jd from rfam_batch import api @@ -45,6 +47,25 @@ # Load environment variables from .env file load_dotenv() +# Configure logging +log_formatter = logging.Formatter("%(asctime)s %(levelname)s %(module)s: %(message)s") +root_logger = logging.getLogger() + +# Log to stdout +stdout_handler = logging.StreamHandler() +stdout_handler.setFormatter(log_formatter) +root_logger.addHandler(stdout_handler) + +# Log to file +file_handler = RotatingFileHandler( + filename="/var/log/gunicorn.log", maxBytes=1000000, backupCount=5 +) +file_handler.setFormatter(log_formatter) +root_logger.addHandler(file_handler) + +# Set log level +root_logger.setLevel(logging.INFO) + @app.on_event("shutdown") async def on_shutdown() -> None: