From 906cccd3fe920c9980ef475db2adcc795af9887e Mon Sep 17 00:00:00 2001 From: Anahita-Mahmoudi Date: Sun, 24 May 2026 09:55:56 +0330 Subject: [PATCH] feat :add log --- backend/.env | 5 +- backend/api/admin.py | 36 ++++++++++--- backend/api/user.py | 48 ++++++----------- backend/core/__init__.py | 0 .../core/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 135 bytes .../core/__pycache__/logger.cpython-313.pyc | Bin 0 -> 2548 bytes backend/core/logger.py | 50 ++++++++++++++++++ backend/logs/app.log | 1 + backend/logs/error.log | 0 backend/wheel.db | Bin 20480 -> 20480 bytes 10 files changed, 98 insertions(+), 42 deletions(-) create mode 100644 backend/core/__init__.py create mode 100644 backend/core/__pycache__/__init__.cpython-313.pyc create mode 100644 backend/core/__pycache__/logger.cpython-313.pyc create mode 100644 backend/core/logger.py create mode 100644 backend/logs/app.log create mode 100644 backend/logs/error.log diff --git a/backend/.env b/backend/.env index b686fce..7841a24 100644 --- a/backend/.env +++ b/backend/.env @@ -1 +1,4 @@ -DATABASE_URL=sqlite:///./wheel.db \ No newline at end of file +DATABASE_URL=sqlite:///./wheel.db + +LOG_ENABLED=true +LOG_LEVEL=DEBUG \ No newline at end of file diff --git a/backend/api/admin.py b/backend/api/admin.py index afc31ed..1677316 100644 --- a/backend/api/admin.py +++ b/backend/api/admin.py @@ -7,11 +7,11 @@ from sqlalchemy.orm import Session import schemas from schemas import ItemResponse from services import crud - from app.db.session import SessionLocal - +from core.logger import get_logger router = APIRouter() +logger = get_logger('admin') def get_db(): @@ -25,7 +25,13 @@ def get_db(): # GET ALL ITEMS @router.get("/items", response_model=list[ItemResponse]) def get_items(db: Session = Depends(get_db)): - return crud.get_items(db) + try: + items = crud.get_items(db) + logger.info(f"Items fetched: {len(items)} items") + return items + except Exception as e: + logger.error(f"Error fetching items: {e}") + raise # CREATE ITEM @@ -34,7 +40,13 @@ def create_item( item: schemas.ItemCreate, db: Session = Depends(get_db) ): - return crud.create_item(db, item.title) + try: + result = crud.create_item(db, item.title) + logger.info(f"Item created: {item.title}") + return result + except Exception as e: + logger.error(f"Error creating item: {e}") + raise # DELETE ITEM @@ -43,7 +55,15 @@ def delete_item( item_id: int, db: Session = Depends(get_db) ): - item = crud.delete_item(db, item_id) - if not item: - raise HTTPException(status_code=404, detail="Item not found") - return {"message": "Item deleted"} \ No newline at end of file + try: + item = crud.delete_item(db, item_id) + if not item: + logger.warning(f"Item not found: {item_id}") + raise HTTPException(status_code=404, detail="Item not found") + logger.info(f"Item deleted: {item_id}") + return {"message": "Item deleted"} + except HTTPException: + raise + except Exception as e: + logger.error(f"Error deleting item: {e}") + raise \ No newline at end of file diff --git a/backend/api/user.py b/backend/api/user.py index 9861a42..a93d67b 100644 --- a/backend/api/user.py +++ b/backend/api/user.py @@ -6,54 +6,36 @@ from sqlalchemy.orm import Session import schemas from services import crud - from app.db.session import SessionLocal - +from core.logger import get_logger router = APIRouter() +logger = get_logger('user') def get_db(): - db = SessionLocal() - try: yield db - finally: db.close() # GET ITEMS -@router.get( - "/items", - response_model=list[schemas.ItemResponse] -) -def get_items( - db: Session = Depends(get_db) -): - - return crud.get_items(db) +@router.get("/items", response_model=list[schemas.ItemResponse]) +def get_items(db: Session = Depends(get_db)): + try: + items = crud.get_items(db) + logger.info(f"User fetched items: {len(items)} items") + return items + except Exception as e: + logger.error(f"Error fetching items: {e}") + raise # SPIN @router.post("/spin") -def spin( - db: Session = Depends(get_db) -): - - winner = crud.spin_wheel(db) - - if not winner: - - raise HTTPException( - status_code=400, - detail="No items available" - ) - - return { - "winner": { - "id": winner.id, - "title": winner.title - } - } \ No newline at end of file +def spin(db: Session = Depends(get_db)): + try: + winner = crud.spin_wheel(db) + if not winner: \ No newline at end of file diff --git a/backend/core/__init__.py b/backend/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/core/__pycache__/__init__.cpython-313.pyc b/backend/core/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d3ec5927e848c0ab1a06ad91a0ebf9ae7236c0d GIT binary patch literal 135 zcmey&%ge<81n;H`Wr66&AOZ#$p^VQgK*m&tbOudEzm*I{OhDdekkldoS3A<7%Q6rNr0+UuWP$N6!SfK!viB}Ph8iKHT-f;O#_wn-hd8&gHG8X0@*y7ixC z*QE`J8ibUp7lPCZgDSNr1QG|3kl+YhxYn^Hn< zXTJBnH+!P!K+yg!bzk{_N9a$wFq^G8*}KgkbQdW|VHOc?j0|RA%`UR%EZE|wGRq=& zj>o(oMfqVg-86+2BfCt8?Qs|>oWf7D4TPU|YkBK4 zeY8i@TNKIOw$z+WTN*R$g3}I~()I|a6%@PTm|@{QNPe-sW6nUsskjtzhQ)40igqdP zs7L9FTBfXuXAoWCa5t=we8kjmk5jDDZD{l=Jzz(*UTN=|vnfvLHMG1*CfN6cio-#M z^vF3qrl+#W`BYjx6U!#jDh9DLor@*b6FFVYUL($><%RW7_~hJD=rrMUTu_Ofik3oe zhn5I`Iy4tqAY3|^)KaIhvw`!o0R^1e5;0x9l+lTB3C>CF2yb{JR;=m;oQ*e$U|g5d zjs|2e58Yj~2IOlrg^3^uy~--AVxjbz;j(Omm7BpcwdfdOrkhrN1R6l>{cX)^N;)-1 zQP3LR;3*iBDTLlaPpI<^zMx+ke=TSsLMC>7?uM>v#Q9DvezlN4l`CZ7T52|)OF$Tc z9Hs_D&{Tbi!bMy#o6q4)OxIOR?DNa=`I9RvAvtKlG%c`5)oqs>q0^|b-|r`*q1mXC zPi6fVE~{!fO8=#16VZ4Mt5G;yQpFSb8$?{EaIQCv@c7$bS46){FV!9HE#cP2 zLt(J)@z;C%>Yo0mcHV6*F6_Dx@2YXVWv+KCQsrK#bIuyqU*`Jn4OF?2y0g0&-UBZv zPCK*F)6s9Q1RVs%lq0z_d`)S)24qnL9TB95(;i#O&ZyjMk-RExL}}1vAlEPv*@SMDmQ!po|qOE!cq3eTa*S7y}N#+vIGL?yzEqBhmdodnb&ussOXmM^)5Z%c&QG3~${{s6uxkN34T z$rN;IANW^~si`m>R!vs@4{NrAlQb3fHS>jduE*93V!j)l7Qit}c*7RU=O=(=8+H}r z9H!Ht6Vs=G*pra`MwSx6%xp|+5OKs3i6#|^Gh9fgJ9&v|;WM(B@F7`VmN6w=ki~v# zYNd=;u|`4hH)-mCAFVg!n8tPlK5Yv+AgI_|6Nk3Np^{z^M~m}2HgWUj=FPgh@0R$N z(|h~%x**krfwC}g@8#Oy`1asoVGW9`S#OQ> zCKe6!Evc+-V2f!M8^{uCBS;2xUnAp;jr13eXL5-`T73f_17(`5+Aq-US{R0TgrrBv z{umv7jE4R|&X2_%sq2%}?Nmv8aIGRu)TF7hG*yv~{dlA-ohUkgbME2Ry5e%gZ_b+~a K@gF)h?)WbR;O-y* literal 0 HcmV?d00001 diff --git a/backend/core/logger.py b/backend/core/logger.py new file mode 100644 index 0000000..c3e59d9 --- /dev/null +++ b/backend/core/logger.py @@ -0,0 +1,50 @@ +import logging +import os +from logging.handlers import RotatingFileHandler +from dotenv import load_dotenv + +load_dotenv() + +LOG_ENABLED = os.getenv('LOG_ENABLED', 'true').lower() == 'true' +LOG_LEVEL = getattr(logging, os.getenv('LOG_LEVEL', 'DEBUG').upper(), logging.DEBUG) + +os.makedirs('logs', exist_ok=True) + +FORMATTER = logging.Formatter( + '%(asctime)s | %(levelname)s | %(name)s | %(message)s', + datefmt='%Y-%m-%d %H:%M:%S' +) + +def _file_handler(filename: str, level: int) -> RotatingFileHandler: + handler = RotatingFileHandler( + f'logs/{filename}', + maxBytes=5 * 1024 * 1024, + backupCount=3, + encoding='utf-8' + ) + handler.setLevel(level) + handler.setFormatter(FORMATTER) + return handler + +def _console_handler() -> logging.StreamHandler: + handler = logging.StreamHandler() + handler.setLevel(logging.INFO) + handler.setFormatter(FORMATTER) + return handler + +def get_logger(name: str) -> logging.Logger: + logger = logging.getLogger(name) + + if logger.handlers: + return logger + + if not LOG_ENABLED: + logger.addHandler(logging.NullHandler()) + return logger + + logger.setLevel(LOG_LEVEL) + logger.addHandler(_file_handler('app.log', LOG_LEVEL)) + logger.addHandler(_file_handler('error.log', logging.ERROR)) + logger.addHandler(_console_handler()) + + return logger \ No newline at end of file diff --git a/backend/logs/app.log b/backend/logs/app.log new file mode 100644 index 0000000..78e4cd8 --- /dev/null +++ b/backend/logs/app.log @@ -0,0 +1 @@ +2026-05-24 09:52:10 | INFO | test | test diff --git a/backend/logs/error.log b/backend/logs/error.log new file mode 100644 index 0000000..e69de29 diff --git a/backend/wheel.db b/backend/wheel.db index 36027c69aac573658cef74aa44f98bbef8eae753..61ec360d2a30b638b10733c71c201947065c600c 100644 GIT binary patch delta 231 zcmZozz}T>Wae_3X@I)DBM&XSK3-v|$A26`-Ph{Xf&wqq}Gyfv~iTv;Rdp8RTl=IgM zvNJRA1F`CjH8+;u?zyq)X1jtRKO3rm89ytkfGH;nGlS&KeK$L9wed4UWae_1>`$QRMM)r*f3-$RK7#LXik1+6mZL4hs&KAbGf43anZ z-R!v4#?Q>mpn7A?jpaAHZfv^Qu3*g1geqXf%gD^22vTvo2c&`vY~m{h{y+TR_&@N! b0-AV>UyPNRk&%T3L^3mjNG2v`W=>83k(DnY