feat: Add admin notification functionality for rate limit exceedances and integrate it into the rate limit exception handler.

main
Cizz22 2 weeks ago
parent f4fee20c1f
commit 0df6225624

@ -78,3 +78,76 @@ async def get_token(request: Request):
CurrentUser = Annotated[UserBase, Depends(get_current_user)] CurrentUser = Annotated[UserBase, Depends(get_current_user)]
Token = Annotated[str, Depends(get_token)] Token = Annotated[str, Depends(get_token)]
import httpx
import logging
from typing import Dict, Any
log = logging.getLogger(__name__)
AUTH_NOTIFY_ENDPOINT = f"{config.AUTH_SERVICE_API}/admin/notify-limit"
async def notify_admin_on_rate_limit(
endpoint_name: str,
ip_address: str,
method: str = "POST",
cooldown: int = 900,
timeout: int = 5
) -> Dict[str, Any]:
"""
Kirim notifikasi ke admin via be-auth service ketika rate limit terlampaui.
Async version - gunakan di async context.
"""
payload = {
"endpoint_name": endpoint_name,
"ip_address": ip_address,
"method": method,
"cooldown": cooldown,
}
try:
async with httpx.AsyncClient(timeout=timeout) as client:
response = await client.post(AUTH_NOTIFY_ENDPOINT, json=payload)
response.raise_for_status()
result = response.json()
log.info(f"Notifikasi admin sent | Endpoint: {endpoint_name}")
return result
except Exception as e:
log.error(f"Error notifying admin: {str(e)}")
return {"status": False, "message": str(e), "data": payload}
def notify_admin_on_rate_limit_sync(
endpoint_name: str,
ip_address: str,
method: str = "POST",
cooldown: int = 900,
timeout: int = 5
) -> Dict[str, Any]:
"""
Kirim notifikasi ke admin via be-auth service.
Sync version - gunakan di exception handler atau sync context.
RECOMMENDED untuk use case ini.
"""
payload = {
"endpoint_name": endpoint_name,
"ip_address": ip_address,
"method": method,
"cooldown": cooldown,
}
try:
response = httpx.post(AUTH_NOTIFY_ENDPOINT, json=payload, timeout=timeout)
response.raise_for_status()
result = response.json()
log.info(f"Notifikasi admin sent | Endpoint: {endpoint_name}")
return result
except Exception as e:
log.error(f"Error notifying admin: {str(e)}")
return {"status": False, "message": str(e), "data": payload}

@ -7,6 +7,7 @@ from fastapi.responses import JSONResponse
from pydantic import BaseModel from pydantic import BaseModel
from src.enums import ResponseStatus from src.enums import ResponseStatus
from src.auth.service import notify_admin_on_rate_limit_sync
from slowapi import _rate_limit_exceeded_handler from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded from slowapi.errors import RateLimitExceeded
@ -104,6 +105,13 @@ def handle_exception(request: Request, exc: Exception):
request.state.error_id = error_id request.state.error_id = error_id
if isinstance(exc, RateLimitExceeded): if isinstance(exc, RateLimitExceeded):
# Kirim notifikasi ke admin
notify_admin_on_rate_limit_sync(
endpoint_name=request_info["endpoint"],
ip_address=request_info["remote_addr"],
method=request_info["method"],
)
logging.warning( logging.warning(
f"Rate limit exceeded | Error ID: {error_id}", f"Rate limit exceeded | Error ID: {error_id}",
extra={ extra={

Loading…
Cancel
Save