feat(observability): structured logging, metrics wiring, graceful degradation
- Item 5: Convert remaining printf-style logger call to structured logging (key=value format) in x402_middleware.py - Item 6: Wire CACHE_HITS counter into cache get() and per-tier SCRAPE_LATENCY histogram into UltimateScraper scrape loop - Item 7: Add circuit-breaker checks in extractor.py (Ollama) and routers/vision.py (OpenRouter) to fail fast and record success/failure when external services are down; attach recovery results to resilience registry for per-service circuit state 560 tests passing, ruff clean
This commit is contained in:
parent
2970c15dbb
commit
5a21133b1d
5 changed files with 20 additions and 1 deletions
|
|
@ -19,6 +19,7 @@ from fastapi import APIRouter, Body
|
|||
from client import get_client
|
||||
from deps import automator
|
||||
from errors import ExternalServiceError, InvalidRequestError, PryError, ScrapeError
|
||||
from resilience import registry
|
||||
from settings import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -171,6 +172,8 @@ async def _call_vision_api(
|
|||
key = _get_or_key()
|
||||
if not key:
|
||||
return None, None, "OPENROUTER_API_KEY not set"
|
||||
if not registry.is_service_allowed("openrouter"):
|
||||
return None, None, "OpenRouter circuit breaker open"
|
||||
|
||||
# Accept either data URI or raw base64
|
||||
data_uri = image_b64 if image_b64.startswith("data:") else f"data:image/png;base64,{image_b64}"
|
||||
|
|
@ -203,6 +206,7 @@ async def _call_vision_api(
|
|||
)
|
||||
resp.raise_for_status()
|
||||
body = resp.json()
|
||||
registry.record_service_result("openrouter", True)
|
||||
return body["choices"][0]["message"]["content"], model, None
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue