feat: Prometheus-метрики GET /metrics + ленивый ISO-8601-парсер для backoff
Build LLM Proxy / Build and push (release) Successful in 40s
Build LLM Proxy / Build and push (release) Successful in 40s
- GET /metrics (Prometheus text 0.0.4): llm_proxy_requests_total{model,upstream,provider,result}
(ok/4xx/429/402/5xx/net_err/cancelled), llm_proxy_upstream_inflight,
llm_proxy_upstream_fail_streak, llm_proxy_upstream_cooling_seconds
- учёт исходов в handleChat (каждая фейловер-попытка — отдельно)
- parseIsoDuration: PnM≈n×30d, PnY≈n×365d (kotlin.time Duration.parse не принимает Y/M)
- remainingSeconds округляет остаток вверх (открытое окно ≥1s)
- доки (CONFIG.md/README/TESTING) + тесты (MetricsTest, BackoffTest)
This commit is contained in:
@@ -4,11 +4,13 @@ import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFails
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.days
|
||||
import kotlin.time.Duration.Companion.hours
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
@@ -53,6 +55,26 @@ class BackoffTest {
|
||||
assertEquals(90.seconds, Duration.parse("PT1M30S"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDurationParsingWithYearsAndMonths() {
|
||||
// kotlin.time не принимает Y/M — конфиг-парсер расширяет: 1Y≈365d, 1M≈30d
|
||||
assertEquals(30.days, parseIsoDuration("P1M"))
|
||||
assertEquals(365.days, parseIsoDuration("P1Y"))
|
||||
assertEquals(455.days, parseIsoDuration("P1Y3M"))
|
||||
assertEquals(7.days, parseIsoDuration("P1W"))
|
||||
assertEquals(2.days + 3.hours + 15.minutes, parseIsoDuration("P2DT3H15M"))
|
||||
// базовый ISO-8601 без Y/M — как kotlin.time
|
||||
assertEquals(30.minutes, parseIsoDuration("PT30M"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDurationParsingRejectsGarbage() {
|
||||
assertFails { parseIsoDuration("PT30") }
|
||||
assertFails { parseIsoDuration("1d") }
|
||||
assertFails { parseIsoDuration("P") }
|
||||
assertFails { parseIsoDuration("") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun providerScopeSharedBetweenItsModels() = runTest {
|
||||
val p = ProviderConf(id = "p", url = "https://p", backoff = 5.minutes)
|
||||
|
||||
Reference in New Issue
Block a user