Skip to content

Commit 8b3ab7c

Browse files
committed
metrics and main
Signed-off-by: rafsaf <rafal.safin12@gmail.com>
1 parent 0d37c0c commit 8b3ab7c

6 files changed

Lines changed: 87 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ There are some **opinionated** default settings in `/app/main.py` for documentat
372372
```python
373373
app = FastAPI(
374374
title="minimal fastapi postgres template",
375-
version="6.1.0",
375+
version="7.0.0",
376376
description="https://github.com/rafsaf/minimal-fastapi-postgres-template",
377377
openapi_url="/openapi.json",
378378
docs_url="/",

app/core/config.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,18 @@ class Database(BaseModel):
4747
db: str = "postgres"
4848

4949

50+
class Prometheus(BaseModel):
51+
enabled: bool = False
52+
port: int = 9090
53+
addr: str = "127.0.0.1"
54+
stop_delay_secs: int = 0
55+
56+
5057
class Settings(BaseSettings):
5158
security: Security = Field(default_factory=Security)
5259
database: Database = Field(default_factory=Database)
60+
prometheus: Prometheus = Field(default_factory=Prometheus)
61+
5362
log_level: str = "INFO"
5463

5564
@computed_field # type: ignore[prop-decorator]

app/core/metrics.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import prometheus_client
2+
3+
NAMESPACE = "org"
4+
SUBSYSTEM = "app"
5+
6+
APP_STARTED = prometheus_client.Counter(
7+
"app_started_total",
8+
"FastAPI application start count",
9+
labelnames=(),
10+
namespace=NAMESPACE,
11+
subsystem=SUBSYSTEM,
12+
)
13+
14+
APP_STOPPED = prometheus_client.Counter(
15+
"app_stopped",
16+
"FastAPI application stop count",
17+
labelnames=(),
18+
namespace=NAMESPACE,
19+
subsystem=SUBSYSTEM,
20+
)

app/main.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,61 @@
1+
import asyncio
2+
import logging
3+
from collections.abc import AsyncGenerator
4+
from contextlib import asynccontextmanager
5+
6+
import prometheus_client
17
from fastapi import FastAPI
28
from fastapi.middleware.cors import CORSMiddleware
39
from fastapi.middleware.trustedhost import TrustedHostMiddleware
410

511
from app.auth.views import router as auth_router
12+
from app.core import database_session, metrics
613
from app.core.config import get_settings
714

15+
logger = logging.getLogger(__name__)
16+
17+
18+
@asynccontextmanager
19+
async def lifespan(_: FastAPI) -> AsyncGenerator[None]:
20+
logger.info("starting application...")
21+
if get_settings().prometheus.enabled:
22+
logger.info(
23+
"starting prometheus client server on interface %s port %d",
24+
get_settings().prometheus.addr,
25+
get_settings().prometheus.port,
26+
)
27+
28+
prometheus_client.start_http_server(
29+
addr=get_settings().prometheus.addr,
30+
port=get_settings().prometheus.port,
31+
)
32+
metrics.APP_STARTED.inc()
33+
34+
yield
35+
36+
logger.info("shutting down application...")
37+
38+
await database_session._ASYNC_ENGINE.dispose()
39+
logger.info("disposed database engine and closed connections...")
40+
41+
if get_settings().prometheus.enabled:
42+
logger.info(
43+
"stopping prometheus with delay of %d seconds...",
44+
get_settings().prometheus.stop_delay_secs,
45+
)
46+
metrics.APP_STOPPED.inc()
47+
await asyncio.sleep(get_settings().prometheus.stop_delay_secs)
48+
49+
logger.info("bye! application shutdown completed")
50+
51+
852
app = FastAPI(
953
title="minimal fastapi postgres template",
1054
version="7.0.0",
1155
description="https://github.com/rafsaf/minimal-fastapi-postgres-template",
1256
openapi_url="/openapi.json",
1357
docs_url="/",
58+
lifespan=lifespan,
1459
)
1560

1661
app.include_router(auth_router, prefix="/auth", tags=["auth"])

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ dependencies = [
55
"asyncpg>=0.31.0",
66
"bcrypt>=5.0.0",
77
"fastapi>=0.128.0",
8+
"prometheus-client>=0.24.1",
89
"pydantic-settings>=2.12.0",
910
"pydantic[email]>=2.12.5",
1011
"pyjwt>=2.11.0",

uv.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)