svc-infra 0.1.603__py3-none-any.whl → 0.1.604__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of svc-infra might be problematic. Click here for more details.
- svc_infra/obs/add.py +54 -7
- svc_infra/obs/grafana/dashboards/http-overview.json +45 -0
- {svc_infra-0.1.603.dist-info → svc_infra-0.1.604.dist-info}/METADATA +2 -1
- {svc_infra-0.1.603.dist-info → svc_infra-0.1.604.dist-info}/RECORD +6 -5
- {svc_infra-0.1.603.dist-info → svc_infra-0.1.604.dist-info}/WHEEL +0 -0
- {svc_infra-0.1.603.dist-info → svc_infra-0.1.604.dist-info}/entry_points.txt +0 -0
svc_infra/obs/add.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Any, Callable, Iterable, Optional
|
|
3
|
+
from typing import Any, Callable, Iterable, Optional, Protocol
|
|
4
4
|
|
|
5
5
|
from svc_infra.obs.settings import ObservabilitySettings
|
|
6
6
|
|
|
@@ -9,12 +9,20 @@ def _want_metrics(cfg: ObservabilitySettings) -> bool:
|
|
|
9
9
|
return bool(cfg.METRICS_ENABLED)
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
class RouteClassifier(Protocol):
|
|
13
|
+
def __call__(
|
|
14
|
+
self, route_path: str, method: str
|
|
15
|
+
) -> str: # e.g., returns "public|internal|admin"
|
|
16
|
+
...
|
|
17
|
+
|
|
18
|
+
|
|
12
19
|
def add_observability(
|
|
13
20
|
app: Any | None = None,
|
|
14
21
|
*,
|
|
15
22
|
db_engines: Optional[Iterable[Any]] = None,
|
|
16
23
|
metrics_path: str | None = None,
|
|
17
24
|
skip_metric_paths: Optional[Iterable[str]] = None,
|
|
25
|
+
route_classifier: RouteClassifier | None = None,
|
|
18
26
|
) -> Callable[[], None]:
|
|
19
27
|
"""
|
|
20
28
|
Enable Prometheus metrics for the ASGI app and optional SQLAlchemy pool metrics.
|
|
@@ -25,14 +33,53 @@ def add_observability(
|
|
|
25
33
|
# --- Metrics (Prometheus) — import lazily so CLIs/tests don’t require prometheus_client
|
|
26
34
|
if app is not None and _want_metrics(cfg):
|
|
27
35
|
try:
|
|
28
|
-
from svc_infra.obs.metrics.asgi import
|
|
36
|
+
from svc_infra.obs.metrics.asgi import ( # lazy
|
|
37
|
+
PrometheusMiddleware,
|
|
38
|
+
add_prometheus,
|
|
39
|
+
metrics_endpoint,
|
|
40
|
+
)
|
|
29
41
|
|
|
30
42
|
path = metrics_path or cfg.METRICS_PATH
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
skip_paths = tuple(skip_metric_paths or (path, "/health", "/healthz"))
|
|
44
|
+
# If a route_classifier is provided, use a custom route_resolver to append class label
|
|
45
|
+
if route_classifier is None:
|
|
46
|
+
add_prometheus(
|
|
47
|
+
app,
|
|
48
|
+
path=path,
|
|
49
|
+
skip_paths=skip_paths,
|
|
50
|
+
)
|
|
51
|
+
else:
|
|
52
|
+
# Install middleware manually to pass route_resolver
|
|
53
|
+
def _resolver(req):
|
|
54
|
+
# Base template
|
|
55
|
+
from svc_infra.obs.metrics.asgi import _route_template # type: ignore
|
|
56
|
+
|
|
57
|
+
base = _route_template(req)
|
|
58
|
+
method = getattr(req, "method", "GET")
|
|
59
|
+
cls = route_classifier(base, method)
|
|
60
|
+
# Encode as base|class for downstream label splitting in dashboards
|
|
61
|
+
return f"{base}|{cls}"
|
|
62
|
+
|
|
63
|
+
app.add_middleware(
|
|
64
|
+
PrometheusMiddleware,
|
|
65
|
+
skip_paths=skip_paths,
|
|
66
|
+
route_resolver=_resolver,
|
|
67
|
+
)
|
|
68
|
+
# Mount /metrics endpoint without re-adding middleware
|
|
69
|
+
try:
|
|
70
|
+
from svc_infra.api.fastapi.dual.public import public_router
|
|
71
|
+
from svc_infra.app.env import CURRENT_ENVIRONMENT, DEV_ENV, LOCAL_ENV
|
|
72
|
+
|
|
73
|
+
router = public_router()
|
|
74
|
+
router.add_api_route(
|
|
75
|
+
path,
|
|
76
|
+
endpoint=metrics_endpoint(),
|
|
77
|
+
include_in_schema=CURRENT_ENVIRONMENT in (LOCAL_ENV, DEV_ENV),
|
|
78
|
+
tags=["observability"],
|
|
79
|
+
)
|
|
80
|
+
app.include_router(router)
|
|
81
|
+
except Exception:
|
|
82
|
+
app.add_route(path, metrics_endpoint())
|
|
36
83
|
except Exception:
|
|
37
84
|
pass
|
|
38
85
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Service HTTP Overview",
|
|
3
|
+
"tags": ["svc-infra", "http"],
|
|
4
|
+
"timezone": "browser",
|
|
5
|
+
"panels": [
|
|
6
|
+
{
|
|
7
|
+
"type": "timeseries",
|
|
8
|
+
"title": "Success Rate (5m)",
|
|
9
|
+
"targets": [
|
|
10
|
+
{
|
|
11
|
+
"expr": "sum(rate(http_server_requests_total{code!~\"5..\"}[5m])) / sum(rate(http_server_requests_total[5m]))",
|
|
12
|
+
"legendFormat": "success_rate"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "timeseries",
|
|
18
|
+
"title": "Latency p99",
|
|
19
|
+
"targets": [
|
|
20
|
+
{
|
|
21
|
+
"expr": "histogram_quantile(0.99, sum(rate(http_server_request_duration_seconds_bucket[5m])) by (le))",
|
|
22
|
+
"legendFormat": "p99"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "table",
|
|
28
|
+
"title": "Top Routes by Error (5m)",
|
|
29
|
+
"targets": [
|
|
30
|
+
{
|
|
31
|
+
"expr": "topk(10, sum(rate(http_server_requests_total{code=~\"5..\"}[5m])) by (route))",
|
|
32
|
+
"legendFormat": "{{route}}"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"templating": {
|
|
38
|
+
"list": []
|
|
39
|
+
},
|
|
40
|
+
"time": {
|
|
41
|
+
"from": "now-6h",
|
|
42
|
+
"to": "now"
|
|
43
|
+
},
|
|
44
|
+
"refresh": "30s"
|
|
45
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: svc-infra
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.604
|
|
4
4
|
Summary: Infrastructure for building and deploying prod-ready services
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: fastapi,sqlalchemy,alembic,auth,infra,async,pydantic
|
|
@@ -91,6 +91,7 @@ svc-infra packages the shared building blocks we use to ship production FastAPI
|
|
|
91
91
|
| Jobs | JobQueue, scheduler, CLI worker | [Jobs quickstart](docs/jobs.md) |
|
|
92
92
|
| Cache | cashews decorators, namespace management, TTL helpers | [Cache guide](docs/cache.md) |
|
|
93
93
|
| Observability | Prometheus middleware, Grafana automation, OTEL hooks | [Observability guide](docs/observability.md) |
|
|
94
|
+
| Ops | Probes, breaker, SLOs & dashboards | [SLOs & Ops](docs/ops.md) |
|
|
94
95
|
| Webhooks | Subscription store, signing, retry worker | [Webhooks framework](docs/webhooks.md) |
|
|
95
96
|
| Security | Password policy, lockout, signed cookies, headers | [Security hardening](docs/security.md) |
|
|
96
97
|
| Data Lifecycle | Fixtures, retention, erasure, backups | [Data lifecycle](docs/data-lifecycle.md) |
|
|
@@ -218,8 +218,9 @@ svc_infra/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
218
218
|
svc_infra/mcp/svc_infra_mcp.py,sha256=NmBY7AM3_pnHAumE-eM5Njr8kpb7Gh1-fjcZAEammiI,1927
|
|
219
219
|
svc_infra/obs/README.md,sha256=pmd6AyFZW3GCCi0sr3uTHrPj5KgAI8rrXw8QPkrf1R8,8021
|
|
220
220
|
svc_infra/obs/__init__.py,sha256=t5DgkiuuhHnfAHChzYqCI1-Fpr68iQ0A1nHOLFIlAuM,75
|
|
221
|
-
svc_infra/obs/add.py,sha256=
|
|
221
|
+
svc_infra/obs/add.py,sha256=Qa8pswZDxspIn3oniqe8NYeHmVhFwiYOYxF9xNAyCOs,4016
|
|
222
222
|
svc_infra/obs/cloud_dash.py,sha256=1rg6NO9kjhN3zCugfBqDxkTN5nQqjQRC5ye2gFxb6g4,4329
|
|
223
|
+
svc_infra/obs/grafana/dashboards/http-overview.json,sha256=WVwkMazdfRAAUdLwGItfzePL9sXuDdhlLVbOLtk1Vic,1042
|
|
223
224
|
svc_infra/obs/metrics/__init__.py,sha256=fSqtl2CNV24j13tihK-bsflt0wSSGK8qjxFKvKWBSfk,1421
|
|
224
225
|
svc_infra/obs/metrics/asgi.py,sha256=d9qvOdwJmkIHeB_YV_QcqflXYXYWiriffuqBaaLRbCg,8873
|
|
225
226
|
svc_infra/obs/metrics/base.py,sha256=IHpNJk12whfBEerW9Qkj2fV5Iiw_H-Od4gqPcdOVWNs,2649
|
|
@@ -282,7 +283,7 @@ svc_infra/webhooks/fastapi.py,sha256=BCNvGNxukf6dC2a4i-6en-PrjBGV19YvCWOot5lXWsA
|
|
|
282
283
|
svc_infra/webhooks/router.py,sha256=6JvAVPMEth_xxHX-IsIOcyMgHX7g1H0OVxVXKLuMp9w,1596
|
|
283
284
|
svc_infra/webhooks/service.py,sha256=hWgiJRXKBwKunJOx91C7EcLUkotDtD3Xp0RT6vj2IC0,1797
|
|
284
285
|
svc_infra/webhooks/signing.py,sha256=NCwdZzmravUe7HVIK_uXK0qqf12FG-_MVsgPvOw6lsM,784
|
|
285
|
-
svc_infra-0.1.
|
|
286
|
-
svc_infra-0.1.
|
|
287
|
-
svc_infra-0.1.
|
|
288
|
-
svc_infra-0.1.
|
|
286
|
+
svc_infra-0.1.604.dist-info/METADATA,sha256=MWq8dgYUohrtSAQkZXS6YO0oeH29rMtGqHVlQSOtX9Q,8014
|
|
287
|
+
svc_infra-0.1.604.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
288
|
+
svc_infra-0.1.604.dist-info/entry_points.txt,sha256=6x_nZOsjvn6hRZsMgZLgTasaCSKCgAjsGhACe_CiP0U,48
|
|
289
|
+
svc_infra-0.1.604.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|