68 lines
2.7 KiB
Python
68 lines
2.7 KiB
Python
|
|
from fastapi import Request
|
|
from fastapi.responses import JSONResponse
|
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
from sqlalchemy.orm import Session
|
|
from app.db.models import OperationLog,User
|
|
from app.core.apiexception import APIException
|
|
from app.core.dbmanager import get_log_db
|
|
from app.db.crud import create_log
|
|
import json
|
|
|
|
class LoggingMiddleware(BaseHTTPMiddleware):
|
|
async def dispatch(self, request: Request, call_next):
|
|
if request.method in ("POST", "PUT", "PATCH","DELETE"):
|
|
try:
|
|
request.state.body = await request.json()
|
|
except json.JSONDecodeError:
|
|
request.state.body = await request.body()
|
|
else:
|
|
request.state.body = None
|
|
|
|
try:
|
|
response = await call_next(request)
|
|
state = request.state
|
|
except Exception as e:
|
|
await self.log_error(request, e)
|
|
response = JSONResponse(
|
|
content={"detail": "Internal Server Error"},
|
|
status_code=500
|
|
)
|
|
|
|
if hasattr(request.state, "user") and hasattr(request.state, "tenant"):
|
|
await self.log_request(request, response,state)
|
|
|
|
return response
|
|
|
|
async def log_request(self, request: Request, response,state):
|
|
try:
|
|
headers = dict(request.headers)
|
|
|
|
db_operation = OperationLog(tenantid =request.state.tenant,
|
|
clientip = request.client.host if request.client else None,
|
|
useragent =headers.get("user-agent", ""),
|
|
userid = request.state.user.id,
|
|
operation = request.method,
|
|
function = request.url.path,
|
|
parameters = str({"path": request.path_params,"query": dict(request.query_params),"body": request.state.body}),
|
|
response = f"status_code:{response.status_code }" )
|
|
|
|
db = request.state.db
|
|
if db:
|
|
await self.write_log_to_db(db_operation,db)
|
|
except Exception as e:
|
|
print(f"Logging failed: {str(e)}")
|
|
|
|
|
|
async def log_error(self, request: Request, e: Exception):
|
|
exc = APIException('operation:dispatch',request.url._url,f"Error occurred while writting operation log:",e)
|
|
db = get_log_db()
|
|
try:
|
|
create_log(db,exc.error)
|
|
finally:
|
|
db.close()
|
|
|
|
async def write_log_to_db(self, db_operation,db):
|
|
db.add(db_operation)
|
|
db.commit()
|
|
|