master #18
@ -6,6 +6,7 @@ services:
|
|||||||
image: mathwave/sprint-repo:configurator
|
image: mathwave/sprint-repo:configurator
|
||||||
networks:
|
networks:
|
||||||
- configurator-development
|
- configurator-development
|
||||||
|
- monitoring
|
||||||
environment:
|
environment:
|
||||||
MONGO_HOST: "mongo.develop.sprinthub.ru"
|
MONGO_HOST: "mongo.develop.sprinthub.ru"
|
||||||
MONGO_PASSWORD: $MONGO_PASSWORD_DEV
|
MONGO_PASSWORD: $MONGO_PASSWORD_DEV
|
||||||
@ -20,3 +21,5 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
configurator-development:
|
configurator-development:
|
||||||
external: true
|
external: true
|
||||||
|
monitoring:
|
||||||
|
external: true
|
||||||
|
@ -6,6 +6,7 @@ services:
|
|||||||
image: mathwave/sprint-repo:configurator
|
image: mathwave/sprint-repo:configurator
|
||||||
networks:
|
networks:
|
||||||
- configurator
|
- configurator
|
||||||
|
- monitoring
|
||||||
environment:
|
environment:
|
||||||
MONGO_HOST: "mongo.sprinthub.ru"
|
MONGO_HOST: "mongo.sprinthub.ru"
|
||||||
MONGO_PASSWORD: $MONGO_PASSWORD_PROD
|
MONGO_PASSWORD: $MONGO_PASSWORD_PROD
|
||||||
@ -20,3 +21,5 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
configurator:
|
configurator:
|
||||||
external: true
|
external: true
|
||||||
|
monitoring:
|
||||||
|
external: true
|
||||||
|
0
app/middlewares/__init__.py
Normal file
0
app/middlewares/__init__.py
Normal file
14
app/middlewares/metrics.py
Normal file
14
app/middlewares/metrics.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import datetime
|
||||||
|
import zoneinfo
|
||||||
|
from fastapi import Request, Response
|
||||||
|
from starlette.middleware.base import BaseHTTPMiddleware
|
||||||
|
|
||||||
|
from app.utils.monitoring import monitoring
|
||||||
|
|
||||||
|
class MetricsMiddleware(BaseHTTPMiddleware):
|
||||||
|
async def dispatch(self, request: Request, call_next):
|
||||||
|
start = datetime.datetime.now(zoneinfo.ZoneInfo("Europe/Moscow"))
|
||||||
|
response: Response = await call_next(request)
|
||||||
|
end = datetime.datetime.now(zoneinfo.ZoneInfo("Europe/Moscow"))
|
||||||
|
monitoring.send_metric(start, end, request.url.path, response.status_code, request.method)
|
||||||
|
return response
|
@ -1,3 +1,4 @@
|
|||||||
|
import bson
|
||||||
import fastapi
|
import fastapi
|
||||||
import pydantic
|
import pydantic
|
||||||
|
|
||||||
@ -37,14 +38,14 @@ async def post(body: RequestPostBody):
|
|||||||
|
|
||||||
@router.put('/api/v1/experiments', status_code=fastapi.status.HTTP_202_ACCEPTED, responses={404: {'description': 'Not found'}})
|
@router.put('/api/v1/experiments', status_code=fastapi.status.HTTP_202_ACCEPTED, responses={404: {'description': 'Not found'}})
|
||||||
async def put(body: RequestPutBody):
|
async def put(body: RequestPutBody):
|
||||||
changed = await experiments.update(id=body.id, enabled=body.enabled, condition=body.condition)
|
changed = await experiments.update(id=bson.ObjectId(body.id), enabled=body.enabled, condition=body.condition)
|
||||||
if not changed:
|
if not changed:
|
||||||
raise fastapi.HTTPException(404)
|
raise fastapi.HTTPException(404)
|
||||||
|
|
||||||
|
|
||||||
@router.delete('/api/v1/experiments', status_code=fastapi.status.HTTP_202_ACCEPTED, responses={404: {'description': 'Not found'}})
|
@router.delete('/api/v1/experiments', status_code=fastapi.status.HTTP_202_ACCEPTED, responses={404: {'description': 'Not found'}})
|
||||||
async def delete(body: RequestDeleteBody):
|
async def delete(body: RequestDeleteBody):
|
||||||
changed = await experiments.delete(id=body.id)
|
changed = await experiments.delete(id=bson.ObjectId(body.id))
|
||||||
if not changed:
|
if not changed:
|
||||||
raise fastapi.HTTPException(404)
|
raise fastapi.HTTPException(404)
|
||||||
|
|
||||||
|
24
app/utils/monitoring.py
Normal file
24
app/utils/monitoring.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
import datetime
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
class Monitroing:
|
||||||
|
def __init__(self):
|
||||||
|
self.executor = ThreadPoolExecutor(max_workers=1)
|
||||||
|
|
||||||
|
def send_metric(self, start: datetime.datetime, end: datetime.datetime, endpoint: str, status_code: int, method: str):
|
||||||
|
def send():
|
||||||
|
requests.post(f'http://monitoring:1237/api/v1/metrics/endpoint', json={
|
||||||
|
'timestamp': start.strftime("%Y-%m-%dT%H:%M:%S") + "Z",
|
||||||
|
'service': 'configurator',
|
||||||
|
'endpoint': endpoint,
|
||||||
|
'status_code': status_code,
|
||||||
|
'response_time': (end - start).microseconds // 1000,
|
||||||
|
'method': method,
|
||||||
|
})
|
||||||
|
|
||||||
|
self.executor.submit(send)
|
||||||
|
|
||||||
|
|
||||||
|
monitoring = Monitroing()
|
2
main.py
2
main.py
@ -1,6 +1,7 @@
|
|||||||
import fastapi
|
import fastapi
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
|
from app.middlewares.metrics import MetricsMiddleware
|
||||||
from app.routers import experiments
|
from app.routers import experiments
|
||||||
from app.routers import configs
|
from app.routers import configs
|
||||||
from app.routers import staff
|
from app.routers import staff
|
||||||
@ -10,6 +11,7 @@ from app.storage import mongo
|
|||||||
|
|
||||||
|
|
||||||
app = fastapi.FastAPI()
|
app = fastapi.FastAPI()
|
||||||
|
app.add_middleware(MetricsMiddleware)
|
||||||
|
|
||||||
app.include_router(experiments.router)
|
app.include_router(experiments.router)
|
||||||
app.include_router(configs.router)
|
app.include_router(configs.router)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
annotated-types==0.7.0
|
annotated-types==0.7.0
|
||||||
anyio==4.6.2.post1
|
anyio==4.6.2.post1
|
||||||
APScheduler==3.10.4
|
APScheduler==3.10.4
|
||||||
|
certifi==2025.6.15
|
||||||
|
charset-normalizer==3.4.2
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
dnspython==2.7.0
|
dnspython==2.7.0
|
||||||
fastapi==0.115.4
|
fastapi==0.115.4
|
||||||
@ -12,9 +14,11 @@ pydantic_core==2.23.4
|
|||||||
pymongo==4.9.2
|
pymongo==4.9.2
|
||||||
pytz==2024.2
|
pytz==2024.2
|
||||||
redis==5.2.0
|
redis==5.2.0
|
||||||
|
requests==2.32.4
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
sniffio==1.3.1
|
sniffio==1.3.1
|
||||||
starlette==0.41.2
|
starlette==0.41.2
|
||||||
typing_extensions==4.12.2
|
typing_extensions==4.12.2
|
||||||
tzlocal==5.2
|
tzlocal==5.2
|
||||||
|
urllib3==2.4.0
|
||||||
uvicorn==0.32.0
|
uvicorn==0.32.0
|
||||||
|
Loading…
Reference in New Issue
Block a user