Skip to content

Commit

Permalink
perf: Add profiling option for backend routes
Browse files Browse the repository at this point in the history
It produces a HTML report to better identify slow actions in routes.
  • Loading branch information
MoritzWeber0 committed Nov 7, 2024
1 parent 3c5c1fd commit ed34a99
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 0 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ repos:
- types-lxml
- cryptography
- types-croniter
- pyinstrument
- repo: local
hooks:
- id: pylint
Expand Down
16 changes: 16 additions & 0 deletions backend/capellacollab/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,22 @@ async def shutdown():
)


if config.logging.profiling:
import pyinstrument

Check warning on line 97 in backend/capellacollab/__main__.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/__main__.py#L97

Added line #L97 was not covered by tests

@app.middleware("http")
async def profile_request(request: fastapi.Request, call_next):
profiling = request.query_params.get("profile", False)

Check warning on line 101 in backend/capellacollab/__main__.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/__main__.py#L99-L101

Added lines #L99 - L101 were not covered by tests
if profiling:
profiler = pyinstrument.Profiler(async_mode="enabled")
profiler.start()
await call_next(request)
profiler.stop()
return responses.HTMLResponse(profiler.output_html())

Check warning on line 107 in backend/capellacollab/__main__.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/__main__.py#L103-L107

Added lines #L103 - L107 were not covered by tests
else:
return await call_next(request)

Check warning on line 109 in backend/capellacollab/__main__.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/__main__.py#L109

Added line #L109 was not covered by tests


@app.get(
"/docs", response_class=responses.RedirectResponse, include_in_schema=False
)
Expand Down
4 changes: 4 additions & 0 deletions backend/capellacollab/config/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ class LoggingConfig(BaseConfig):
description="The path to the log file (saved as 'backend.log').",
examples=["logs/"],
)
profiling: bool = pydantic.Field(
default=False,
description="Enable profiling of requests.",
)


class RequestsConfig(BaseConfig):
Expand Down
1 change: 1 addition & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ dev = [
"aioresponses",
"types-lxml",
"types-croniter",
"pyinstrument",
]

[tool.black]
Expand Down
38 changes: 38 additions & 0 deletions docs/docs/development/backend/profiling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!--
~ SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
~ SPDX-License-Identifier: Apache-2.0
-->

# Profile Backend Routes

Profiling can be useful if you want to examine the performance of specific
backend routes.

## Enable profiling

In the `config.yaml`, set the `logging.profiling` key to `True`. Then, call the
route you want to profile with the `profile` query parameter set to `True`.

For example, to profile the `/api/v1/metadata` route, you would call
`/api/v1/metadata?profile=True` in the browser. It will return a HTML report.

!!! info

Synchronous routes are not supported properly. If you want to profile a
synchronous route, add `async` to the route definition.

```
@router.get(...)
def metadata():
...
```

becomes

```
@router.get(...)
async def metadata():
...
```

[More Information on GitHub](https://github.com/joerick/pyinstrument/issues/257)
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ nav:
- Introduction: development/index.md
- Backend:
- Code Style: development/backend/code-style.md
- Profiling: development/backend/profiling.md
- Technology Overview: development/backend/technology.md
- Extension Modules: development/backend/extensions.md
- Exception Handling: development/backend/exception.md
Expand Down

0 comments on commit ed34a99

Please sign in to comment.