mirror of
https://github.com/grillazz/fastapi-sqlalchemy-asyncpg.git
synced 2026-04-23 08:20:39 +03:00
refactor: update logger import paths to use rotoger
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, Query, Request, status
|
||||
from pydantic import EmailStr
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
from starlette.concurrency import run_in_threadpool
|
||||
|
||||
from app.services.smtp import SMTPEmailService
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, Form
|
||||
from fastapi.responses import StreamingResponse
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
|
||||
from app.services.llm import get_llm_service
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, Form, HTTPException, Request, status
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.database import get_db
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
from collections.abc import AsyncGenerator
|
||||
|
||||
from fastapi.exceptions import ResponseValidationError
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import orjson
|
||||
from attrs import define, field
|
||||
from fastapi import Request
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
|
||||
logger = get_logger()
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ from typing import Any
|
||||
|
||||
from asyncpg import UniqueViolationError
|
||||
from fastapi import HTTPException, status
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import DeclarativeBase, declared_attr
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
from typing import Any
|
||||
from typing import Any, Callable
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic import BaseModel, ConfigDict, Field, WrapValidator, ValidationError
|
||||
|
||||
config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class RandomStuff(BaseModel):
|
||||
chaos: dict[str, Any] = Field(
|
||||
..., description="Pretty chaotic JSON data can be added here..."
|
||||
|
||||
@@ -3,7 +3,7 @@ import time
|
||||
import jwt
|
||||
from fastapi import HTTPException, Request
|
||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
|
||||
from app.config import settings as global_settings
|
||||
from app.models.user import User
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import logging
|
||||
import os
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from pathlib import Path
|
||||
|
||||
import orjson
|
||||
import structlog
|
||||
from whenever._whenever import Instant
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Constants / defaults
|
||||
# ---------------------------------------------------------------------------
|
||||
_DEFAULT_LOG_PATH = "."
|
||||
_DEFAULT_MAX_BYTES = 10 * 1024 * 1024 # 10 MiB
|
||||
_DEFAULT_BACKUP_COUNT = 5
|
||||
|
||||
# Generic registry: add any stdlib logger name + its desired level here.
|
||||
_STDLIB_LOGGERS: dict[str, int] = {
|
||||
"root": logging.INFO,
|
||||
"uvicorn": logging.INFO,
|
||||
"sqlalchemy": logging.WARNING,
|
||||
}
|
||||
|
||||
# Shared processor chain used by both structlog and the stdlib formatter.
|
||||
_SHARED_PROCESSORS: list[structlog.types.Processor] = [
|
||||
structlog.contextvars.merge_contextvars,
|
||||
structlog.stdlib.add_log_level,
|
||||
structlog.stdlib.add_logger_name,
|
||||
structlog.stdlib.PositionalArgumentsFormatter(),
|
||||
structlog.processors.TimeStamper(fmt="iso", utc=True),
|
||||
structlog.processors.format_exc_info,
|
||||
]
|
||||
|
||||
|
||||
def _build_handler() -> RotatingFileHandler:
|
||||
log_dir = Path(os.getenv("ROTOGER_LOG_PATH", _DEFAULT_LOG_PATH))
|
||||
log_dir.mkdir(parents=True, exist_ok=True)
|
||||
log_path = log_dir / f"{Instant.now().py_datetime().strftime('%Y%m%d')}_{os.getpid()}.log"
|
||||
|
||||
handler = RotatingFileHandler(
|
||||
filename=log_path,
|
||||
maxBytes=int(os.getenv("ROTOGER_LOG_MAX_BYTES", _DEFAULT_MAX_BYTES)),
|
||||
backupCount=int(os.getenv("ROTOGER_LOG_BACKUP_COUNT", _DEFAULT_BACKUP_COUNT)),
|
||||
encoding="utf-8",
|
||||
)
|
||||
handler.setFormatter(
|
||||
structlog.stdlib.ProcessorFormatter(
|
||||
foreign_pre_chain=_SHARED_PROCESSORS,
|
||||
processor=structlog.processors.JSONRenderer(
|
||||
serializer=lambda *a, **kw: orjson.dumps(*a, **kw).decode()
|
||||
),
|
||||
)
|
||||
)
|
||||
return handler
|
||||
|
||||
|
||||
def _configure_logger() -> structlog.BoundLogger:
|
||||
"""Configure structlog + stdlib loggers and return a bound logger."""
|
||||
structlog.configure(
|
||||
processors=[
|
||||
*_SHARED_PROCESSORS,
|
||||
structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
|
||||
],
|
||||
logger_factory=structlog.stdlib.LoggerFactory(),
|
||||
wrapper_class=structlog.stdlib.BoundLogger,
|
||||
cache_logger_on_first_use=True,
|
||||
)
|
||||
|
||||
handler = _build_handler()
|
||||
|
||||
for name, level in _STDLIB_LOGGERS.items():
|
||||
logger = logging.getLogger(name)
|
||||
logger.addHandler(handler)
|
||||
logger.propagate = False
|
||||
logger.setLevel(level)
|
||||
|
||||
return structlog.get_logger()
|
||||
|
||||
|
||||
# Module-level singleton
|
||||
_logger_instance = _configure_logger()
|
||||
|
||||
|
||||
def get_logger() -> structlog.BoundLogger:
|
||||
"""Return the configured singleton logger instance."""
|
||||
return _logger_instance
|
||||
@@ -3,7 +3,7 @@ from datetime import datetime
|
||||
from apscheduler import AsyncScheduler
|
||||
from apscheduler.triggers.interval import IntervalTrigger
|
||||
from attrs import define
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
from sqlalchemy import text
|
||||
from starlette.types import ASGIApp, Receive, Scope, Send
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from email.mime.text import MIMEText
|
||||
from attrs import define, field
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from pydantic import EmailStr
|
||||
from app.services.logging import get_logger
|
||||
from rotoger import get_logger
|
||||
|
||||
from app.config import settings as global_settings
|
||||
from app.utils.singleton import SingletonMetaNoArgs
|
||||
|
||||
+2
-2
@@ -22,14 +22,14 @@ dependencies = [
|
||||
"redis==7.1.0",
|
||||
"bcrypt==5.0.0",
|
||||
"polars[pyarrow]==1.36.1",
|
||||
"python-multipart==0.0.20",
|
||||
"python-multipart==0.0.22",
|
||||
"fastexcel==0.18.0",
|
||||
"inline-snapshot==0.31.1",
|
||||
"dirty-equals==0.11",
|
||||
"polyfactory==3.1.0",
|
||||
"granian==2.6.0",
|
||||
"apscheduler[redis,sqlalchemy]>=4.0.0a6",
|
||||
"rotoger==0.2.1",
|
||||
"rotoger==0.3.0",
|
||||
"pyinstrument>=5.1.2",
|
||||
]
|
||||
|
||||
|
||||
@@ -438,10 +438,10 @@ requires-dist = [
|
||||
{ name = "pyjwt", specifier = "==2.10.1" },
|
||||
{ name = "pytest", specifier = "==9.0.2" },
|
||||
{ name = "pytest-cov", specifier = "==7.0.0" },
|
||||
{ name = "python-multipart", specifier = "==0.0.20" },
|
||||
{ name = "python-multipart", specifier = "==0.0.22" },
|
||||
{ name = "redis", specifier = "==7.1.0" },
|
||||
{ name = "rich", specifier = "==14.2.0" },
|
||||
{ name = "rotoger", specifier = "==0.2.1" },
|
||||
{ name = "rotoger", specifier = "==0.3.0" },
|
||||
{ name = "sqlalchemy", specifier = "==2.0.45" },
|
||||
{ name = "uvicorn", extras = ["standard"], specifier = "==0.38.0" },
|
||||
{ name = "uvloop", specifier = "==0.22.1" },
|
||||
@@ -1075,11 +1075,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "python-multipart"
|
||||
version = "0.0.20"
|
||||
version = "0.0.22"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/01/979e98d542a70714b0cb2b6728ed0b7c46792b695e3eaec3e20711271ca3/python_multipart-0.0.22.tar.gz", hash = "sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58", size = 37612, upload-time = "2026-01-25T10:15:56.219Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/d0/397f9626e711ff749a95d96b7af99b9c566a9bb5129b8e4c10fc4d100304/python_multipart-0.0.22-py3-none-any.whl", hash = "sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155", size = 24579, upload-time = "2026-01-25T10:15:54.811Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1196,7 +1196,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "rotoger"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "attrs" },
|
||||
@@ -1204,9 +1204,9 @@ dependencies = [
|
||||
{ name = "structlog" },
|
||||
{ name = "whenever" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9d/ad/75a22ddd259505547fd47c36ea984688e3b56d9cbc49c0f98bb95c84c01b/rotoger-0.2.1.tar.gz", hash = "sha256:823bb39c781d6038d2aae1c2c3f6d74c0abb1e9f07b257c079028d6ae3f2589d", size = 1647, upload-time = "2025-11-13T16:12:27.833Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/06/40/475df92ef562d22489a1b07bc41cf1094dce1d4d03475f59112b97070560/rotoger-0.3.0.tar.gz", hash = "sha256:e407e3f4cf4948886bd26b35bd54e635f58703db406f5a706e4c4579dc273241", size = 2714, upload-time = "2026-03-01T17:08:46.78Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/da/9422061c62499eaafcf90c4adf3e13c51031d4b593af899451825fa85a7b/rotoger-0.2.1-py3-none-any.whl", hash = "sha256:849ed131068ab724991c38c32fb63e4904efb79e29bf084f37ec11a31ec0c703", size = 2603, upload-time = "2025-11-13T16:12:26.895Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/85/2164d61cff7594366d5797cc6f33784a05e83a39841701860bbbc41631dc/rotoger-0.3.0-py3-none-any.whl", hash = "sha256:08d3c239f05c0551a9cdb682332f4c1e981844b1b0afa7b1e04c50730bbe2098", size = 3458, upload-time = "2026-03-01T17:08:47.684Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user