Repository navigation
[Feature]: make routed account identity obvious in request logs (which Codex/OpenRouter account served each request) #4057
Description
Area
Multiple areas
What are you trying to accomplish?
I run a provider setup with multiple accounts/credentials behind one provider name: a Codex main+pool, several OpenRouter API keys (free-tier rotation), and chained clients. When debugging quota exhaustion, cache anomalies, or routing behavior, I need to see which specific account served each request directly in the logs — dashboard Logs panel, CLI ocx logs, and usage.jsonl.
What prevents this today?
usage.jsonlhasaccountLogLabel, but it is Codex-only ("main" |p{hex}). Other OAuth providers have no per-account labeling (see closed [Feature]: persist per-account usage for OAuth providers (xai/cursor), not only Codex main/pN labels #2699).- For OpenRouter, multiple API keys under one provider are indistinguishable: the provider field shows only the provider name (e.g.
openrouter), never which key made the upstream call. - The dashboard Logs panel shows model, latency, tokens — but account/credential identity is absent or requires manually cross-referencing
usage.jsonlrows.
What should OpenCodex do?
When a request is routed through a provider that has multiple configured accounts or keys, each log row (dashboard Logs table, ocx logs output, and usage.jsonl) should display a stable per-account label identifying the credential that served the request. A reader should be able to answer "which account handled request X" without reading raw JSONL or the source code.
Example usage or interface
Dashboard Logs table gains an Account column:
| Time | Provider | Model | Account | Tokens | Latency |
|---|---|---|---|---|---|
| 12:01 | openai | gpt-5.6 | p3 |
12k | 2.1s |
| 12:02 | openrouter | free/x | key-2 |
8k | 1.4s |
CLI:
ocx logs --account p3 # filter rows by account label
ocx logs --last 50 --account key-2usage.jsonl row gains a populated accountLogLabel for every multi-account provider (e.g. "accountLogLabel": "key-2" on OpenRouter rows), not just Codex.
Alternatives or workarounds
- Manually grepping
usage.jsonl— only works for Codex rows today. - One provider entry per API key (
openrouter-key1,openrouter-key2) — bloats the provider catalog and breaks free-tier rotation logic. - feat(pricing): apply base-provider price overlays to all account log labels #3817 (closed) improved price overlays for account log labels — the labeling machinery exists, it just does not cover non-Codex providers or surface in the UI.
Additional context
- [Feature]: persist per-account usage for OAuth providers (xai/cursor), not only Codex main/pN labels #2699 (closed) — per-account usage persistence for OAuth providers; this request extends the same gap to log visibility.
- [Bug]: Intermittent consecutive zero cache hits for Hermes requests through OpenCodeX #3433 (open) — intermittent zero cache hits; account identity in logs would make such debugging tractable.
- [Bug]: Weekly-exhausted Codex account never rotates — incomplete quota terminal recorded as success (2.43.0) #3795 / [Bug]: 2.42.0 Plus quota exhaustion causes 18 incomplete failures without switching to main (related to #3795) #3994 (open) — quota exhaustion bugs where "which account served this" is the first diagnostic question.
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
Activity
github-actions commentedon Sep 8, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
lidge-jun commentedon Sep 8, 2026
리뷰 · 우선순위 52 / 80
이 이슈는 한 provider 이름 뒤에 여러 자격 증명이 있을 때, 요청 로그에서 “이번 요청은 어느 계정/키가 처리했는가”를 바로 보고 싶다는 관측성 요청입니다. 작성자는 Codex main+pool, OpenRouter API 키 여러 개(무료 티어 로테이션), 체인 클라이언트를 같이 돌립니다. 쿼터 고갈·캐시 이상·라우팅을 디버깅할 때 dashboard Logs,
ocx logs,usage.jsonl에서 계정 정체를 한눈에 보고 싶어 합니다. 제안 UI는 Logs 표에 Account 열, CLI--account필터, 그리고 multi-account provider마다accountLogLabel을 채우는 것입니다.지금
devHEAD(164bd2b36, package 2.49.0, tip #4053)를 기준으로 보면, 이슈 본문의 “OAuth는 라벨이 없다 / Codex만 있다” 문장은 이미 절반 이상 낡았습니다. #2699가 들어와UsageAccountLogLabel은main|p<hex6>|o<hex6>세 가족을 받습니다.isCodexUsageAccountLogLabel이름만 Codex처럼 남아 있고, 실제 persistence 게이트는o라벨도 통과시킵니다. non-Codex OAuth는stampOAuthAccountLabel(src/providers/label.ts)이authMode === "oauth"이고 openai/anthropic이 아닐 때o{sha256(provider\\0accountId)[:6]}를 찍고,core.tsadmission/resolve 경로에서 호출됩니다. Codex는 여전히codexAuthContextLogLabel로main/p…를 찍습니다. #3817(닫힘)은 가격 오버레이가 이 라벨 가족을 따라가도록 맞춘 후속입니다.진짜 남은 구멍은 API-key pool(특히 OpenRouter) 쪽입니다.
apiKeyPool항목은id+ optionallabel을 갖고(src/types/provider.ts,src/providers/api-keys.ts),key-failover.ts는 429/401 때failedId/candidateId로 키를 돌립니다. 그런데stampOAuthAccountLabel은 oauth만 스탬프하고, key-auth 경로에는 “이번 요청에 쓴 pool entry id/label → accountLogLabel” 연결이 없습니다.usage.jsonl//api/logs의apiKeyId필드는 주석상 데이터플레인 입장(admission)용 configured key id이지 OpenRouter upstream 키 id가 아닙니다. 그래서 provider 칸에openrouter만 보이고 “key-2가 서빙했다”는 답을 JSONL에서도 못 얻는 체감은 맞습니다.UI/CLI 면도 이슈 주장과 맞습니다.
gui/src/pages/Logs.tsx의LogEntry/LogAttempt타입에accountLogLabel이 없고,logs-filter-bar.tsx필터도 provider/model/time/status/conversation만 있습니다. 서버가 행에accountLogLabel을 실어 줘도(요청 로그 persistence는 이미 조건부로 넣음) 대시보드는 Account 열을 그리지 않습니다.ocx logs(src/cli/observe.ts)도--account필터가 없습니다. 다만 사람이 읽기 쉬운key-2같은 문자열을 그대로 로그에 박자는 제안은, 현재 라벨이 이메일/원시 id를 쓰지 않는 digest인 프라이버시 계약(src/codex/account-label.ts주석)과 충돌합니다. 운영자label을 그대로 노출할지,k<hex6>같은 새 가족을 둘지는 설계 선택입니다.관련 이슈: #3433(캐시 이상 디버깅), #3994(쿼터 소진 진단), #4024(OpenRouter free 쿼터 park)는 같은 운영 스토리의 이웃이지 중복이 아닙니다. #4024는 “죽은 키를 얼마나 오래 쉴지”이고, 이 이슈는 “어느 키가 실제로 나갔는지 로그에 남기기”입니다. conversation affinity / pool / quota 작업이 HEAD에 이미 무거운 상태에서, 2.49.x 마감용으로는 관측성 보강이지 블로커가 아닙니다. naive PR이
config.ts/types.ts에 큰 스키마를 끼워 넣으면 types/config 분할 캠페인에 무효화될 수 있으니, 라벨 가족·필터만 건드리는 얇은 PR이 안전합니다.경로
src/usage/log.tsUsageAccountLogLabel / isCodexUsageAccountLogLabel - #2699 이후o<hex6>도 persistence 통과. “Codex-only” 서술은 구버전 진단경로
src/providers/label.tsstampOAuthAccountLabel - oauth만 스탬프. OpenRouter 등 key-auth apiKeyPool은 대상 밖경로
src/providers/key-failover.ts/src/providers/api-keys.ts- 키 id·label·회전은 있으나 request log에 account 정체로 안 실림경로
src/server/request-log.tsapiKeyId 주석 - admission configured key용. upstream pool key와 이름만 비슷하고 의미가 다름경로
gui/src/pages/Logs.tsxLogEntry - accountLogLabel 필드·Account 열·필터 없음. Codexp…/main도 UI에 안 보임경로
src/cli/observe.ts-ocx logs --account없음이슈 예시
key-2- 사람이 읽기 쉬운 label 직접 기록은 digest-only 프라이버시 계약과 충돌 가능메인테이너의 판단이 필요한 지점
o/p에 맞춘k<hex6>(provider\\0keyId)vs 운영자apiKeyPool[].label그대로(마스킹/길이 제한 필요)--account가 usage summary attribution과 같은 필터 축을 쓸지, request-log ring만 볼지너의 추천
enhancement로 유지하고 design-first. 닫지 마세요(중복 아님). 1단계: 이미 찍히는
main/p…/o…를 Logs 표·상세·ocx logs에 보이게 하고(필터 포함). 2단계: key-authapiKeyPool에 digest 라벨 스탬프를 oauth와 같은 persistence 게이트로 넣기. 사람이 붙인key-2문자열을 JSONL에 그대로 쓰지 말고, UI에서 poollabel로 조인 표시하는 편이 프라이버시·안정성에 맞습니다.dashboard.*/ 큰 config 스키마 PR은 types/config 분할과 겹치면 close-don't-rebase. 2.49.x 블로커로 끌어올리지 말고, #4024 재현 패킷이 오면 같은 OpenRouter 운영 묶음으로 리뷰하면 됩니다.이 댓글은 grok-bot이 작성했습니다
Merge pull request #4134 from lidge-jun/codex/log-account-identity-4057
feat(logs): surface and filter the routed account label per request
lidge-jun commentedon Sep 9, 2026
Landed via #4134 at 7dd50ea
feat(logs): surface and filter the routed account label per request
Merge pull request lidge-jun#4134 from lidge-jun/codex/log-account-id…