chore: introducing metrics
This commit is contained in:
parent
fad6ab856a
commit
d33d8a4c71
27
app/crud.py
27
app/crud.py
@ -1,10 +1,11 @@
|
|||||||
import bcrypt, time
|
import bcrypt, time
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session, load_only
|
||||||
from app import models, schemas
|
from app import models, schemas
|
||||||
|
|
||||||
|
|
||||||
User=models.User
|
User=models.User
|
||||||
Service=models.Service
|
Service=models.Service
|
||||||
|
Metric=models.Metric
|
||||||
|
|
||||||
def get_user(db: Session, user_id: int):
|
def get_user(db: Session, user_id: int):
|
||||||
return db.query(User).filter(User.id == user_id).first()
|
return db.query(User).filter(User.id == user_id).first()
|
||||||
@ -44,6 +45,8 @@ def update_user(db: Session, user_id: int, user: schemas.UserUpdate):
|
|||||||
db.query(User).filter(User.id==user_id).update({User.full_name: updated_user.full_name})
|
db.query(User).filter(User.id==user_id).update({User.full_name: updated_user.full_name})
|
||||||
if (updated_user.is_active is not None):
|
if (updated_user.is_active is not None):
|
||||||
db.query(User).filter(User.id==user_id).update({User.is_active: updated_user.is_active})
|
db.query(User).filter(User.id==user_id).update({User.is_active: updated_user.is_active})
|
||||||
|
if (updated_user.is_superuser is not None):
|
||||||
|
db.query(User).filter(User.id==user_id).update({User.is_superuser: updated_user.is_superuser})
|
||||||
if (updated_user is not user):
|
if (updated_user is not user):
|
||||||
db.query(User).filter(User.id==user_id).update({User.updated_unix: time.time()})
|
db.query(User).filter(User.id==user_id).update({User.updated_unix: time.time()})
|
||||||
return db.commit()
|
return db.commit()
|
||||||
@ -109,3 +112,25 @@ def login_info(db: Session, name: str, password: str):
|
|||||||
return
|
return
|
||||||
return usr
|
return usr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_urls(db: Session):
|
||||||
|
# return db.query(Service).filter(Service.is_active == True).options(load_only(Service.url)).all()
|
||||||
|
return db.query(Service).filter(Service.is_active == True).all()
|
||||||
|
|
||||||
|
|
||||||
|
def get_metrics(db: Session, skip: int = 0, limit: int = 90):
|
||||||
|
return db.query(Metrics).offset(skip).limit(limit).all()
|
||||||
|
|
||||||
|
def create_metric(db: Session, me: schemas.MetricCreate):
|
||||||
|
db_metric = User(**me.dict())
|
||||||
|
if (me.http_response_code >=500):
|
||||||
|
db_metric.status=2
|
||||||
|
elif (me.http_response_code >=400):
|
||||||
|
db_metric.status=1
|
||||||
|
elif (me.http_response_code >=200):
|
||||||
|
db_metric.status=0
|
||||||
|
db.add(db_metric)
|
||||||
|
db.commit()
|
||||||
|
return db.commit()
|
||||||
|
|
||||||
|
15
app/main.py
15
app/main.py
@ -1,6 +1,7 @@
|
|||||||
# vim:fileencoding=utf-8:ft=python:foldmethod=marker
|
# vim:fileencoding=utf-8:ft=python:foldmethod=marker
|
||||||
# statuspage/app/main.py
|
# statuspage/app/main.py
|
||||||
|
|
||||||
|
import asyncio
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from fastapi import FastAPI, Depends, Security, HTTPException
|
from fastapi import FastAPI, Depends, Security, HTTPException
|
||||||
@ -8,6 +9,7 @@ from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app import crud, models, schemas, auth
|
from app import crud, models, schemas, auth
|
||||||
|
from app import ultrametrics
|
||||||
from app.database import SessionLocal, engine
|
from app.database import SessionLocal, engine
|
||||||
|
|
||||||
|
|
||||||
@ -111,7 +113,7 @@ async def read_user(user_id: int, db: Session = Depends(get_db)):
|
|||||||
|
|
||||||
@app.patch("/api/v1/users/{user_id}")
|
@app.patch("/api/v1/users/{user_id}")
|
||||||
async def update_user(user_id: int, user: schemas.UserUpdate, db: Session = Depends(get_db), token: str = Security(is_auth)):
|
async def update_user(user_id: int, user: schemas.UserUpdate, db: Session = Depends(get_db), token: str = Security(is_auth)):
|
||||||
if ((user.name is None) and (user.password is None) and (user.full_name is None) and (user.is_active is None)):
|
if ((user.name is None) and (user.password is None) and (user.full_name is None) and (user.is_active is None) and (user.is_superuser is None)):
|
||||||
raise HTTPException(status_code=400, detail="No data provided")
|
raise HTTPException(status_code=400, detail="No data provided")
|
||||||
db_user = get_usr(user_id, db)
|
db_user = get_usr(user_id, db)
|
||||||
if db_user is None:
|
if db_user is None:
|
||||||
@ -142,3 +144,14 @@ async def validate_token(token: str):
|
|||||||
if a:
|
if a:
|
||||||
return a
|
return a
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/v1/metrics", response_model=List[schemas.Metric])
|
||||||
|
async def get_metrics(skip: int = 0, limit: int = 90, db: Session = Depends(get_db)):
|
||||||
|
return crud.get_metrics(db=db, skip=skip, limit=limit)
|
||||||
|
|
||||||
|
@app.get("/api/v1/urls")
|
||||||
|
async def get_urls(skip: int = 0, limit: int = 90, db: Session = Depends(get_db)):
|
||||||
|
return crud.get_urls(db=db, skip=skip, limit=limit)
|
||||||
|
|
||||||
|
@ -28,9 +28,23 @@ class User(Base):
|
|||||||
full_name = Column(String, index=True)
|
full_name = Column(String, index=True)
|
||||||
password = Column(String)
|
password = Column(String)
|
||||||
is_active = Column(Boolean, index=True)
|
is_active = Column(Boolean, index=True)
|
||||||
|
is_superuser = Column(Boolean, default=False)
|
||||||
created_unix = Column(Float)
|
created_unix = Column(Float)
|
||||||
updated_unix = Column(Float, default=None)
|
updated_unix = Column(Float, default=None)
|
||||||
last_login_unix = Column(Float, default=None)
|
last_login_unix = Column(Float, default=None)
|
||||||
|
|
||||||
service = relationship("Service", back_populates="user")
|
service = relationship("Service", back_populates="user")
|
||||||
|
|
||||||
|
|
||||||
|
class Metric(Base):
|
||||||
|
__tablename__ = "metric"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
|
service_id = Column(Integer, ForeignKey("service.id"), index=True)
|
||||||
|
request_unix = Column(Float)
|
||||||
|
response_unix = Column(Float)
|
||||||
|
http_response_code = Column(Integer)
|
||||||
|
status = Column(Integer)
|
||||||
|
|
||||||
|
# service = relationship("Service", back_populates="metric")
|
||||||
|
|
||||||
|
6
app/run_tasks.py
Normal file
6
app/run_tasks.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from .tasks import api, metrics
|
||||||
|
import time
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
metrics()
|
||||||
|
# api()
|
14
app/tasks.py
Normal file
14
app/tasks.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import time, asyncio, uvicorn
|
||||||
|
from celery import Celery
|
||||||
|
from celery.schedules import crontab
|
||||||
|
from app.celery import app
|
||||||
|
from app import ultrametrics
|
||||||
|
from app.main import app as statuspage
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def metrics():
|
||||||
|
task = asyncio.create_task(ultrametrics.main())
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def api():
|
||||||
|
task = asyncio.create_task(uvicorn.run(statuspage))
|
@ -1,12 +1,15 @@
|
|||||||
import asyncio, logging, time
|
import asyncio, logging, time, aiohttp
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from typing import Optional, Tuple, Sequence
|
from typing import Optional, Tuple, Sequence
|
||||||
|
from app import crud
|
||||||
|
from app.database import SessionLocal
|
||||||
|
|
||||||
import aiohttp
|
|
||||||
|
|
||||||
logging.basicConfig(format='%(levelname)s:%(message)s', filename='example.log', filemode='w', level=logging.INFO)
|
logging.basicConfig(format='%(levelname)s:%(message)s', filename='example.log', filemode='w', level=logging.INFO)
|
||||||
|
|
||||||
|
db=SessionLocal()
|
||||||
|
|
||||||
URLS = [
|
URLS = [
|
||||||
"https://python.org",
|
"https://python.org",
|
||||||
"https://google.com",
|
"https://google.com",
|
||||||
@ -20,6 +23,7 @@ URLS = [
|
|||||||
'https://testdotya.dotya.ml',
|
'https://testdotya.dotya.ml',
|
||||||
"https://ubuntu.com",
|
"https://ubuntu.com",
|
||||||
]
|
]
|
||||||
|
URL = crud.get_urls(db=db)
|
||||||
|
|
||||||
def start_background_loop(loop: asyncio.AbstractEventLoop) -> None:
|
def start_background_loop(loop: asyncio.AbstractEventLoop) -> None:
|
||||||
asyncio.set_event_loop(loop)
|
asyncio.set_event_loop(loop)
|
||||||
@ -28,6 +32,7 @@ def start_background_loop(loop: asyncio.AbstractEventLoop) -> None:
|
|||||||
|
|
||||||
async def fetch(url: str, session: aiohttp.ClientSession = None) -> Tuple[str, str]:
|
async def fetch(url: str, session: aiohttp.ClientSession = None) -> Tuple[str, str]:
|
||||||
async def _fetch(url: str, session: aiohttp.ClientSession):
|
async def _fetch(url: str, session: aiohttp.ClientSession):
|
||||||
|
URL = crud.get_urls(db=db)
|
||||||
s = time.time()
|
s = time.time()
|
||||||
async with session.head(url) as response:
|
async with session.head(url) as response:
|
||||||
f = time.time() - s
|
f = time.time() - s
|
||||||
@ -45,7 +50,7 @@ async def fetch(url: str, session: aiohttp.ClientSession = None) -> Tuple[str, s
|
|||||||
|
|
||||||
async def fetch_urls(loop: asyncio.AbstractEventLoop) -> Sequence[Tuple[str, str]]:
|
async def fetch_urls(loop: asyncio.AbstractEventLoop) -> Sequence[Tuple[str, str]]:
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
tasks = [loop.create_task(fetch(url, session)) for url in URLS]
|
tasks = [loop.create_task(fetch(url, session)) for url in URL]
|
||||||
results = await asyncio.gather(*tasks)
|
results = await asyncio.gather(*tasks)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
4
nurun.sh
4
nurun.sh
@ -2,4 +2,6 @@
|
|||||||
|
|
||||||
celery worker -A app.celery --loglevel=info &
|
celery worker -A app.celery --loglevel=info &
|
||||||
sleep 5
|
sleep 5
|
||||||
python -m app.run_tasks &
|
|
||||||
|
python -m app.run_tasks
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user