Emit a docling_serve.request span per instance attempt
This commit is contained in:
parent
da79f92af1
commit
73ba764922
3 changed files with 40 additions and 2 deletions
|
|
@ -4,6 +4,7 @@
|
|||
### Changed
|
||||
|
||||
- Logfire spans carry `service.version` and a per-process `service.name` (`haiku-ingester`, `haiku-rag`, `haiku-rag-app`); `OTEL_SERVICE_NAME` / `LOGFIRE_SERVICE_NAME` override the default.
|
||||
- Each docling-serve request emits a `docling_serve.request` span carrying the instance `url` and `attempt`.
|
||||
|
||||
## [0.65.0] - 2026-07-09
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import httpx
|
|||
|
||||
from haiku.rag.circuit_breaker import CircuitBreaker
|
||||
from haiku.rag.config import CircuitBreakerConfig, DoclingServeConfig
|
||||
from haiku.rag.telemetry import logfire
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -156,8 +157,14 @@ class DoclingServeClient:
|
|||
base_url = self._pick_url(exclude=frozenset(tried))
|
||||
breaker = self._breaker_for(base_url)
|
||||
try:
|
||||
async with self._httpx_client() as client:
|
||||
result = await attempt(client, base_url)
|
||||
with logfire.span(
|
||||
"docling_serve.request",
|
||||
name=name,
|
||||
url=base_url,
|
||||
attempt=attempt_no,
|
||||
):
|
||||
async with self._httpx_client() as client:
|
||||
result = await attempt(client, base_url)
|
||||
except Exception as exc:
|
||||
if not _is_retryable(exc):
|
||||
raise
|
||||
|
|
|
|||
|
|
@ -301,6 +301,36 @@ async def test_task_failure_is_not_retried():
|
|||
assert set(seen) == {"h"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_request_span_records_instance_per_attempt(monkeypatch):
|
||||
"""Each attempt opens a docling_serve.request span tagged with the
|
||||
instance URL, so failover is traceable in Logfire."""
|
||||
from contextlib import nullcontext
|
||||
|
||||
from haiku.rag.providers import docling_serve as ds_module
|
||||
|
||||
spans: list[dict] = []
|
||||
|
||||
def _fake_span(span_name, /, **attrs):
|
||||
spans.append({"span_name": span_name, **attrs})
|
||||
return nullcontext()
|
||||
|
||||
monkeypatch.setattr(ds_module.logfire, "span", _fake_span)
|
||||
|
||||
transport, _ = _failover_transport({"down-s"}, "t", {"ok": True})
|
||||
client = DoclingServeClient(
|
||||
base_urls=["http://down-s:5001", "http://up-s:5001"],
|
||||
transport=transport,
|
||||
retry_base_delay=0.0,
|
||||
)
|
||||
|
||||
await _poll(client)
|
||||
|
||||
requests = [s for s in spans if s["span_name"] == "docling_serve.request"]
|
||||
assert [s["url"] for s in requests] == ["http://down-s:5001", "http://up-s:5001"]
|
||||
assert [s["attempt"] for s in requests] == [0, 1]
|
||||
|
||||
|
||||
def test_pick_url_skips_excluded_instances():
|
||||
"""On retry, _pick_url advances past every excluded instance."""
|
||||
urls = ["http://p1:5001", "http://p2:5001", "http://p3:5001"]
|
||||
|
|
|
|||
Loading…
Reference in a new issue