refactor logging module, add welcome and reset daemons, changed structure of the rabbitmq queues

This commit is contained in:
2026-09-13 18:40:14 +03:00
parent b4e88a6ff4
commit a93c6d5fca
20 changed files with 374 additions and 58 deletions
+46 -24
View File
@@ -1,8 +1,10 @@
import asyncio
import json
import logging
from contextvars import ContextVar
from time import gmtime, perf_counter, strftime
from typing import cast
from uuid import uuid4
import aiofiles
from fastapi import Request
@@ -11,8 +13,28 @@ from starlette.concurrency import iterate_in_threadpool
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response, StreamingResponse
request_id_ctx: ContextVar[str] = ContextVar("request_id", default="-")
class ProcessingTimeMiddleware(BaseHTTPMiddleware):
log_queue=asyncio.Queue()
class LogWriter:
def __init__(self) -> None:
pass
async def log_writer(self)->None:
while True:
log_type, msg=await log_queue.get()
await self._write(msg, log_type)
async def _write(self, msg:str, type:str)->None:
file_time = strftime("%b_%Y", gmtime())
current_time = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
async with aiofiles.open(f"./logs/{type}_log_{file_time}.txt", "a") as f:
await f.write(f"[{current_time}] {msg}\n")
class ProcessingTimeMiddleware(BaseHTTPMiddleware, ):
async def dispatch(self, request: Request, call_next)->Response:
start_time = perf_counter()
response = await call_next(request)
@@ -22,19 +44,26 @@ class ProcessingTimeMiddleware(BaseHTTPMiddleware):
class LoggingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next) -> Response:
current_time = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
file_time = strftime("%b_%Y", gmtime())
client_ip = request.headers.get('x-forwarded-for', '').split(',')[0].strip() or (request.client.host if request.client else 'unknown')
async def build_log_line(self, request_id, method, path, status_code, detail, client_ip) -> str:
return f"[{request_id}] [{method}] [{path}] [{status_code}] [{detail}] [{client_ip}]"
async def dispatch(self, request: Request, call_next) -> Response:
request_id=str(uuid4())
request_id_ctx.set(request_id)
client_ip = request.headers.get('x-forwarded-for', '').split(',')[0].strip() or (request.client.host if request.client else 'unknown')
method = request.method
path=request.url.path
try:
response = await call_next(request)
except Exception as exc: # noqa: BLE001
body = str(exc)
async with aiofiles.open(f"./logs/endpoints_log_{file_time}.txt", "a") as file:
await file.write(f"[{current_time}] [500] [{body}] [{client_ip}]\n")
return JSONResponse(status_code=500, content={"detail": "Internal Server Error"})
line=await self.build_log_line(request_id=request_id, method=method, path=path, status_code=500, detail=repr(exc), client_ip=client_ip)
log_queue.put_nowait(("endpoints", line))
return JSONResponse(
status_code=500,
content={"detail": "Internal Server Error", "request_id": request_id}
)
streaming_response = cast(StreamingResponse, response)
chunks = []
@@ -49,23 +78,16 @@ class LoggingMiddleware(BaseHTTPMiddleware):
body = parsed.get("detail", None) if not isinstance(parsed, bool) else None
except (json.JSONDecodeError, TypeError):
body = None
async with aiofiles.open(f"./logs/endpoints_log_{file_time}.txt", "a") as file:
await file.write(f"[{current_time}] [{response.status_code}] [{body}] [{client_ip}]\n")
line=await self.build_log_line(request_id=request_id, method=method, path=path, status_code=response.status_code, detail=body, client_ip=client_ip)
log_queue.put_nowait(("endpoints", line))
return response
class LoggerDB(logging.Handler):
class LoggerDB(logging.Handler, LogWriter):
def emit(self, record: logging.LogRecord) -> None:
msg = self.format(record)
asyncio.create_task(self._write(msg))
async def _write(self, msg: str) -> None:
file_time = strftime("%b_%Y", gmtime())
current_time = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
async with aiofiles.open(f"./logs/sql_log_{file_time}.txt", "a") as f:
await f.write(f"[{current_time}] {msg}\n")
rid=request_id_ctx.get()
log_queue.put_nowait(("sql",f"[{rid}] {msg}"))