refactor: update logger import paths to use rotoger

This commit is contained in:
grillazz
2026-03-09 18:05:05 +01:00
parent 07c98d79ae
commit 21c5953385
13 changed files with 21 additions and 108 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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
+2 -3
View File
@@ -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..."
+1 -1
View File
@@ -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
-86
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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",
]
Generated
+8 -8
View File
@@ -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]]