chore: introducing metrics

This commit is contained in:
surtur 2020-08-11 15:02:42 +02:00
parent fad6ab856a
commit d33d8a4c71
Signed by: wanderer
GPG Key ID: 19CE1EC1D9E0486D
7 changed files with 85 additions and 6 deletions

@ -1,10 +1,11 @@
import bcrypt, time
from sqlalchemy.orm import Session
from sqlalchemy.orm import Session, load_only
from app import models, schemas
User=models.User
Service=models.Service
Metric=models.Metric
def get_user(db: Session, user_id: int):
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})
if (updated_user.is_active is not None):
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):
db.query(User).filter(User.id==user_id).update({User.updated_unix: time.time()})
return db.commit()
@ -109,3 +112,25 @@ def login_info(db: Session, name: str, password: str):
return
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()

@ -1,6 +1,7 @@
# vim:fileencoding=utf-8:ft=python:foldmethod=marker
# statuspage/app/main.py
import asyncio
from typing import List, Optional
from fastapi import FastAPI, Depends, Security, HTTPException
@ -8,6 +9,7 @@ from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from app import crud, models, schemas, auth
from app import ultrametrics
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}")
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")
db_user = get_usr(user_id, db)
if db_user is None:
@ -142,3 +144,14 @@ async def validate_token(token: str):
if 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)
password = Column(String)
is_active = Column(Boolean, index=True)
is_superuser = Column(Boolean, default=False)
created_unix = Column(Float)
updated_unix = Column(Float, default=None)
last_login_unix = Column(Float, default=None)
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

@ -0,0 +1,6 @@
from .tasks import api, metrics
import time
if __name__ == '__main__':
metrics()
# api()

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 threading import Thread
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)
db=SessionLocal()
URLS = [
"https://python.org",
"https://google.com",
@ -20,6 +23,7 @@ URLS = [
'https://testdotya.dotya.ml',
"https://ubuntu.com",
]
URL = crud.get_urls(db=db)
def start_background_loop(loop: asyncio.AbstractEventLoop) -> None:
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):
URL = crud.get_urls(db=db)
s = time.time()
async with session.head(url) as response:
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 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)
return results

@ -2,4 +2,6 @@
celery worker -A app.celery --loglevel=info &
sleep 5
python -m app.run_tasks &
python -m app.run_tasks