Skip to content

Commit dbf9934

Browse files
core: Melhorando logs com loguru
1 parent e887d05 commit dbf9934

15 files changed

Lines changed: 106 additions & 41 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## [0.2.2](https://github.com/henriquesebastiao/vagas-dev/releases/0.2.2) - 2026-03-10
2+
3+
### Core
4+
5+
- Melhorando logs com loguru
6+
7+
18
## [0.2.1](https://github.com/henriquesebastiao/vagas-dev/releases/0.2.1) - 2026-03-05
29

310
### Funcionalidade

backend/app/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.2.1'
1+
__version__ = '0.2.2'

backend/app/api/routes/job.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import logging
21
from typing import Annotated
32

43
from fastapi import APIRouter, BackgroundTasks, HTTPException, Query, status
4+
from loguru import logger
55
from sqlalchemy import func, select
66

77
from app.enum import JobLevel, JobSource, Keyword, WorkplaceType
@@ -11,8 +11,6 @@
1111
from app.scrapers import gupy, linkedin
1212
from app.utils import Session
1313

14-
logger = logging.getLogger(__name__)
15-
1614
router = APIRouter(prefix='/jobs', tags=['jobs'])
1715

1816

backend/app/core/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Settings(BaseSettings):
1414
# App
1515
APP_URL: str = 'http://localhost:8000'
1616
INTERVAL_SYNC: int = 60 # Intervalo de execução dos jobs do scheduler
17+
DEBUG: bool = False
1718

1819
# Telegram
1920
TELEGRAM_BOT_TOKEN: str = ''

backend/app/main.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import asyncio
22
import logging
3+
import sys
34
from contextlib import asynccontextmanager
45

56
from fastapi import FastAPI
67
from fastapi.middleware.cors import CORSMiddleware
8+
from loguru import logger
79

810
from app import __version__
911
from app.api.routes import job
@@ -12,9 +14,32 @@
1214
from app.schemas.health import HealthOut
1315
from app.wrappers.discord_bot import bot
1416

15-
logging.basicConfig(level=logging.INFO)
1617
settings = get_settings()
1718

19+
log_level = 'INFO'
20+
if settings.DEBUG:
21+
log_level = 'DEBUG'
22+
23+
24+
class InterceptHandler(logging.Handler):
25+
def emit(self, record: logging.LogRecord):
26+
# Descobre o nível equivalente no loguru
27+
try:
28+
level = logger.level(record.levelname).name
29+
except ValueError:
30+
level = record.levelno
31+
32+
# Sobe na call stack para achar o chamador real
33+
frame, depth = sys._getframe(6), 6
34+
while frame and frame.f_code.co_filename == logging.__file__:
35+
frame = frame.f_back
36+
depth += 1
37+
38+
logger.opt(depth=depth, exception=record.exc_info).log(
39+
level, record.getMessage()
40+
)
41+
42+
1843
description = f"""
1944
Esta API fornece acesso a vagas de emprego para desenvolvedores, coletadas de diversas fontes.
2045
@@ -28,6 +53,30 @@
2853
async def lifespan(app: FastAPI):
2954
# Startup
3055

56+
# Remove o handler padrão do loguru
57+
logger.remove()
58+
59+
logger.add(
60+
sys.stdout,
61+
level=log_level,
62+
colorize=True,
63+
)
64+
65+
# Opcional: salvar em arquivo com rotação
66+
logger.add(
67+
'logs/app.log',
68+
level=log_level,
69+
rotation='10 MB',
70+
retention='7 days',
71+
compression='zip',
72+
)
73+
74+
# Intercepta todos os loggers do Python (uvicorn, sqlalchemy, etc.)
75+
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
76+
for name in logging.root.manager.loggerDict:
77+
logging.getLogger(name).handlers = [InterceptHandler()]
78+
logging.getLogger(name).propagate = False
79+
3180
# Aplica migrations pendentes automaticamente no startup
3281
proc = await asyncio.create_subprocess_exec(
3382
'alembic',

backend/app/notifiers.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import logging
21
from dataclasses import asdict
32
from typing import Any
43

4+
from loguru import logger
55
from sqlalchemy import select
66

77
from app.core.database import AsyncSessionLocal
@@ -10,8 +10,6 @@
1010
from app.wrappers.discord_bot import send_notification_jobs
1111
from app.wrappers.telegram import BotTelegram
1212

13-
logger = logging.getLogger(__name__)
14-
1513

1614
async def get_jobs_for_selector(selector) -> dict[str, Any]:
1715
async with AsyncSessionLocal() as session:

backend/app/scheduler.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import logging
2-
31
from apscheduler.schedulers.asyncio import AsyncIOScheduler
42
from apscheduler.triggers.interval import IntervalTrigger
3+
from loguru import logger
54

65
from app.core.database import AsyncSessionLocal
76
from app.core.settings import get_settings
87
from app.keywords import KEYWORDS
98
from app.notifiers import notify_new_jobs
109
from app.scrapers import gupy, linkedin
1110

12-
logger = logging.getLogger(__name__)
1311
scheduler = AsyncIOScheduler()
1412
settings = get_settings()
1513

backend/app/scrapers/base.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import logging
21
from abc import ABC, abstractmethod
32

3+
from loguru import logger
44
from sqlalchemy import select
55
from sqlalchemy.ext.asyncio import AsyncSession
66

77
from app.keywords import KEYWORDS
88
from app.models import Job
99

10-
logger = logging.getLogger(__name__)
11-
1210

1311
class BaseJobScraper(ABC):
1412
"""Contrato base para todos os scrapers de vagas.

backend/app/scrapers/gupy.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import html
2-
import logging
32
import re
43

54
import httpx
5+
from loguru import logger
66

77
from app.scrapers import transport
88
from app.scrapers.base import BaseJobScraper
99
from app.utils import get_level_seniority
1010

11-
logger = logging.getLogger(__name__)
12-
1311

1412
class GupyScraper(BaseJobScraper):
1513
"""

backend/app/scrapers/linkedin.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import asyncio
22
import hashlib
3-
import logging
43
from http import HTTPStatus
54

65
import httpx
76
from bs4 import BeautifulSoup
7+
from loguru import logger
88

99
from app.scrapers import transport
1010
from app.scrapers.base import BaseJobScraper
1111

12-
logger = logging.getLogger(__name__)
13-
1412
linkedin_level_id = {
1513
'estagio': 1,
1614
'junior': 3,

0 commit comments

Comments
 (0)