add health check endpoint

This commit is contained in:
Nexus 2024-04-20 00:55:51 +01:00
parent 38eef0e33e
commit b7a78ba140
Signed by: nex
GPG key ID: 0FA334385D0B689F
2 changed files with 54 additions and 1 deletions

View file

@ -1,7 +1,7 @@
import requests
import json
import logging
import time
import os
import aiohttp
import random
from fastapi import FastAPI, Header, Request, Query, HTTPException
@ -11,6 +11,23 @@ from contextlib import asynccontextmanager
logging.basicConfig(level=logging.INFO)
class Manager:
def __init__(self, api: FastAPI):
self.app = api
self.waiting = 0
def __enter__(self) -> "Manager":
self.waiting += 1
if self.waiting >= 2048:
logging.critical("TCP pool full! %d/2048. Requests are now being backlogged.")
elif self.waiting > 1024:
logging.warning("TCP pool half full! %d/2048.")
return self
def __exit__(self, *args):
self.waiting -= 1
@asynccontextmanager
async def lifespan(_app: FastAPI):
async with aiohttp.ClientSession(
@ -24,6 +41,15 @@ async def lifespan(_app: FastAPI):
app = FastAPI(lifespan=lifespan)
app.state.cache = {}
app.state.meta = Manager(app)
@app.middleware("http")
async def http_middleware(request: Request, call_next):
if app.state.meta.waiting >= 2512:
return JSONResponse({"error": os.urandom(512).decode("latin-1", "replace")}, status_code=503)
with app.state.meta:
return await call_next(request)
async def make_request(ip: str, headers: dict[str, str]) -> dict | HTTPException:
@ -45,6 +71,7 @@ async def make_request(ip: str, headers: dict[str, str]) -> dict | HTTPException
return HTTPException(500, "Failed to get upstream data.")
return data
@app.get("/")
async def ip(
request: Request,
@ -125,3 +152,27 @@ async def im_feeling_lucky(req: Request):
@app.get("/raw")
def get_raw(req: Request):
return PlainTextResponse(req.client.host)
@app.get("/health")
def get_health():
detail = {"issues": []}
if app.state.meta.waiting >= 2048:
detail["status"] = "critical"
detail["issues"].append("(C) Connection pool full.")
elif app.state.meta.waiting >= 1024:
detail["status"] = "warning"
detail["issues"].append("(W) TCP pool half full.")
else:
detail["status"] = "ok"
try:
t = time.perf_counter()
async with app.state.session.get("/") as response:
await response.text()
detail["latency"] = time.perf_counter() - t
except Exception as e:
detail["issues"].append(f"(E) Failed to check upstream: {e}")
detail["status"] = "critical"
return JSONResponse(detail)

2
tox.ini Normal file
View file

@ -0,0 +1,2 @@
[flake8]
max-line-length = 128