bug: Ring and ledger count errors and coverage differently, cost reads slow down over time, and cost comments are stale
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 49/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- go
- Área
- backend, databases, performance
Línea de trabajo
Start with core/cost/usage/usage.go and core/cost/ledger/writer.go to compare the error and priceability rules, then inspect the archive read and write paths in core/session/archive and ledger queries in core/cost/ledger. Add or update focused tests for zero-usage successful responses, excluded errors, archive rotation and reads, and past-day caching. Done means the ledger and ring agree, archive reads avoid repeatedly decoding growing segments, and stale comments match the code.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Problem
The cost and session read paths have three problems. The ring (which serves the duration windows) and the ledger (which serves today/7d/month) count the same traffic by different rules. Two read paths get slower the longer the proxy runs. And several comments in core/cost describe code that has since changed. Line numbers are at ab5f01f26.
1. The ledger hides a coverage gap that the ring reports
- Ledger (
core/cost/ledger/writer.go:519-521): a request counts as priceable only ifr.Model != "" && r.Tokens > 0. - Ring (
core/cost/usage/usage.go:812-840): any successful response with a model counts as priceable, even with zero usage, and it is named inUnpricedBy.
Case: a truncated OpenAI-dialect stream returns 200, the model is set, and there is no usage block. inference-parser publishes no cost record for it. With 9 priced requests plus one of these:
window=todayshows 9/9, which looks fully priced.window=1hshows 9/10 and names the gap.
The ring's own comment (usage.go:821-825) calls the 9/9 result a bug it fixed. There is no ledger test for a successful response with zero usage.
2. The error rule is written twice, and only one copy was updated
countsAsError(usage.go:1279-1285) excludesErrorKindUpgradeDeclinedandErrorKindDestinationPrivate. The latter was added in ab5f01f26.- The ledger (
writer.go:514-516) still counts anyStatusCode >= 400 || Denied.
So a parsed inference request refused with 403 destination_private counts as an error on today but not on 1h.
Fix for 1 and 2: export usage.CountsAsError and a single "priceable" check, and call both from the ledger writer.
3. Archive segments never rotate, and every read decodes from the start
core/session/archive/archive.go: a segment closes only after 60 minutes idle (:736), at the open-writer cap, or on delete, clear, rename or a write failure. There is no size or event-count limit.
planPrunenever deletes an open segment (retention.go:54-63). A session busy all day therefore keeps one segment growing without limit, andmaxBytes(2 GiB) can stay exceeded.PageandEventdecode the segment from its first event up to the cursor, andEarliercallsPageonce per 500 events (read.go:44-81, 189-203). inference-router'swentTocallsEarlieron the request path withhistoryLimit = 2000. With 20k events in the segment, that is 4 page calls, each decompressing and decoding most of the segment, per request.
Fix: rotate in write after N events or M bytes, by calling closeWriter when s.w.info() passes the cap.
4. Every ledger query re-reads every day file in the window
core/cost/ledger/query.go:183-250 / store.go:493-530 open and fully decode each day file on every request, with no cache.
- agentop polls
todayevery minute and7d/monthevery 5 minutes (cmd/agentop/tui/spend.go:211-217). On the 31st,monthdecodes 31 files per poll, and past days almost never change. - The endpoint has no auth.
Fix: cache decoded past days keyed by (path, size, mtime). Only today's file needs re-reading.
5. Comments that contradict the code
core/cost/pricing/cost.go:20-25calls the accumulation wrap "an open defect", butCounts.Addsaturates (usage.go:349-405).cost.go:93-99saysMaxPlausibleTokenshas "NO IMPORTER ON THIS BRANCH". The ledger writer imports it (writer.go:288-324).cost.go:202-204saysplausibleTokenReportandRefusedTokenRequestsdon't exist. They do (usage.go:438, :122).ledger/writer.go:929-933saysDropped()has "No non-test caller today".sessionapi/usage.go:404calls it.
These read like notes from the middle of a PR stack. A reader trusting them would conclude that sums can still wrap and that the token bounds are not enforced.
Fix: delete or correct them.
Found by a code audit of main at ab5f01f26. Items 3 and 4 were verified by reading the code; the decode cost was not measured.
Assisted-By: Claude (Anthropic AI) [email protected]
- Lenguaje dominante
- Go
- Estrellas
- 21
- Forks
- 43
- Merge medio
- 15 h 38 min
- PR fusionados (30 d)
- 234
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de rossoctl/cortex
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
UI shows costs for all sessions even when drilled into a sessionPosiblemente ocupada @esnible la tomó hace 19 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
rossoctl/cortex#1116 · 2 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
bug: install-stats by-release table credits smoke installs to the newest-published release, not the one installedPosiblemente ocupada @Alan-Cha la tomó hoy. Abiertobug
Dificultad 3/5 Medio día Aptitud para principiantes 42/100
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 60/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 Más de una semana Aptitud para principiantes 18/100
Los mantenedores suelen responder en 1 día
Todos los issues de rossoctl/cortex
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
limitlessprojects/Go-Hybrid#3342 ·
Los mantenedores suelen responder en 1 día
-
status/ready type/bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
buildpacks/pack#2733 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
kind/bug needs-priority needs-triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
konveyor/tackle2-hub#1166 · 1 comentario ·
Los mantenedores suelen responder en 4 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
router-for-me/CLIProxyAPI#7209 ·
Los mantenedores suelen responder en 1 día