diff --git a/changelog.d/fixes/15248-proxy-health-slow-abandoned.md b/changelog.d/fixes/15248-proxy-health-slow-abandoned.md
new file mode 100644
index 000000000000..8c35890e0d15
--- /dev/null
+++ b/changelog.d/fixes/15248-proxy-health-slow-abandoned.md
@@ -0,0 +1 @@
+- **fix(dashboard):** proxy health now reports headers-wait abandonments and client aborts as separate counters instead of transport failures ([#15248](https://github.com/diegosouzapw/OmniRoute/pull/15248)) — thanks @maxmad64bis
diff --git a/src/app/(dashboard)/dashboard/settings/components/ProxyHealthCell.tsx b/src/app/(dashboard)/dashboard/settings/components/ProxyHealthCell.tsx
index b90001e83ffb..69df003dd2c3 100644
--- a/src/app/(dashboard)/dashboard/settings/components/ProxyHealthCell.tsx
+++ b/src/app/(dashboard)/dashboard/settings/components/ProxyHealthCell.tsx
@@ -18,6 +18,8 @@ interface HealthInfo {
measured?: boolean;
transportOk?: number;
transportFailures?: number;
+ slowAbandoned?: number;
+ clientAborted?: number;
upstream4xx?: number;
upstream5xx?: number;
connectionTests?: number;
@@ -91,6 +93,10 @@ export function ProxyHealthCell({ testResult, health }: ProxyHealthCellProps) {
? t("notMeasured")
: t("transportRate", { rate: health.transportRate ?? 0 })}
+
+ {t("slowAbandoned", { count: health.slowAbandoned ?? 0 })}
+
+ {t("clientAborted", { count: health.clientAborted ?? 0 })}
{t("upstreamRefusals", { count: upstreamRefusals })}
{t("connectionTestsCount", { count: health.connectionTests ?? 0 })}
{t("avgLatency", { latency: health.avgLatencyMs ?? "-" })}
diff --git a/src/app/(dashboard)/dashboard/settings/components/proxyRegistryConstants.ts b/src/app/(dashboard)/dashboard/settings/components/proxyRegistryConstants.ts
index 1d9ecce75257..807e9a05db37 100644
--- a/src/app/(dashboard)/dashboard/settings/components/proxyRegistryConstants.ts
+++ b/src/app/(dashboard)/dashboard/settings/components/proxyRegistryConstants.ts
@@ -17,6 +17,8 @@ export type HealthInfo = {
measured: boolean;
transportOk: number;
transportFailures: number;
+ slowAbandoned: number;
+ clientAborted: number;
upstream4xx: number;
upstream5xx: number;
connectionTests: number;
diff --git a/src/i18n/messages/am.json b/src/i18n/messages/am.json
index 95d503a47101..d2bfe117ea5d 100644
--- a/src/i18n/messages/am.json
+++ b/src/i18n/messages/am.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "የአቀማመጥ ቅደም ተከተል",
"poolHealthRankingOff": "የጤና ደረጃ አሰጣጥ ጠፍቷል",
"transportRate": "{rate}% ትራንስፖርት",
+ "slowAbandoned": "{count} በቀስታ የሚተው ልውውጥ",
+ "clientAborted": "{count} የደንበኛ ማቆም",
+ "slowAbandonedHint": "የራስ ምልክቶች የመጠባበቅ ኪስ በላይ በኋላ ተተው, ከመጓጓዣ ፍጥነት ውጭ ተሰርዘዋል",
"previousSuccessRate": "ከዚህ በፊት {rate}% ስኬት",
"upstreamRefusals": "{count} upstream ውድቅዎች",
"connectionTestsCount": "{count} የግንኙነት ሙከራዎች",
diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json
index 5eb2e3066d39..15cb6a325106 100644
--- a/src/i18n/messages/ar.json
+++ b/src/i18n/messages/ar.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "ترتيب المواضع",
"poolHealthRankingOff": "ترتيب الصحة متوقف",
"transportRate": "{rate}% نقل",
+ "slowAbandoned": "{count} عمليات تخلٍّ بطيئة",
+ "clientAborted": "{count} عمليات إلغاء من العميل",
+ "slowAbandonedHint": "تم التخلي بعد عتبة انتظار الترويسات، مستبعد من معدل النقل",
"previousSuccessRate": "سابقًا {rate}% نجاح",
"upstreamRefusals": "{count} رفضًا من الخادم الأعلى",
"connectionTestsCount": "{count} اختبارات اتصال",
diff --git a/src/i18n/messages/az.json b/src/i18n/messages/az.json
index 06758ace65d4..a8cf0056f16d 100644
--- a/src/i18n/messages/az.json
+++ b/src/i18n/messages/az.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Mövqe sırası",
"poolHealthRankingOff": "Sağlamlıq reytinqi kapalı",
"transportRate": "{rate}% nəqliyyat",
+ "slowAbandoned": "{count} yavaş tərk etmələr",
+ "clientAborted": "{count} müştəri ləğv etmələri",
+ "slowAbandonedHint": "Başlıqların gözləmə həddindən sonra tərk edildi, daşınma dərəcəsindən çıxarılıb",
"previousSuccessRate": "Əvvəlcə {rate}% uğur",
"upstreamRefusals": "{count} upstream rəddi",
"connectionTestsCount": "{count} bağlantı testi",
diff --git a/src/i18n/messages/bg.json b/src/i18n/messages/bg.json
index af6ff3bd81ac..ff5c5719f131 100644
--- a/src/i18n/messages/bg.json
+++ b/src/i18n/messages/bg.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ред на позициите",
"poolHealthRankingOff": "Класирането по здраве е изключено",
"transportRate": "{rate}% транспорт",
+ "slowAbandoned": "{count} бавни изоставяния",
+ "clientAborted": "{count} прекъсвания от клиента",
+ "slowAbandonedHint": "Изоставено след прага на изчакване на хедърите, изключено от транспортната скорост",
"previousSuccessRate": "Преди {rate}% успех",
"upstreamRefusals": "{count} отказа от upstream",
"connectionTestsCount": "{count} теста на връзката",
diff --git a/src/i18n/messages/bn.json b/src/i18n/messages/bn.json
index 6008143ca4f0..d591ba679a64 100644
--- a/src/i18n/messages/bn.json
+++ b/src/i18n/messages/bn.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "অবস্থান ক্রম",
"poolHealthRankingOff": "স্বাস্থ্য র্যাঙ্কিং বন্ধ",
"transportRate": "{rate}% ট্রান্সপোর্ট",
+ "slowAbandoned": "{count} ধীর ত্যাগ",
+ "clientAborted": "{count} ক্লায়েন্ট বাতিল",
+ "slowAbandonedHint": "হেডার অপেক্ষা থ্রেশহোল্ডের পরে ত্যাগ করা হয়েছে, ট্রান্সপোর্ট রেট থেকে বাদ দেওয়া হয়েছে",
"previousSuccessRate": "পূর্বে {rate}% সাফল্য",
"upstreamRefusals": "{count} আপস্ট্রিম প্রত্যাখ্যান",
"connectionTestsCount": "{count} সংযোগ পরীক্ষা",
diff --git a/src/i18n/messages/bs.json b/src/i18n/messages/bs.json
index b03eaa35f35d..7efbb22e371c 100644
--- a/src/i18n/messages/bs.json
+++ b/src/i18n/messages/bs.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Redoslijed pozicija",
"poolHealthRankingOff": "Rangiranje zdravlja isključeno",
"transportRate": "{rate} % transporta",
+ "slowAbandoned": "{count} sporih napuštanja",
+ "clientAborted": "{count} klijentskih prekida",
+ "slowAbandonedHint": "Napušteno nakon praga čekanja zaglavlja, isključeno iz stope prijenosa",
"previousSuccessRate": "Ranije {rate} % uspjeha",
"upstreamRefusals": "{count} upstream odbijanja",
"connectionTestsCount": "{count} testova konekcije",
diff --git a/src/i18n/messages/cs.json b/src/i18n/messages/cs.json
index b42dfe40f850..7a40012190cb 100644
--- a/src/i18n/messages/cs.json
+++ b/src/i18n/messages/cs.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Pořadí pozic",
"poolHealthRankingOff": "Hodnocení zdraví vypnuto",
"transportRate": "{rate} % přenosu",
+ "slowAbandoned": "{count} pomalých opuštění",
+ "clientAborted": "{count} přerušení klienta",
+ "slowAbandonedHint": "Opuštěno po překročení prahu čekání na hlavičky, vyloučeno z transportní míry",
"previousSuccessRate": "Dříve {rate} % úspěšnost",
"upstreamRefusals": "{count} odmítnutí upstream",
"connectionTestsCount": "{count} testů připojení",
diff --git a/src/i18n/messages/da.json b/src/i18n/messages/da.json
index 964e6672f805..e265c48f9748 100644
--- a/src/i18n/messages/da.json
+++ b/src/i18n/messages/da.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Positionsrækkefølge",
"poolHealthRankingOff": "Sundhedsrangering fra",
"transportRate": "{rate} % transport",
+ "slowAbandoned": "{count} langsomme opgivelser",
+ "clientAborted": "{count} klientafbrydelser",
+ "slowAbandonedHint": "Opgivet efter headerventetærsklen, udelukket fra transporthastigheden",
"previousSuccessRate": "Tidligere {rate} % succes",
"upstreamRefusals": "{count} upstream-afvisninger",
"connectionTestsCount": "{count} forbindelsestests",
diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json
index 2410cdf3aebc..2c5cfa7bc1fb 100644
--- a/src/i18n/messages/de.json
+++ b/src/i18n/messages/de.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Positionsreihenfolge",
"poolHealthRankingOff": "Health-Ranking aus",
"transportRate": "{rate} % Transport",
+ "slowAbandoned": "{count} langsame Abbrüche",
+ "clientAborted": "{count} Client-Abbrüche",
+ "slowAbandonedHint": "Nach Erreichen der Wartezeit‑Grenze für Header abgebrochen, aus der Transportrate ausgeschlossen",
"previousSuccessRate": "Zuvor {rate} % Erfolg",
"upstreamRefusals": "{count} Upstream-Ablehnungen",
"connectionTestsCount": "{count} Verbindungstests",
diff --git a/src/i18n/messages/el.json b/src/i18n/messages/el.json
index 31e4d1ac470c..0bc9a093a8b2 100644
--- a/src/i18n/messages/el.json
+++ b/src/i18n/messages/el.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Σειρά θέσης",
"poolHealthRankingOff": "Η κατάταξη υγείας απενεργοποιημένη",
"transportRate": "{rate} % μεταφορά",
+ "slowAbandoned": "{count} αργές εγκαταλείψεις",
+ "clientAborted": "{count} διακοπές πελάτη",
+ "slowAbandonedHint": "Εγκαταλείφθηκε μετά το όριο αναμονής επικεφαλίδων, εξαιρείται από το ποσοστό μεταφοράς",
"previousSuccessRate": "Προηγουμένως {rate} % επιτυχία",
"upstreamRefusals": "{count} απορρίψεις upstream",
"connectionTestsCount": "{count} δοκιμές σύνδεσης",
diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json
index 09c72e0c4715..3dc2c29ef596 100644
--- a/src/i18n/messages/en.json
+++ b/src/i18n/messages/en.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Position order",
"poolHealthRankingOff": "Health ranking off",
"transportRate": "{rate}% transport",
+ "slowAbandoned": "{count} slow abandonments",
+ "clientAborted": "{count} client aborts",
+ "slowAbandonedHint": "Abandoned after the headers wait threshold, excluded from the transport rate",
"previousSuccessRate": "Previously {rate}% success",
"upstreamRefusals": "{count} upstream refusals",
"connectionTestsCount": "{count} connection tests",
diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json
index af222a2bdbd3..f12490016db9 100644
--- a/src/i18n/messages/es.json
+++ b/src/i18n/messages/es.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Orden de posición",
"poolHealthRankingOff": "Clasificación de salud desactivada",
"transportRate": "{rate} % transporte",
+ "slowAbandoned": "{count} abandonos lentos",
+ "clientAborted": "{count} abortos de cliente",
+ "slowAbandonedHint": "Abandonado tras el umbral de espera de encabezados, excluido de la tasa de transporte",
"previousSuccessRate": "Anteriormente {rate} % de éxito",
"upstreamRefusals": "{count} rechazos aguas arriba",
"connectionTestsCount": "{count} pruebas de conexión",
diff --git a/src/i18n/messages/et.json b/src/i18n/messages/et.json
index a97c01eefcd0..4bfd9a270d41 100644
--- a/src/i18n/messages/et.json
+++ b/src/i18n/messages/et.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Positsioonijärjekord",
"poolHealthRankingOff": "Tervise järjestus väljas",
"transportRate": "{rate} % transporti",
+ "slowAbandoned": "{count} aeglased katkestused",
+ "clientAborted": "{count} kliendi katkestused",
+ "slowAbandonedHint": "Katkestatud pärast päiste oote läve ületamist, transpordimäärast välja arvatud",
"previousSuccessRate": "Varem {rate} % edukust",
"upstreamRefusals": "{count} upstream-keeldumist",
"connectionTestsCount": "{count} ühenduse testi",
diff --git a/src/i18n/messages/fa.json b/src/i18n/messages/fa.json
index 8a03c7150f9e..917a87312c30 100644
--- a/src/i18n/messages/fa.json
+++ b/src/i18n/messages/fa.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "ترتیب موقعیت",
"poolHealthRankingOff": "رتبهبندی سلامت خاموش",
"transportRate": "{rate}٪ انتقال",
+ "slowAbandoned": "{count} رها کردنهای کند",
+ "clientAborted": "{count} لغو کردنهای مشتری",
+ "slowAbandonedHint": "پس از گذشت زمان انتظار هدرها، رها شد و از نرخ انتقال حذف گردید.",
"previousSuccessRate": "قبلاً {rate}٪ موفقیت",
"upstreamRefusals": "{count} رد بالادستی",
"connectionTestsCount": "{count} آزمون اتصال",
diff --git a/src/i18n/messages/fi.json b/src/i18n/messages/fi.json
index d808cde455ab..c24ee8c0e44a 100644
--- a/src/i18n/messages/fi.json
+++ b/src/i18n/messages/fi.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Sijaintijärjestys",
"poolHealthRankingOff": "Terveysjärjestys pois päältä",
"transportRate": "{rate} % siirtoa",
+ "slowAbandoned": "{count} hidasta keskeytystä",
+ "clientAborted": "{count} asiakkaan keskeytystä",
+ "slowAbandonedHint": "Keskeytetty otsikoiden odotusajan rajan jälkeen, ei huomioida kuljetusnopeudessa",
"previousSuccessRate": "Aiemmin {rate} % onnistumisia",
"upstreamRefusals": "{count} upstream-hylkäystä",
"connectionTestsCount": "{count} yhteystestiä",
diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json
index 215e1bdd2c62..e7bc95378c2f 100644
--- a/src/i18n/messages/fr.json
+++ b/src/i18n/messages/fr.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ordre de position",
"poolHealthRankingOff": "Classement de santé désactivé",
"transportRate": "{rate} % transport",
+ "slowAbandoned": "{count} abandons lents",
+ "clientAborted": "{count} annulations par le client",
+ "slowAbandonedHint": "Abandonné après dépassement du délai d'attente des en-têtes, exclu du taux de transport",
"previousSuccessRate": "Précédemment {rate} % de réussite",
"upstreamRefusals": "{count} refus en amont",
"connectionTestsCount": "{count} tests de connexion",
diff --git a/src/i18n/messages/ga.json b/src/i18n/messages/ga.json
index 5c647c4b6bcd..e57f98a5a575 100644
--- a/src/i18n/messages/ga.json
+++ b/src/i18n/messages/ga.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ord suímh",
"poolHealthRankingOff": "Rangú sláinte múchta",
"transportRate": "{rate}% iompair",
+ "slowAbandoned": "{count} tréigtheann malla",
+ "clientAborted": "{count} cliant ag scor",
+ "slowAbandonedHint": "Tréigthe tar éis an tairseach fanadh ceannteideal, eisiata ón ráta iompair",
"previousSuccessRate": "Roimhe seo {rate}% rath",
"upstreamRefusals": "{count} diúltú in aghaidh srutha",
"connectionTestsCount": "{count} tástáil nasctha",
diff --git a/src/i18n/messages/gu.json b/src/i18n/messages/gu.json
index bcb5e74ad306..8cf7eb354850 100644
--- a/src/i18n/messages/gu.json
+++ b/src/i18n/messages/gu.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "સ્થાન ક્રમ",
"poolHealthRankingOff": "આરોગ્ય રેન્કિંગ બંધ",
"transportRate": "{rate}% ટ્રાન્સપોર્ટ",
+ "slowAbandoned": "{count} ધીમી છોડી દેવાની ઘટનાઓ",
+ "clientAborted": "{count} ક્લાયન્ટ દ્વારા રદ કરવામાં આવેલી ઘટનાઓ",
+ "slowAbandonedHint": "હેડર્સની રાહ જોવાની સીમા પછી છોડી દેવામાં આવી, ટ્રાન્સપોર્ટ રેટમાંથી બાકાત કરવામાં આવી",
"previousSuccessRate": "અગાઉ {rate}% સફળતા",
"upstreamRefusals": "{count} અપસ્ટ્રીમ અસ્વીકાર",
"connectionTestsCount": "{count} કનેક્શન પરીક્ષણો",
diff --git a/src/i18n/messages/ha.json b/src/i18n/messages/ha.json
index 177ae7803a6c..ba512d58e3fb 100644
--- a/src/i18n/messages/ha.json
+++ b/src/i18n/messages/ha.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Tsarin matsayi",
"poolHealthRankingOff": "Matsayin lafiya a kashe",
"transportRate": "{rate}% sufuri",
+ "slowAbandoned": "{count} mashiya waɗaɗa",
+ "clientAborted": "{count} mashiya aborts",
+ "slowAbandonedHint": "An abandoned after the headers wait threshold, excluded from the transport rate",
"previousSuccessRate": "A baya {rate}% nasara",
"upstreamRefusals": "{count} kin amincewa daga sama",
"connectionTestsCount": "{count} gwaje-gwajen haɗi",
diff --git a/src/i18n/messages/he.json b/src/i18n/messages/he.json
index 2fdcbfa5e502..aceb4bf333c3 100644
--- a/src/i18n/messages/he.json
+++ b/src/i18n/messages/he.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "סדר מיקומים",
"poolHealthRankingOff": "דירוג בריאות כבוי",
"transportRate": "{rate}% תעבורה",
+ "slowAbandoned": "{count} נטישות איטיות",
+ "clientAborted": "{count} ביטולים על ידי הלקוח",
+ "slowAbandonedHint": "ננטש לאחר חריגה מסף ההמתנה לכותרות, לא נכלל בחישוב קצב ההובלה",
"previousSuccessRate": "בעבר {rate}% הצלחה",
"upstreamRefusals": "{count} דחיות upstream",
"connectionTestsCount": "{count} בדיקות חיבור",
diff --git a/src/i18n/messages/hi.json b/src/i18n/messages/hi.json
index 80ee9e065554..4a0de7826db1 100644
--- a/src/i18n/messages/hi.json
+++ b/src/i18n/messages/hi.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "स्थिति क्रम",
"poolHealthRankingOff": "स्वास्थ्य रैंकिंग बंद",
"transportRate": "{rate}% ट्रांसपोर्ट",
+ "slowAbandoned": "{count} धीमी परित्यागें",
+ "clientAborted": "{count} क्लाइंट रद्दीकरण",
+ "slowAbandonedHint": "हेडर प्रतीक्षा सीमा के बाद परित्यक्त, परिवहन दर से बाहर रखा गया",
"previousSuccessRate": "पहले {rate}% सफलता",
"upstreamRefusals": "{count} अपस्ट्रीम अस्वीकृतियाँ",
"connectionTestsCount": "{count} कनेक्शन परीक्षण",
diff --git a/src/i18n/messages/hr.json b/src/i18n/messages/hr.json
index 3bab8444c9a0..44c109ed13f6 100644
--- a/src/i18n/messages/hr.json
+++ b/src/i18n/messages/hr.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Redoslijed pozicija",
"poolHealthRankingOff": "Rangiranje zdravlja isključeno",
"transportRate": "{rate} % prijenosa",
+ "slowAbandoned": "{count} sporih odustajanja",
+ "clientAborted": "{count} odustajanja klijenta",
+ "slowAbandonedHint": "Opušteno nakon prag čekanja zaglavlja, isključeno iz transportne stope",
"previousSuccessRate": "Prije {rate} % uspjeha",
"upstreamRefusals": "{count} upstream odbijanja",
"connectionTestsCount": "{count} testova veze",
diff --git a/src/i18n/messages/hu.json b/src/i18n/messages/hu.json
index 90b061ff08fd..7f7df45acca4 100644
--- a/src/i18n/messages/hu.json
+++ b/src/i18n/messages/hu.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Pozíciósorrend",
"poolHealthRankingOff": "Állapot-rangsorolás kikapcsolva",
"transportRate": "{rate}% átvitel",
+ "slowAbandoned": "{count} lassú elhagyás",
+ "clientAborted": "{count} kliens által megszakítva",
+ "slowAbandonedHint": "A fejlécek várakozási időkorlát után elhagyva, kizárva a szállítási sebességből",
"previousSuccessRate": "Korábban {rate}% siker",
"upstreamRefusals": "{count} upstream-elutasítás",
"connectionTestsCount": "{count} kapcsolati teszt",
diff --git a/src/i18n/messages/hy.json b/src/i18n/messages/hy.json
index 8ccfa89521a6..20cf3a125d56 100644
--- a/src/i18n/messages/hy.json
+++ b/src/i18n/messages/hy.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Դիրքի կարգ",
"poolHealthRankingOff": "Առողջության վարկանիշն անջատված է",
"transportRate": "{rate}% փոխադրում",
+ "slowAbandoned": "{count} դանդաղ լքումներ",
+ "clientAborted": "{count} հաճախորդի չեղարկումներ",
+ "slowAbandonedHint": "Լքվել է վերնագրերի սպասման շեմից հետո, չի ներառվում տրանսպորտի դասին",
"previousSuccessRate": "Նախկինում {rate}% հաջողություն",
"upstreamRefusals": "{count} upstream մերժում",
"connectionTestsCount": "{count} կապի թեստ",
diff --git a/src/i18n/messages/id.json b/src/i18n/messages/id.json
index ccfed3aecabb..f9bf89d3e669 100644
--- a/src/i18n/messages/id.json
+++ b/src/i18n/messages/id.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Urutan posisi",
"poolHealthRankingOff": "Peringkat kesehatan mati",
"transportRate": "{rate}% transport",
+ "slowAbandoned": "{count} penghentian lambat",
+ "clientAborted": "{count} pembatalan oleh klien",
+ "slowAbandonedHint": "Ditinggalkan setelah melewati batas waktu tunggu header, tidak termasuk dalam tarif transportasi",
"previousSuccessRate": "Sebelumnya {rate}% berhasil",
"upstreamRefusals": "{count} penolakan upstream",
"connectionTestsCount": "{count} uji koneksi",
diff --git a/src/i18n/messages/ig.json b/src/i18n/messages/ig.json
index 16f17a690cff..94542704d68e 100644
--- a/src/i18n/messages/ig.json
+++ b/src/i18n/messages/ig.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Usoro ọnọdụ",
"poolHealthRankingOff": "Ogo ahụike agbanyụrụ",
"transportRate": "{rate}% mbugharị",
+ "slowAbandoned": "{count} nke na-ewu oge na-eche echiche",
+ "clientAborted": "{count} ndị ahịa na-eme ka o kwụsị",
+ "slowAbandonedHint": "Eche echiche ka o kwụsị mgbe o chee oge nke isiokwu, na-ekpughe na ọnụ ọgụgụ nke ịgwọ ụgbọ",
"previousSuccessRate": "Na mbụ {rate}% ịga nke ọma",
"upstreamRefusals": "{count} ọjụjụ upstream",
"connectionTestsCount": "{count} nnwale njikọ",
diff --git a/src/i18n/messages/it.json b/src/i18n/messages/it.json
index 2fdfb078c00d..a3d54931f7bb 100644
--- a/src/i18n/messages/it.json
+++ b/src/i18n/messages/it.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ordine di posizione",
"poolHealthRankingOff": "Classificazione salute disattivata",
"transportRate": "{rate} % trasporto",
+ "slowAbandoned": "{count} abbandoni lenti",
+ "clientAborted": "{count} interruzioni da parte del client",
+ "slowAbandonedHint": "Abbandonato dopo aver superato la soglia di attesa delle intestazioni, escluso dalla tariffa di trasporto",
"previousSuccessRate": "In precedenza {rate} % di successo",
"upstreamRefusals": "{count} rifiuti upstream",
"connectionTestsCount": "{count} test di connessione",
diff --git a/src/i18n/messages/ja.json b/src/i18n/messages/ja.json
index bd0e0963b8d7..31d3106ff9d2 100644
--- a/src/i18n/messages/ja.json
+++ b/src/i18n/messages/ja.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "位置順序",
"poolHealthRankingOff": "ヘルスランキング無効",
"transportRate": "{rate}%トランスポート",
+ "slowAbandoned": "{count} 回の遅延による中断",
+ "clientAborted": "{count} 回のクライアントによる中断",
+ "slowAbandonedHint": "ヘッダー待ち時間の閾値を超過した後に中断され、転送レートから除外されました",
"previousSuccessRate": "以前は{rate}%成功",
"upstreamRefusals": "{count}件のアップストリーム拒否",
"connectionTestsCount": "{count}件の接続テスト",
diff --git a/src/i18n/messages/ka.json b/src/i18n/messages/ka.json
index 182123e5b532..e5a6cc25e7fe 100644
--- a/src/i18n/messages/ka.json
+++ b/src/i18n/messages/ka.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "პოზიციის თანმიმდევრობა",
"poolHealthRankingOff": "ჯანმრთელობის რეიტინგი გამორთულია",
"transportRate": "{rate}% ტრანსპორტი",
+ "slowAbandoned": "{count} ნელი უარისთვის ჩაბარება",
+ "clientAborted": "{count} კლიენტის უარისთვის ჩაბარება",
+ "slowAbandonedHint": "უარი თქმულია სათაურების ლოდინის ზღვრის გადალახვის შემდეგ, გამორიცხულია სატრანსპორტო განაკვეთიდან",
"previousSuccessRate": "ადრე {rate}% წარმატება",
"upstreamRefusals": "{count} upstream უარყოფა",
"connectionTestsCount": "{count} კავშირის ტესტი",
diff --git a/src/i18n/messages/km.json b/src/i18n/messages/km.json
index 9cdfbea3f861..3a7b8f8a8dee 100644
--- a/src/i18n/messages/km.json
+++ b/src/i18n/messages/km.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "លំដាប់ទីតាំង",
"poolHealthRankingOff": "ចំណាត់ថ្នាក់សុខភាពបិទ",
"transportRate": "{rate}% ការដឹកជញ្ជូន",
+ "slowAbandoned": "{count} ការបាត់បង់យ៉ាងយឺត",
+ "clientAborted": "{count} ការបញ្ឈប់ដោយអតិថិជន",
+ "slowAbandonedHint": "ត្រូវបានបាត់បង់បន្ទាប់ពីកម្រិតរង់ចាំប៉ុស្តិ៍ ត្រូវបានលុបចេញពីកម្រិតផ្ទេរ",
"previousSuccessRate": "ពីមុន {rate}% ជោគជ័យ",
"upstreamRefusals": "{count} ការបដិសេធ upstream",
"connectionTestsCount": "{count} ការធ្វើតេស្តការតភ្ជាប់",
diff --git a/src/i18n/messages/kn.json b/src/i18n/messages/kn.json
index 28431bd423b1..c3056fffaa81 100644
--- a/src/i18n/messages/kn.json
+++ b/src/i18n/messages/kn.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "ಸ್ಥಾನ ಕ್ರಮ",
"poolHealthRankingOff": "ಆರೋಗ್ಯ ಶ್ರೇಯಾಂಕ ಆಫ್",
"transportRate": "{rate}% ಸಾರಿಗೆ",
+ "slowAbandoned": "{count} ನಿಧಾನ ತ್ಯಜಿಸುವಿಕೆಗಳು",
+ "clientAborted": "{count} ಕ್ಲೈಂಟ್ ರದ್ದುಗೊಳಿಸುವಿಕೆಗಳು",
+ "slowAbandonedHint": "ಶೀರ್ಷಿಕೆಗಳ ನಿರೀಕ್ಷಾ ಮಿತಿ ನಂತರ ತ್ಯಜಿಸಲಾಗಿದೆ, ಸಾರಿಗೆ ದರದಿಂದ ಹೊರಗಿಡಲಾಗಿದೆ",
"previousSuccessRate": "ಹಿಂದೆ {rate}% ಯಶಸ್ಸು",
"upstreamRefusals": "{count} ಅಪ್ಸ್ಟ್ರೀಮ್ ನಿರಾಕರಣೆಗಳು",
"connectionTestsCount": "{count} ಸಂಪರ್ಕ ಪರೀಕ್ಷೆಗಳು",
diff --git a/src/i18n/messages/ko.json b/src/i18n/messages/ko.json
index df20779c5e6c..7a6839f3494f 100644
--- a/src/i18n/messages/ko.json
+++ b/src/i18n/messages/ko.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "위치 순서",
"poolHealthRankingOff": "상태 순위 꺼짐",
"transportRate": "{rate}% 전송",
+ "slowAbandoned": "{count} 느린 포기",
+ "clientAborted": "{count} 클라이언트 중단",
+ "slowAbandonedHint": "헤더 대기 임계값 이후 포기, 전송률에서 제외",
"previousSuccessRate": "이전에 {rate}% 성공",
"upstreamRefusals": "{count}개 업스트림 거부",
"connectionTestsCount": "{count}개 연결 테스트",
diff --git a/src/i18n/messages/lt.json b/src/i18n/messages/lt.json
index dc0b18bd24b4..1ee12d7600b2 100644
--- a/src/i18n/messages/lt.json
+++ b/src/i18n/messages/lt.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Pozicijų tvarka",
"poolHealthRankingOff": "Sveikatos reitingavimas išjungtas",
"transportRate": "{rate} % transporto",
+ "slowAbandoned": "{count} lėtos atšaukimų",
+ "clientAborted": "{count} kliento nutraukimų",
+ "slowAbandonedHint": "Panaikinta po antraštės laukimo ribos, neįtraukiama į perdavimo greitį",
"previousSuccessRate": "Anksčiau {rate} % sėkmės",
"upstreamRefusals": "{count} aukštesnio lygio atmetimų",
"connectionTestsCount": "{count} ryšio testus",
diff --git a/src/i18n/messages/lv.json b/src/i18n/messages/lv.json
index 2958edc473e5..182815c5a2e3 100644
--- a/src/i18n/messages/lv.json
+++ b/src/i18n/messages/lv.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Pozīciju secība",
"poolHealthRankingOff": "Veselības ranžēšana izslēgta",
"transportRate": "{rate} % transporta",
+ "slowAbandoned": "{count} lēnas atteikšanās",
+ "clientAborted": "{count} klienta pārtraukumi",
+ "slowAbandonedHint": "Atteikta pēc galvenes gaidīšanas sliekšņa, izslēgta no transporta likmes",
"previousSuccessRate": "Iepriekš {rate} % sekmju",
"upstreamRefusals": "{count} augšupējos noraidījumus",
"connectionTestsCount": "{count} savienojuma testus",
diff --git a/src/i18n/messages/ml.json b/src/i18n/messages/ml.json
index cc20dc0cf258..6053c23bc0e4 100644
--- a/src/i18n/messages/ml.json
+++ b/src/i18n/messages/ml.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "സ്ഥാന ക്രമം",
"poolHealthRankingOff": "ആരോഗ്യ റാങ്കിംഗ് ഓഫ്",
"transportRate": "{rate}% ഗതാഗതം",
+ "slowAbandoned": "{count} മന്ദഗതിയിലുള്ള ഉപേക്ഷണങ്ങൾ",
+ "clientAborted": "{count} ക്ലയന്റ് റദ്ദാക്കലുകൾ",
+ "slowAbandonedHint": "ഹെഡറുകൾ കാത്തിരിപ്പ് പരിധിക്ക് ശേഷം ഉപേക്ഷിക്കപ്പെട്ടത്, ട്രാൻസ്പോർട്ട് നിരക്കിൽ നിന്ന് ഒഴിവാക്കിയിരിക്കുന്നു",
"previousSuccessRate": "മുമ്പ് {rate}% വിജയം",
"upstreamRefusals": "{count} അപ്സ്ട്രീം നിരസിക്കലുകൾ",
"connectionTestsCount": "{count} കണക്ഷൻ പരിശോധനകൾ",
diff --git a/src/i18n/messages/mr.json b/src/i18n/messages/mr.json
index f146ee10160a..9c902d98bbbb 100644
--- a/src/i18n/messages/mr.json
+++ b/src/i18n/messages/mr.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "स्थान क्रम",
"poolHealthRankingOff": "आरोग्य क्रमवारी बंद",
"transportRate": "{rate}% वाहतूक",
+ "slowAbandoned": "{count} धीमे परित्याग",
+ "clientAborted": "{count} क्लायंट रद्दीकरणे",
+ "slowAbandonedHint": "हेडर्स प्रतीक्षा मर्यादेनंतर परित्यक्त, ट्रान्सपोर्ट दरातून वगळलेले",
"previousSuccessRate": "यापूर्वी {rate}% यश",
"upstreamRefusals": "{count} अपस्ट्रीम नकार",
"connectionTestsCount": "{count} कनेक्शन चाचण्या",
diff --git a/src/i18n/messages/ms.json b/src/i18n/messages/ms.json
index d319746558ac..6f75f41e218a 100644
--- a/src/i18n/messages/ms.json
+++ b/src/i18n/messages/ms.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Susunan kedudukan",
"poolHealthRankingOff": "Penarafan kesihatan dimatikan",
"transportRate": "{rate}% pengangkutan",
+ "slowAbandoned": "{count} penolakan perlahan",
+ "clientAborted": "{count} penamatan klien",
+ "slowAbandonedHint": "Ditinggalkan selepas ambang tunggu tajuk, tidak termasuk dalam kadar penghantaran",
"previousSuccessRate": "Sebelum ini {rate}% berjaya",
"upstreamRefusals": "{count} penolakan huluan",
"connectionTestsCount": "{count} ujian sambungan",
diff --git a/src/i18n/messages/mt.json b/src/i18n/messages/mt.json
index 1531ce4bd24e..b1ed689a88a1 100644
--- a/src/i18n/messages/mt.json
+++ b/src/i18n/messages/mt.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ordni tal-pożizzjoni",
"poolHealthRankingOff": "Klassifika tas-saħħa mitfija",
"transportRate": "{rate}% trasport",
+ "slowAbandoned": "{count} abbandonamenti tal‑mellieħ",
+ "clientAborted": "{count} kansellazzjonijiet tal‑klijent",
+ "slowAbandonedHint": "Abbandonat wara l‑threshold ta’ ħin ta’ ħruġ tal‑headers, eskluż mill‑rate tal‑trasport",
"previousSuccessRate": "Qabel {rate}% suċċess",
"upstreamRefusals": "{count} rifjuti upstream",
"connectionTestsCount": "{count} testijiet tal-konnessjoni",
diff --git a/src/i18n/messages/my.json b/src/i18n/messages/my.json
index 2c3bf29989a3..b6a315527b6f 100644
--- a/src/i18n/messages/my.json
+++ b/src/i18n/messages/my.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "အနေအထားအစီအစဉ်",
"poolHealthRankingOff": "ကျန်းမာရေးအဆင့် ပိတ်ထားသည်",
"transportRate": "{rate}% သယ်ယူပို့ဆောင်မှု",
+ "slowAbandoned": "{count} အလျင်အမြန် ပယ်သွားမှုများ",
+ "clientAborted": "{count} ဖောက်သည် ပယ်သွားမှုများ",
+ "slowAbandonedHint": "Headers များစောင့်ရှောင်မှုကန့်သတ်ချက်အပြီး ပယ်သွားပြီး၊ သယ်ယူပို့ဆောင်မှုနှုန်းထဲမှ ဖယ်ရှားထားသည်",
"previousSuccessRate": "အစက {rate}% အောင်မြင်မှု",
"upstreamRefusals": "{count} upstream ငြင်းပယ်မှုများ",
"connectionTestsCount": "{count} ချိတ်ဆက်မှု စမ်းသပ်မှုများ",
diff --git a/src/i18n/messages/ne.json b/src/i18n/messages/ne.json
index a77f71181c77..59f3e325edb2 100644
--- a/src/i18n/messages/ne.json
+++ b/src/i18n/messages/ne.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "स्थिति क्रम",
"poolHealthRankingOff": "स्वास्थ्य श्रेणी बन्द",
"transportRate": "{rate}% ढुवानी",
+ "slowAbandoned": "{count} ढिलो परित्यागहरू",
+ "clientAborted": "{count} क्लाइन्टको रद्दीकरणहरू",
+ "slowAbandonedHint": "हेडर प्रतीक्षा सीमा पछि परित्याग गरियो, ट्रान्सपोर्ट दरबाट बहिष्कृत",
"previousSuccessRate": "पहिले {rate}% सफलता",
"upstreamRefusals": "{count} अपस्ट्रीम अस्वीकृति",
"connectionTestsCount": "{count} जडान परीक्षण",
diff --git a/src/i18n/messages/nl.json b/src/i18n/messages/nl.json
index 4532778a63e7..d4c8590c7ffe 100644
--- a/src/i18n/messages/nl.json
+++ b/src/i18n/messages/nl.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Positievolgorde",
"poolHealthRankingOff": "Gezondheidsrangschikking uit",
"transportRate": "{rate} % transport",
+ "slowAbandoned": "{count} trage afwijzingen",
+ "clientAborted": "{count} clientafbrekingen",
+ "slowAbandonedHint": "Verlaten na de headers-wachttijd, uitgesloten van het transporttarief",
"previousSuccessRate": "Eerder {rate} % succes",
"upstreamRefusals": "{count} upstream-weigeringen",
"connectionTestsCount": "{count} verbindingstests",
diff --git a/src/i18n/messages/no.json b/src/i18n/messages/no.json
index 5a67f9beffc7..a4bf1d22f76e 100644
--- a/src/i18n/messages/no.json
+++ b/src/i18n/messages/no.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Posisjonsrekkefølge",
"poolHealthRankingOff": "Helserangering av",
"transportRate": "{rate} % transport",
+ "slowAbandoned": "{count} langsomme forlatelser",
+ "clientAborted": "{count} klientavbrudd",
+ "slowAbandonedHint": "Forlatt etter overskriftsventetidspunktet, ekskludert fra transportrate",
"previousSuccessRate": "Tidligere {rate} % suksess",
"upstreamRefusals": "{count} upstream-avvisninger",
"connectionTestsCount": "{count} tilkoblingstester",
diff --git a/src/i18n/messages/or.json b/src/i18n/messages/or.json
index ba4be2901fff..10fdfb1f8047 100644
--- a/src/i18n/messages/or.json
+++ b/src/i18n/messages/or.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "ସ୍ଥିତି କ୍ରମ",
"poolHealthRankingOff": "ସ୍ୱାସ୍ଥ୍ୟ ରାଙ୍କିଙ୍ଗ ବନ୍ଦ",
"transportRate": "{rate}% ପରିବହନ",
+ "slowAbandoned": "{count} ଧୀର ତ୍ୟାଗ",
+ "clientAborted": "{count} ଗ୍ରାହକ ବିଚ୍ଛିନ୍ନ",
+ "slowAbandonedHint": "ହେଡର ଅପେକ୍ଷା ଥ୍ରେଶହୋଲ୍ଡ ପରେ ତ୍ୟାଗ ହୋଇଛି, ଟ୍ରାନ୍ସପୋର୍ଟ ହାରରୁ ବାହାର ରଖାଯାଇଛି",
"previousSuccessRate": "ପୂର୍ବରୁ {rate}% ସଫଳତା",
"upstreamRefusals": "{count} ଅପଷ୍ଟ୍ରିମ୍ ପ୍ରତ୍ୟାଖ୍ୟାନ",
"connectionTestsCount": "{count} ସଂଯୋଗ ପରୀକ୍ଷା",
diff --git a/src/i18n/messages/pa.json b/src/i18n/messages/pa.json
index 81b5b77ba65a..63ab0350ba4c 100644
--- a/src/i18n/messages/pa.json
+++ b/src/i18n/messages/pa.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "ਸਥਿਤੀ ਕ੍ਰਮ",
"poolHealthRankingOff": "ਸਿਹਤ ਦਰਜਾਬੰਦੀ ਬੰਦ",
"transportRate": "{rate}% ਟਰਾਂਸਪੋਰਟ",
+ "slowAbandoned": "{count} ਹੌਲੀ ਛੱਡਣੀਆਂ",
+ "clientAborted": "{count} ਕਲਾਇੰਟ ਰੱਦਾਂ",
+ "slowAbandonedHint": "ਹੈਡਰ ਉਡੀਕ ਸੀਮਾ ਤੋਂ ਬਾਅਦ ਛੱਡਿਆ ਗਿਆ, ਟਰਾਂਸਪੋਰਟ ਦਰ ਤੋਂ ਬਾਹਰ ਰੱਖਿਆ ਗਿਆ",
"previousSuccessRate": "ਪਹਿਲਾਂ {rate}% ਸਫਲਤਾ",
"upstreamRefusals": "{count} ਅੱਪਸਟ੍ਰੀਮ ਅਸਵੀਕਾਰ",
"connectionTestsCount": "{count} ਕਨੈਕਸ਼ਨ ਜਾਂਚਾਂ",
diff --git a/src/i18n/messages/phi.json b/src/i18n/messages/phi.json
index d1a827a30814..e03e5607ac49 100644
--- a/src/i18n/messages/phi.json
+++ b/src/i18n/messages/phi.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ayos ng posisyon",
"poolHealthRankingOff": "Naka-off ang ranggo ng kalusugan",
"transportRate": "{rate}% transport",
+ "slowAbandoned": "{count} mabagal na pag-abandona",
+ "clientAborted": "{count} abort ng kliyente",
+ "slowAbandonedHint": "Inabandona matapos ang threshold ng paghihintay ng mga header, hindi isinama sa rate ng transport",
"previousSuccessRate": "Dati {rate}% tagumpay",
"upstreamRefusals": "{count} pagtanggi ng upstream",
"connectionTestsCount": "{count} pagsubok ng koneksyon",
diff --git a/src/i18n/messages/pl.json b/src/i18n/messages/pl.json
index 3bad4555ba73..1eaf6bb53681 100644
--- a/src/i18n/messages/pl.json
+++ b/src/i18n/messages/pl.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Kolejność pozycji",
"poolHealthRankingOff": "Ranking kondycji wyłączony",
"transportRate": "{rate}% transportu",
+ "slowAbandoned": "{count} wolne porzucenia",
+ "clientAborted": "{count} przerwań klienta",
+ "slowAbandonedHint": "Porzucone po przekroczeniu progu czasu oczekiwania na nagłówki, wyłączone z wskaźnika transportu",
"previousSuccessRate": "Wcześniej {rate}% skuteczności",
"upstreamRefusals": "{count} odmów upstream",
"connectionTestsCount": "{count} testów połączenia",
diff --git a/src/i18n/messages/pt-BR.json b/src/i18n/messages/pt-BR.json
index 42f8e7a3e66e..e76cc630ca63 100644
--- a/src/i18n/messages/pt-BR.json
+++ b/src/i18n/messages/pt-BR.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ordem de posição",
"poolHealthRankingOff": "Classificação de integridade desativada",
"transportRate": "{rate} % transporte",
+ "slowAbandoned": "{count} abandonos lentos",
+ "clientAborted": "{count} abortos de cliente",
+ "slowAbandonedHint": "Abandonado após o limite de espera dos cabeçalhos, excluído da taxa de transporte",
"previousSuccessRate": "Anteriormente {rate} % de êxito",
"upstreamRefusals": "{count} recusas upstream",
"connectionTestsCount": "{count} testes de conexão",
diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json
index b9cddd55498d..e71eb21d3baa 100644
--- a/src/i18n/messages/pt.json
+++ b/src/i18n/messages/pt.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ordem de posição",
"poolHealthRankingOff": "Classificação de saúde desativada",
"transportRate": "{rate} % transporte",
+ "slowAbandoned": "{count} abandonos lentos",
+ "clientAborted": "{count} abortos de cliente",
+ "slowAbandonedHint": "Abandonado após o limite de espera dos cabeçalhos, excluído da taxa de transporte",
"previousSuccessRate": "Anteriormente {rate} % de sucesso",
"upstreamRefusals": "{count} recusas upstream",
"connectionTestsCount": "{count} testes de ligação",
diff --git a/src/i18n/messages/ro.json b/src/i18n/messages/ro.json
index 0752a8908637..45ec000019e9 100644
--- a/src/i18n/messages/ro.json
+++ b/src/i18n/messages/ro.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ordinea pozițiilor",
"poolHealthRankingOff": "Clasificarea stării dezactivată",
"transportRate": "{rate} % transport",
+ "slowAbandoned": "{count} abandonări lente",
+ "clientAborted": "{count} abandonări ale clientului",
+ "slowAbandonedHint": "Abandonat după pragul de așteptare a antetelor, exclus din rata de transport",
"previousSuccessRate": "Anterior {rate} % succes",
"upstreamRefusals": "{count} refuzuri upstream",
"connectionTestsCount": "{count} teste de conexiune",
diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json
index 4aca925be340..1e2801fc7961 100644
--- a/src/i18n/messages/ru.json
+++ b/src/i18n/messages/ru.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Порядок позиций",
"poolHealthRankingOff": "Рейтинг здоровья выкл",
"transportRate": "{rate}% транспорта",
+ "slowAbandoned": "{count} медленных отказов",
+ "clientAborted": "{count} прерываний клиента",
+ "slowAbandonedHint": "Отказано после порога ожидания заголовков, исключено из транспортной скорости",
"previousSuccessRate": "Ранее {rate}% успеха",
"upstreamRefusals": "{count} отказов апстрима",
"connectionTestsCount": "{count} проверок соединения",
diff --git a/src/i18n/messages/si.json b/src/i18n/messages/si.json
index beb37ebe01b3..1127bfed9ed6 100644
--- a/src/i18n/messages/si.json
+++ b/src/i18n/messages/si.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "ස්ථාන අනුපිළිවෙල",
"poolHealthRankingOff": "සෞඛ්ය ශ්රේණිගත කිරීම අක්රිය",
"transportRate": "{rate}% ප්රවාහනය",
+ "slowAbandoned": "{count} ස්වල්ප අත්හිටුවීම්",
+ "clientAborted": "{count} ක්ලයින්ට් අවම් කිරීම්",
+ "slowAbandonedHint": "හෙඩර්ස් අත්හිටුවීමේ තරම පසුව අත්හිටුවීම, තොග අනුපාතයෙන් අභාවිත කරනු ලැබීම",
"previousSuccessRate": "පෙර {rate}% සාර්ථකත්වය",
"upstreamRefusals": "{count} upstream ප්රතික්ෂේප",
"connectionTestsCount": "{count} සම්බන්ධතා පරීක්ෂණ",
diff --git a/src/i18n/messages/sk.json b/src/i18n/messages/sk.json
index 666a5d4f7dee..de84f0cec5e5 100644
--- a/src/i18n/messages/sk.json
+++ b/src/i18n/messages/sk.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Poradie pozícií",
"poolHealthRankingOff": "Hodnotenie stavu vypnuté",
"transportRate": "{rate} % prenosu",
+ "slowAbandoned": "{count} pomalých opustení",
+ "clientAborted": "{count} klientských prerušení",
+ "slowAbandonedHint": "Opustené po prekročení limitu čakania na hlavičky, vynechané z miery prenosu",
"previousSuccessRate": "Predtým {rate} % úspešnosť",
"upstreamRefusals": "{count} odmietnutí upstream",
"connectionTestsCount": "{count} testov pripojenia",
diff --git a/src/i18n/messages/sl.json b/src/i18n/messages/sl.json
index eb6c6260250e..1d552f002910 100644
--- a/src/i18n/messages/sl.json
+++ b/src/i18n/messages/sl.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Vrstni red položajev",
"poolHealthRankingOff": "Razvrščanje zdravja izklopljeno",
"transportRate": "{rate} % prenosa",
+ "slowAbandoned": "{count} počasnih opustitev",
+ "clientAborted": "{count} prekinitve odjemalca",
+ "slowAbandonedHint": "Opustitev po presežku praga čakanja glave, izključeno iz hitrosti prenosa",
"previousSuccessRate": "Prej {rate} % uspešnosti",
"upstreamRefusals": "{count} zavrnitev upstream",
"connectionTestsCount": "{count} preskusov povezave",
diff --git a/src/i18n/messages/sr.json b/src/i18n/messages/sr.json
index ed9c7a0409de..12392a733f81 100644
--- a/src/i18n/messages/sr.json
+++ b/src/i18n/messages/sr.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Редослед позиција",
"poolHealthRankingOff": "Рангирање здравља искључено",
"transportRate": "{rate} % преноса",
+ "slowAbandoned": "{count} sporih napuštanja",
+ "clientAborted": "{count} odustajanja klijenta",
+ "slowAbandonedHint": "Napusteno nakon praga čekanja zaglavlja, izuzeto iz transportne stope",
"previousSuccessRate": "Раније {rate} % успеха",
"upstreamRefusals": "{count} upstream одбијања",
"connectionTestsCount": "{count} тестова везе",
diff --git a/src/i18n/messages/sv.json b/src/i18n/messages/sv.json
index e8d9dc3b927a..44e71f3735d1 100644
--- a/src/i18n/messages/sv.json
+++ b/src/i18n/messages/sv.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Positionsordning",
"poolHealthRankingOff": "Hälsorankning av",
"transportRate": "{rate} % transport",
+ "slowAbandoned": "{count} långsamma övergivanden",
+ "clientAborted": "{count} klientavbrott",
+ "slowAbandonedHint": "Övergivna efter rubrikväntetidgränsen, exkluderade från transporttalet",
"previousSuccessRate": "Tidigare {rate} % lyckade",
"upstreamRefusals": "{count} upstream-avvisningar",
"connectionTestsCount": "{count} anslutningstester",
diff --git a/src/i18n/messages/sw.json b/src/i18n/messages/sw.json
index 87c5d29e918e..1208268d9dee 100644
--- a/src/i18n/messages/sw.json
+++ b/src/i18n/messages/sw.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Mpangilio wa nafasi",
"poolHealthRankingOff": "Kiwango cha afya kimezimwa",
"transportRate": "{rate}% usafiri",
+ "slowAbandoned": "{count} uacha polepole",
+ "clientAborted": "{count} mteja amegoma",
+ "slowAbandonedHint": "Imewekwa kando baada ya kufikia kikomo cha kusubiri vichwa, imefutwa kutoka kwa kiwango cha usafirishaji",
"previousSuccessRate": "Awali {rate}% mafanikio",
"upstreamRefusals": "{count} kukataliwa kwa upstream",
"connectionTestsCount": "{count} majaribio ya muunganisho",
diff --git a/src/i18n/messages/ta.json b/src/i18n/messages/ta.json
index edeaeb3ffd59..bef18785c7e3 100644
--- a/src/i18n/messages/ta.json
+++ b/src/i18n/messages/ta.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "நிலை வரிசை",
"poolHealthRankingOff": "சுகாதார தரவரிசை நிறுத்தம்",
"transportRate": "{rate}% போக்குவரத்து",
+ "slowAbandoned": "{count} மெதுவான கைவிடல்கள்",
+ "clientAborted": "{count} வாடிக்கையாளர் நிறுத்தங்கள்",
+ "slowAbandonedHint": "தலைப்புகள் காத்திருப்பு வரம்புக்குப் பிறகு கைவிடப்பட்டது, போக்குவரத்து விகிதத்தில் இருந்து நீக்கப்பட்டது",
"previousSuccessRate": "முன்பு {rate}% வெற்றி",
"upstreamRefusals": "{count} அப்ஸ்ட்ரீம் மறுப்புகள்",
"connectionTestsCount": "{count} இணைப்பு சோதனைகள்",
diff --git a/src/i18n/messages/te.json b/src/i18n/messages/te.json
index fcccd32a573b..87d16cdb8367 100644
--- a/src/i18n/messages/te.json
+++ b/src/i18n/messages/te.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "స్థాన క్రమం",
"poolHealthRankingOff": "ఆరోగ్య ర్యాంకింగ్ ఆఫ్",
"transportRate": "{rate}% రవాణా",
+ "slowAbandoned": "{count} నెమ్మదిగా వదిలివేయబడినవి",
+ "clientAborted": "{count} క్లయింట్ రద్దులు",
+ "slowAbandonedHint": "హెడర్లు వేచి ఉండే పరిమితి తర్వాత వదిలివేయబడింది, ట్రాన్స్పోర్ట్ రేటు నుండి మినహాయించబడింది",
"previousSuccessRate": "గతంలో {rate}% విజയം",
"upstreamRefusals": "{count} అప్స్ట్రీమ్ నిరాకరణలు",
"connectionTestsCount": "{count} కనెక్షన్ పరీక్షలు",
diff --git a/src/i18n/messages/th.json b/src/i18n/messages/th.json
index 154c7ab9e86b..d0d235db6abb 100644
--- a/src/i18n/messages/th.json
+++ b/src/i18n/messages/th.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "ลำดับตำแหน่ง",
"poolHealthRankingOff": "ปิดการจัดอันดับสุขภาพ",
"transportRate": "{rate}% การขนส่ง",
+ "slowAbandoned": "{count} การละทิ้งที่ช้า",
+ "clientAborted": "{count} การยกเลิกของไคลเอนต์",
+ "slowAbandonedHint": "ถูกละทิ้งหลังจากเกณฑ์การรอหัวข้อ, ไม่รวมในอัตราการขนส่ง",
"previousSuccessRate": "ก่อนหน้านี้ {rate}% สำเร็จ",
"upstreamRefusals": "{count} การปฏิเสธต้นน้ำ",
"connectionTestsCount": "{count} การทดสอบการเชื่อมต่อ",
diff --git a/src/i18n/messages/tr.json b/src/i18n/messages/tr.json
index aedcc059e9ad..ff43605466bc 100644
--- a/src/i18n/messages/tr.json
+++ b/src/i18n/messages/tr.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Konum sırası",
"poolHealthRankingOff": "Sağlık sıralaması kapalı",
"transportRate": "{rate}% taşıma",
+ "slowAbandoned": "{count} yavaş terk etmeler",
+ "clientAborted": "{count} istemci iptalleri",
+ "slowAbandonedHint": "Başlıkların bekleme eşiğinden sonra terk edildi, taşıma oranından hariç tutuldu",
"previousSuccessRate": "Önceden {rate}% başarı",
"upstreamRefusals": "{count} yukarı akış reddi",
"connectionTestsCount": "{count} bağlantı testi",
diff --git a/src/i18n/messages/uk-UA.json b/src/i18n/messages/uk-UA.json
index 554fde54c362..de6ec6497f77 100644
--- a/src/i18n/messages/uk-UA.json
+++ b/src/i18n/messages/uk-UA.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Порядок позицій",
"poolHealthRankingOff": "Рейтинг здоровʼя вимкнено",
"transportRate": "{rate}% транспорту",
+ "slowAbandoned": "{count} повільних відмов",
+ "clientAborted": "{count} відмов клієнта",
+ "slowAbandonedHint": "Відкинуто після порогу очікування заголовків, виключено з швидкості транспорту",
"previousSuccessRate": "Раніше {rate}% успіху",
"upstreamRefusals": "{count} відмов апастріму",
"connectionTestsCount": "{count} перевірок зʼєднання",
diff --git a/src/i18n/messages/ur.json b/src/i18n/messages/ur.json
index 547c7a25f3c9..6f515fb1b63c 100644
--- a/src/i18n/messages/ur.json
+++ b/src/i18n/messages/ur.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "مقام کی ترتیب",
"poolHealthRankingOff": "ہیلتھ رینکنگ آف",
"transportRate": "{rate}% ٹرانسپورٹ",
+ "slowAbandoned": "{count} سست ترکیاں",
+ "clientAborted": "{count} کلائنٹ منسوخیاں",
+ "slowAbandonedHint": "ہیڈرز کے انتظار کی حد کے بعد ترک کر دیا گیا، ٹرانسپورٹ کی شرح سے خارج",
"previousSuccessRate": "پہلے {rate}% کامیابی",
"upstreamRefusals": "{count} اپ اسٹریم مسترد",
"connectionTestsCount": "{count} کنکشن ٹیسٹ",
diff --git a/src/i18n/messages/uz.json b/src/i18n/messages/uz.json
index 97b87a20f1e0..4e418710cd90 100644
--- a/src/i18n/messages/uz.json
+++ b/src/i18n/messages/uz.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Pozitsiya tartibi",
"poolHealthRankingOff": "Salomatlik reytingi o‘chiq",
"transportRate": "{rate}% transport",
+ "slowAbandoned": "{count} sekin tark etishlar",
+ "clientAborted": "{count} mijoz bekor qilishlari",
+ "slowAbandonedHint": "Sarlavhalar kutish chegarasidan keyin tark etildi, transport tezligidan chiqarildi",
"previousSuccessRate": "Oldin {rate}% muvaffaqiyat",
"upstreamRefusals": "{count} ta yuqori rad etish",
"connectionTestsCount": "{count} ulanish testi",
diff --git a/src/i18n/messages/vi.json b/src/i18n/messages/vi.json
index c98e2e6f9469..9dc08af5d266 100644
--- a/src/i18n/messages/vi.json
+++ b/src/i18n/messages/vi.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Thứ tự vị trí",
"poolHealthRankingOff": "Xếp hạng tình trạng tắt",
"transportRate": "{rate}% vận chuyển",
+ "slowAbandoned": "{count} lần hủy bỏ chậm",
+ "clientAborted": "{count} lần hủy bỏ bởi client",
+ "slowAbandonedHint": "Hủy bỏ sau ngưỡng chờ tiêu đề, không được tính vào tỷ lệ vận chuyển",
"previousSuccessRate": "Trước đây {rate}% thành công",
"upstreamRefusals": "{count} từ chối từ máy chủ",
"connectionTestsCount": "{count} kiểm tra kết nối",
diff --git a/src/i18n/messages/yo.json b/src/i18n/messages/yo.json
index ed0a4b80b2da..1dc3397cadf8 100644
--- a/src/i18n/messages/yo.json
+++ b/src/i18n/messages/yo.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "Ilana ipo",
"poolHealthRankingOff": "Ipo ilera pa",
"transportRate": "{rate}% gbigbe",
+ "slowAbandoned": "{count} ìfọkànsí tó lọ́ra",
+ "clientAborted": "{count} ìdákẹ́jẹ́ oníbàárà",
+ "slowAbandonedHint": "Ti kọ́ silẹ̀ lẹ́yìn àkókò ìdúró àkóónú, a yọ kúrò nínú oṣuwọn ìkópa",
"previousSuccessRate": "Ni iṣaaju {rate}% aṣeyọri",
"upstreamRefusals": "{count} kikọ upstream",
"connectionTestsCount": "{count} idanwo asopọ",
diff --git a/src/i18n/messages/zh-CN.json b/src/i18n/messages/zh-CN.json
index 37b00bcf2d6d..96f99c5edc07 100644
--- a/src/i18n/messages/zh-CN.json
+++ b/src/i18n/messages/zh-CN.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "位置顺序",
"poolHealthRankingOff": "健康排名已关闭",
"transportRate": "{rate}%传输",
+ "slowAbandoned": "{count} 次慢速放弃",
+ "clientAborted": "{count} 次客户端中止",
+ "slowAbandonedHint": "在达到头部等待阈值后放弃,未计入传输速率",
"previousSuccessRate": "此前{rate}%成功",
"upstreamRefusals": "{count}次上游拒绝",
"connectionTestsCount": "{count}次连接测试",
diff --git a/src/i18n/messages/zh-TW.json b/src/i18n/messages/zh-TW.json
index 2f9d317d8960..2686b8984e33 100644
--- a/src/i18n/messages/zh-TW.json
+++ b/src/i18n/messages/zh-TW.json
@@ -11094,6 +11094,9 @@
"poolSignalPosition": "位置順序",
"poolHealthRankingOff": "健康排名已關閉",
"transportRate": "{rate}%傳輸",
+ "slowAbandoned": "{count} 緩慢放棄",
+ "clientAborted": "{count} 客戶端中止",
+ "slowAbandonedHint": "在標頭等待閾值之後被放棄,未計入傳輸速率",
"previousSuccessRate": "此前{rate}%成功",
"upstreamRefusals": "{count}次上游拒絕",
"connectionTestsCount": "{count}次連線測試",
diff --git a/src/lib/db/proxies.ts b/src/lib/db/proxies.ts
index d80a3f7bd300..8a9869831853 100755
--- a/src/lib/db/proxies.ts
+++ b/src/lib/db/proxies.ts
@@ -865,7 +865,9 @@ export async function getProxyHealthStats(options?: { hours?: number }) {
SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) THEN 1 ELSE 0 END) as real_requests,
SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) AND l.upstream_status IS NOT NULL THEN 1 ELSE 0 END) as measured_requests,
SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) AND (l.upstream_status IS NOT NULL OR l.status = 'success') THEN 1 ELSE 0 END) as transport_ok,
- SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) AND l.status IN ('error', 'timeout') AND l.upstream_status IS NULL THEN 1 ELSE 0 END) as transport_failures,
+ SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) AND l.status IN ('error', 'timeout') AND l.upstream_status IS NULL AND NOT (COALESCE(l.attempt_issue, '') = 'abandoned' AND COALESCE(l.error, '') LIKE 'OpencodeHeadersWaitTimeout:%') AND NOT (l.attempt_issue IS NOT NULL AND COALESCE(l.error, '') LIKE '%Request aborted%') THEN 1 ELSE 0 END) as transport_failures,
+ SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) AND l.status IN ('error', 'timeout') AND l.upstream_status IS NULL AND COALESCE(l.attempt_issue, '') = 'abandoned' AND COALESCE(l.error, '') LIKE 'OpencodeHeadersWaitTimeout:%' THEN 1 ELSE 0 END) as slow_abandoned,
+ SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) AND l.status IN ('error', 'timeout') AND l.upstream_status IS NULL AND l.attempt_issue IS NOT NULL AND COALESCE(l.error, '') LIKE '%Request aborted%' THEN 1 ELSE 0 END) as client_aborted,
SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) AND l.upstream_status >= 400 AND l.upstream_status < 500 THEN 1 ELSE 0 END) as upstream_4xx,
SUM(CASE WHEN l.id IS NOT NULL AND (l.target_url NOT LIKE '%/connection-test' OR l.target_url IS NULL) AND l.upstream_status >= 500 AND l.upstream_status < 600 THEN 1 ELSE 0 END) as upstream_5xx,
AVG(CASE WHEN l.latency_ms IS NOT NULL THEN l.latency_ms END) as avg_latency_ms,
@@ -890,6 +892,8 @@ export async function getProxyHealthStats(options?: { hours?: number }) {
const realRequests = Number(row.real_requests || 0);
const transportOk = Number(row.transport_ok || 0);
const transportFailures = Number(row.transport_failures || 0);
+ const slowAbandoned = Number(row.slow_abandoned || 0);
+ const clientAborted = Number(row.client_aborted || 0);
const measuredRequests = Number(row.measured_requests || 0);
const transportRate =
!measuredRequests || transportOk + transportFailures === 0
@@ -915,6 +919,8 @@ export async function getProxyHealthStats(options?: { hours?: number }) {
measured: measuredRequests > 0,
transportOk,
transportFailures,
+ slowAbandoned,
+ clientAborted,
transportRate,
upstream4xx: Number(row.upstream_4xx || 0),
upstream5xx: Number(row.upstream_5xx || 0),
diff --git a/stryker.conf.json b/stryker.conf.json
index 721484f9d633..397c594d5e6e 100644
--- a/stryker.conf.json
+++ b/stryker.conf.json
@@ -570,7 +570,8 @@
"tests/unit/search-success-clears-connection-error.test.ts",
"tests/unit/secret-compare-constant-time.test.ts",
"tests/unit/version-manager-local-only.test.ts",
- "tests/unit/stream-failure-after-output-no-model-lockout.test.ts"
+ "tests/unit/stream-failure-after-output-no-model-lockout.test.ts",
+ "tests/unit/db-proxies-ventilated.test.ts"
],
"nodeArgs": [
"--import",
diff --git a/tests/unit/db-proxies-crud.test.ts b/tests/unit/db-proxies-crud.test.ts
index 99f340600144..224b021e7cd6 100644
--- a/tests/unit/db-proxies-crud.test.ts
+++ b/tests/unit/db-proxies-crud.test.ts
@@ -237,6 +237,8 @@ test("proxy health stats aggregate proxy_logs and force delete removes assignmen
transportOk: 1,
transportFailures: 2,
transportRate: null,
+ slowAbandoned: 0,
+ clientAborted: 0,
upstream4xx: 0,
upstream5xx: 0,
avgLatencyMs: 250,
diff --git a/tests/unit/db-proxies-ventilated.test.ts b/tests/unit/db-proxies-ventilated.test.ts
index 0f814fe3bff6..8a91063478c0 100644
--- a/tests/unit/db-proxies-ventilated.test.ts
+++ b/tests/unit/db-proxies-ventilated.test.ts
@@ -48,6 +48,8 @@ type LogRow = {
status: string;
targetUrl: string | null;
upstreamStatus: number | null;
+ attemptIssue: string | null;
+ error: string | null;
};
let logSeq = 0;
@@ -59,8 +61,8 @@ async function seedProxy(name: string, host: string, rows: LogRow[]) {
const insertLog = db.prepare(`
INSERT INTO proxy_logs (
id, timestamp, status, proxy_type, proxy_host, proxy_port,
- target_url, upstream_status, latency_ms
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+ target_url, upstream_status, latency_ms, attempt_issue, error
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
for (const row of rows) {
logSeq += 1;
@@ -73,7 +75,9 @@ async function seedProxy(name: string, host: string, rows: LogRow[]) {
8080,
row.targetUrl,
row.upstreamStatus,
- 100
+ 100,
+ row.attemptIssue ?? null,
+ row.error ?? null
);
}
const stats = await proxiesDb.getProxyHealthStats({ hours: 2 });
@@ -88,9 +92,18 @@ async function seedProxy(name: string, host: string, rows: LogRow[]) {
function row(
status: string,
upstreamStatus: number | null,
- targetUrl: string | null = null
+ targetUrl: string | null = null,
+ attemptIssue: string | null = null,
+ error: string | null = null
): LogRow {
- return { id: `log-${status}-${String(upstreamStatus)}`, status, targetUrl, upstreamStatus };
+ return {
+ id: `log-${status}-${String(upstreamStatus)}`,
+ status,
+ targetUrl,
+ upstreamStatus,
+ attemptIssue,
+ error,
+ };
}
test("measured successes count as transport ok, including legacy rows without upstream status", async () => {
@@ -203,3 +216,150 @@ test("legacy aggregate fields keep their previous values", async () => {
assert.equal(entry.timeoutCount, 1);
assert.equal(entry.successRate, 33.33);
});
+
+const { headersWaitExpiryError } = await import("../../open-sse/executors/opencodeHeadersWait.ts");
+const { sanitizeErrorMessage } = await import("../../open-sse/utils/errorSanitization.ts");
+
+function storedErrorText(value: unknown): string {
+ return sanitizeErrorMessage(sanitizeErrorMessage(value));
+}
+
+test("slow abandoned headers-wait rows leave the transport failures and count separately", async () => {
+ const stored = storedErrorText(headersWaitExpiryError(5000));
+ assert.match(stored, /^OpencodeHeadersWaitTimeout:/);
+ const entry = await seedProxy("Vent Slow", "vent-slow.local", [
+ {
+ id: "log-slow",
+ status: "error",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: "abandoned",
+ error: stored,
+ },
+ ]);
+ assert.equal(entry.transportFailures, 0);
+ assert.equal(entry.slowAbandoned, 1);
+ assert.equal(entry.clientAborted, 0);
+});
+
+test("abandoned client aborts leave the transport failures and count separately", async () => {
+ const stored = storedErrorText(new Error("Request aborted"));
+ assert.match(stored, /Request aborted/);
+ const entry = await seedProxy("Vent Abort", "vent-abort.local", [
+ {
+ id: "log-abort",
+ status: "error",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: "abandoned",
+ error: stored,
+ },
+ ]);
+ assert.equal(entry.transportFailures, 0);
+ assert.equal(entry.slowAbandoned, 0);
+ assert.equal(entry.clientAborted, 1);
+});
+
+test("served client aborts leave the transport failures and count separately", async () => {
+ const stored = storedErrorText("Request aborted");
+ assert.match(stored, /Request aborted/);
+ const entry = await seedProxy("Vent Served", "vent-served.local", [
+ {
+ id: "log-served",
+ status: "error",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: "served",
+ error: stored,
+ },
+ ]);
+ assert.equal(entry.transportFailures, 0);
+ assert.equal(entry.slowAbandoned, 0);
+ assert.equal(entry.clientAborted, 1);
+});
+
+test("abandoned connection errors stay transport failures", async () => {
+ const entry = await seedProxy("Vent Conn", "vent-conn.local", [
+ {
+ id: "log-conn",
+ status: "error",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: "abandoned",
+ error: "fetch failed (cause ECONNREFUSED)",
+ },
+ ]);
+ assert.equal(entry.transportFailures, 1);
+ assert.equal(entry.slowAbandoned, 0);
+ assert.equal(entry.clientAborted, 0);
+});
+
+test("long-ceiling timeouts stay transport failures", async () => {
+ const entry = await seedProxy("Vent Ceil", "vent-ceil.local", [
+ {
+ id: "log-ceil",
+ status: "timeout",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: null,
+ error: "Upstream request did not return response headers after 180000ms (openai/gpt)",
+ },
+ ]);
+ assert.equal(entry.transportFailures, 1);
+ assert.equal(entry.slowAbandoned, 0);
+ assert.equal(entry.clientAborted, 0);
+});
+
+test("transport rate is computed on transport rows only", async () => {
+ const slow = storedErrorText(headersWaitExpiryError(5000));
+ const aborted = storedErrorText(new Error("Request aborted"));
+ const servedAbort = storedErrorText("Request aborted");
+ const entry = await seedProxy("Vent Mix", "vent-mix.local", [
+ {
+ id: "log-mix-slow",
+ status: "error",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: "abandoned",
+ error: slow,
+ },
+ {
+ id: "log-mix-conn",
+ status: "error",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: "abandoned",
+ error: "fetch failed (cause ECONNREFUSED)",
+ },
+ {
+ id: "log-mix-ceil",
+ status: "timeout",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: null,
+ error: "Upstream request did not return response headers after 180000ms (openai/gpt)",
+ },
+ {
+ id: "log-mix-abort",
+ status: "error",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: "abandoned",
+ error: aborted,
+ },
+ {
+ id: "log-mix-served",
+ status: "error",
+ targetUrl: null,
+ upstreamStatus: null,
+ attemptIssue: "served",
+ error: servedAbort,
+ },
+ row("success", 200),
+ ]);
+ assert.equal(entry.transportOk, 1);
+ assert.equal(entry.transportFailures, 2);
+ assert.equal(entry.slowAbandoned, 1);
+ assert.equal(entry.clientAborted, 2);
+ assert.equal(entry.transportRate, 33.33);
+});