Skip to content

Commit

Permalink
feat: add profiler to calculate route execution time (#1020)
Browse files Browse the repository at this point in the history
* build: add pyinstrument to debug dep group

* feat: add route profiler in debug mode
  • Loading branch information
spwoodcock authored Nov 29, 2023
1 parent 60b9a82 commit a8f705d
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 15 deletions.
47 changes: 33 additions & 14 deletions src/backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,23 @@
from fastapi import FastAPI, Request
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse, RedirectResponse
from loguru import logger as log
from osm_fieldwork.xlsforms import xlsforms_path

from .__version__ import __version__
from .auth import auth_routes
from .central import central_routes
from .config import settings
from .db.database import get_db
from .organization import organization_routes
from .projects import project_routes
from .projects.project_crud import read_xlsforms
from .submission import submission_routes
from .tasks import tasks_routes
from .users import user_routes

from app.__version__ import __version__
from app.auth import auth_routes
from app.central import central_routes
from app.config import settings
from app.db.database import get_db
from app.organization import organization_routes
from app.projects import project_routes
from app.projects.project_crud import read_xlsforms
from app.submission import submission_routes
from app.tasks import tasks_routes
from app.users import user_routes

# Add sentry tracing only in prod
if not settings.DEBUG:
sentry_sdk.init(
dsn=settings.SENTRY_DSN,
Expand All @@ -51,7 +52,7 @@

@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup events
"""Startup events."""
log.debug("Starting up FastAPI server.")
log.debug("Reading XLSForms from DB.")
await read_xlsforms(next(get_db()), xlsforms_path)
Expand Down Expand Up @@ -165,6 +166,24 @@ def get_logger():
api = get_application()


# Add endpoint profiler to check for bottlenecks
if settings.DEBUG:
from pyinstrument import Profiler

@api.middleware("http")
async def profile_request(request: Request, call_next):
"""Calculate the execution time for routes."""
profiling = request.query_params.get("profile", False)
if profiling:
profiler = Profiler(interval=0.001, async_mode="enabled")
profiler.start()
await call_next(request)
profiler.stop()
return HTMLResponse(profiler.output_html())
else:
return await call_next(request)


@api.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""Exception handler for more descriptive logging."""
Expand Down
31 changes: 30 additions & 1 deletion src/backend/pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ test = [
debug = [
"ipdb>=0.13.13",
"debugpy>=1.6.7.post1",
"pyinstrument>=4.6.1",
]
docs = [
"mkdocs>=1.5.2",
Expand Down

0 comments on commit a8f705d

Please sign in to comment.