Skip to content

Commit 0928fb3

Browse files
committed
feat: add Prometheus metrics support and update Dockerfile for exposure
1 parent 52863a9 commit 0928fb3

6 files changed

Lines changed: 57 additions & 6 deletions

File tree

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ COPY --from=builder --chown=nonroot:nonroot /app/ /app
2222
ENV PATH="/app/.venv/bin:$PATH"
2323
USER nonroot
2424
WORKDIR /app/src
25-
CMD ["python", "-m", "python_response_time.main"]
25+
EXPOSE 8000
26+
CMD ["python", "-m", "python_response_time.main"]

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies = [
99
"coverage>=7.13.5",
1010
"isort>=8.0.1",
1111
"loguru>=0.7.3",
12+
"prometheus-client>=0.24.1",
1213
"pydantic>=2.12.5",
1314
"pydantic-settings>=2.13.1",
1415
"pytest>=9.0.2",

src/python_response_time/core/__init__.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,16 @@
22

33
from python_response_time.core.config import app_settings
44
from python_response_time.core.logging import setup_logger
5+
from python_response_time.core.metrics import (
6+
REQUEST_COUNT,
7+
REQUEST_LATENCY,
8+
start_metrics_server,
9+
)
510

6-
__all__ = ["app_settings", "setup_logger"]
11+
__all__ = [
12+
"app_settings",
13+
"setup_logger",
14+
"start_metrics_server",
15+
"REQUEST_COUNT",
16+
"REQUEST_LATENCY",
17+
]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Core metrics for the application."""
2+
3+
from prometheus_client import Counter, Histogram, start_http_server
4+
5+
REQUEST_COUNT = Counter("http_requests_total", "Total HTTP requests", ["status"])
6+
7+
REQUEST_LATENCY = Histogram(
8+
"http_request_duration_seconds",
9+
"HTTP request latency in seconds",
10+
["status"],
11+
buckets=(0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.25, 0.5, 1, 2, 5),
12+
)
13+
14+
15+
def start_metrics_server(port: int = 8000):
16+
"""Start the Prometheus metrics server."""
17+
start_http_server(port)

src/python_response_time/main.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88
from loguru import logger
99
from rich.console import Console
1010

11-
from python_response_time.core import app_settings, setup_logger
11+
from python_response_time.core import (
12+
REQUEST_COUNT,
13+
REQUEST_LATENCY,
14+
app_settings,
15+
setup_logger,
16+
start_metrics_server,
17+
)
1218

1319
setup_logger(app_settings.LOG_LEVEL)
1420
console = Console()
@@ -67,18 +73,20 @@ def run_app():
6773
timeout=app_settings.TIMEOUT,
6874
verify=app_settings.VERIFY_SSL,
6975
)
70-
elapsed_ms = (time.perf_counter() - start_time) * 1000
76+
elapsed = time.perf_counter() - start_time
7177
console.print(
72-
f"{i + 1:>4} | {response.status_code} | {elapsed_ms:.2f} ms"
78+
f"{i + 1:>4} | {response.status_code} | {elapsed * 1000:.2f} ms"
7379
)
7480
logger.info(
7581
{
7682
"request": i + 1,
7783
"status": response.status_code,
78-
"response_time_ms": elapsed_ms,
84+
"response_time_ms": elapsed * 1000,
7985
"url": str(app_settings.TARGET_URL),
8086
}
8187
)
88+
REQUEST_COUNT.labels(status=str(response.status_code)).inc()
89+
REQUEST_LATENCY.observe(elapsed)
8290
except requests.exceptions.SSLError as e:
8391
console.print(f"{i + 1:>4} | SSL ERROR")
8492
logger.error(
@@ -89,6 +97,7 @@ def run_app():
8997
}
9098
)
9199
except requests.RequestException as e:
100+
REQUEST_COUNT.labels(status="error").inc()
92101
console.print(f"{i + 1:>4} | ERROR")
93102
logger.error(
94103
{
@@ -107,6 +116,7 @@ def run_app():
107116
if __name__ == "__main__":
108117
"""Run the application."""
109118
register_signals()
119+
start_metrics_server(port=8000)
110120
try:
111121
run_app()
112122
except KeyboardInterrupt:

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)