refactor(observability): restructure into service-owned packages

This commit is contained in:
2026-09-22 17:19:57 +03:30
parent d2a678264e
commit 98fa1f6441
15 changed files with 369 additions and 87 deletions

View File

@@ -1,21 +1,18 @@
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.responses import JSONResponse, Response
from prometheus_client import CONTENT_TYPE_LATEST
from core.api.kafka_publisher import KafkaPublisher
from core.api.publisher import Publisher
from core.api.routes import router
from core.config import get_settings
from core.api.metrics import ApiMetrics
from core.api.stats import (
from core.api.observability.metrics import ApiMetrics
from core.api.observability.routes import create_observability_router
from core.api.observability.stats import (
ApiRuntimeStats,
HttpWorkerStatsClient,
WorkerStatsProvider,
WorkerStatsUnavailable,
)
from core.api.publisher import Publisher
from core.api.routes import router
from core.config import get_settings
def create_app(
@@ -27,6 +24,15 @@ def create_app(
api_metrics = ApiMetrics()
api_stats = ApiRuntimeStats()
active_worker_stats_client = (
worker_stats_client
if worker_stats_client is not None
else HttpWorkerStatsClient(
url=settings.worker_stats_url,
timeout_seconds=settings.worker_stats_timeout_seconds,
)
)
@asynccontextmanager
async def lifespan(app: FastAPI):
active_publisher = publisher
@@ -36,20 +42,6 @@ def create_app(
settings
)
active_worker_stats_client = (
worker_stats_client
)
if active_worker_stats_client is None:
active_worker_stats_client = (
HttpWorkerStatsClient(
url=settings.worker_stats_url,
timeout_seconds=(
settings.worker_stats_timeout_seconds
),
)
)
app.state.publisher = active_publisher
app.state.worker_stats_client = (
@@ -75,73 +67,27 @@ def create_app(
app.state.api_metrics = api_metrics
app.state.api_stats = api_stats
observability_router = create_observability_router(
metrics=api_metrics,
stats=api_stats,
worker_stats_provider=active_worker_stats_client,
)
app.include_router(
router,
prefix="/api/v1",
)
app.include_router(
observability_router,
)
@app.get("/health")
async def health() -> dict[str, str]:
return {
"status": "ok",
}
@app.get(
"/metrics",
include_in_schema=False,
)
async def metrics() -> Response:
return Response(
content=api_metrics.render(),
media_type=CONTENT_TYPE_LATEST,
)
@app.get("/stats")
async def stats():
try:
worker_stats = await (
app.state
.worker_stats_client
.get_stats()
)
except WorkerStatsUnavailable as exc:
return JSONResponse(
status_code=503,
content={
"error": "worker_stats_unavailable",
"detail": str(exc),
},
)
api_snapshot = api_stats.snapshot()
worker_pipeline = (
worker_stats["pipeline"]
)
return {
"pipeline": {
"total_received":
api_snapshot["total_received"],
"total_processed":
worker_pipeline["total_processed"],
"total_dlq":
worker_pipeline["total_dlq"],
"in_flight_buffer":
worker_pipeline["in_flight_buffer"],
"last_flush_at":
worker_pipeline["last_flush_at"],
},
"breakdown":
worker_stats["breakdown"],
}
return app