# OpenAI-compatible Usage – Grafana Query Guide > **Purpose**: 이 문서는 운영자가 Prometheus metric을 Grafana 패널로 조회해 사용자별 OpenAI-compatible token 사용량을 볼 수 있도록 한다. Control Plane/Client dashboard, request-level ledger, 사용자별 제한 enforcement는 만들지 않는다. --- ## Metric 목록 ### 1. `iop_openai_usage_tokens_total` (Counter) Provider-reported OpenAI-compatible token usage by token type. | Label | Value 예시 | 설명 | |-------|-----------|------| | `edge_id` | `edge-1` | Edge instance identity | | `principal_ref` | `usr-abc123` | Principal foreign-key-like reference | | `principal_alias` | `john@acme` | Human-readable alias | | `token_ref` | `tok-xyz789` | Token identity (not a raw secret) | | `model_group` | `gpt-4o` | Model group identifier | | `endpoint` | `chat.completions`, `responses` | OpenAI-compatible route | | `response_mode` | `blocking`, `streaming` | Response mode | | `token_type` | `input`, `output`, `reasoning`, `cached_input` | Token type | ### 2. `iop_openai_requests_total` (Counter) OpenAI-compatible requests processed by terminal status and usage source. | Label | Value 예시 | 설명 | |-------|-----------|------| | `edge_id` | `edge-1` | Edge instance identity | | `principal_ref` | `usr-abc123` | Principal reference | | `principal_alias` | `john@acme` | Human-readable alias | | `token_ref` | `tok-xyz789` | Token identity | | `model_group` | `gpt-4o` | Model group identifier | | `endpoint` | `chat.completions`, `responses` | OpenAI-compatible route | | `response_mode` | `blocking`, `streaming` | Response mode | | `status` | `success`, `error`, `cancel` | Terminal request status | | `usage_source` | `provider_reported`, `unavailable` | Whether at least one token type was reported | ### 3. `iop_openai_reasoning_observed_total` (Counter) Requests where reasoning text was observed but the provider did not report reasoning token usage. Same labels as `iop_openai_requests_total` excluding `status` and `usage_source`: `edge_id`, `principal_ref`, `principal_alias`, `token_ref`, `model_group`, `endpoint`, `response_mode`. ### 4. `iop_openai_reasoning_chars_total` (Counter) Observed reasoning text characters for requests without provider-reported reasoning tokens. Never converted to a token estimate. --- ## Label Allowlist & Forbidden Labels ### 허용 label ``` edge_id, principal_ref, principal_alias, token_ref, model_group, endpoint, response_mode, status, token_type, usage_source ``` ### 금지 label - `request_id`, `session_id` — request-level 상세는 후속 ledger/Loki 축에서 다룬다. - Bearer token, provider API key, raw payload, raw prompt/response text — secret 누출 방지 (SDD S08). - 그 외 임의 label — cardinality 폭발을 막는다. --- ## PromQL Examples ### 기본: 사용자별 사용량 (principal_alias 기준) ```promql # 입력 토큰 합계 sum by (principal_alias) (iop_openai_usage_tokens_total{token_type="input"}) # 출력 토큰 합계 sum by (principal_alias) (iop_openai_usage_tokens_total{token_type="output"}) ``` ### principal_ref별 usage breakdown ```promql # principal_ref, token_type별 aggregation sum by (principal_ref, token_type) (iop_openai_usage_tokens_total) ``` ### token_ref별 사용량 ```promql # token_ref별 input/output 합계 sum by (token_ref, token_type) (iop_openai_usage_tokens_total) ``` ### model_group별 usage ```promql # model_group, token_type별 aggregation sum by (model_group, token_type) (iop_openai_usage_tokens_total) ``` ### endpoint별 요청 수 ```promql # endpoint, status별 요청 수 sum by (endpoint, status) (iop_openai_requests_total) ``` ### response_mode별 분석 ```promql # response_mode별 성공 요청 수 sum by (response_mode, status) (iop_openai_requests_total{status="success"}) ``` ### token_type별 사용량 전체 ```promql # 모든 token_type별 합계 (time range 그래프용) sum by (token_type) (irate(iop_openai_usage_tokens_total[5m])) ``` ### usage_source별 요청 coverage ```promql # provider_reported vs unavailable 비율 sum by (usage_source) (iop_openai_requests_total) ``` ### reasoning 보조 metric provider가 reasoning token을 보고하지 않는 경우: ```promql # reasoning text가 관찰된 요청 수 (provider token 미보고) sum by (principal_alias) (iop_openai_reasoning_observed_total) # reasoning text character 합계 sum by (principal_alias) (iop_openai_reasoning_chars_total) ``` > **주의**: `iop_openai_reasoning_observed_total` / `iop_openai_reasoning_chars_total`는 provider-reported reasoning token이 있을 경우 emit되지 않는다. 즉, 이 metric은 "reasoning text는 있으나 token count 보고를 안 하는 provider"만 커버한다. token 추정을 위해 chars를 사용할 수 있으나 이 문서는 추정 권유를 하지 않는다. --- ## Dashboard Panel 후보 | 패널 | query | visualization | |------|-------|---------------| | 사용자별 token 사용량 (line) | `sum by (principal_alias, token_type) (irate(iop_openai_usage_tokens_total[5m]))` | Time series, legend=`{{principal_alias}} {{token_type}}` | | model_group별 token 비율 (pie) | `sum by (model_group, token_type) (iop_openai_usage_tokens_total)` | Stat or bar chart | | 요청 상태 분포 (table) | `sum by (endpoint, status, usage_source) (iop_openai_requests_total)` | Table | | reasoning 보조 지표 (singlestat) | `sum(iop_openai_reasoning_observed_total)` | Singlestat | > Grafana JSON dashboard import file은 본 scope에 포함되지 않는다. 위 PromQL을 바탕으로 패널을 수동 구성한다. --- ## daily / monthly Rollup ### 일일 토큰 합계 ```promql # 일일 입력/출력 토큰 합계 (principal_alias별) sum by (principal_alias, token_type) ( increase(iop_openai_usage_tokens_total[1d]) ) ``` > Grafana dashboard에서 `by time` aggregation으로 대체 가능: > ```promql > # Grafana 범용 aggregation (PromQL 함수 아님) > # time range를 1일로 설정 후 sum by (principal_alias, token_type) > iop_openai_usage_tokens_total > ``` ### 월간 토큰 합계 ```promql # 월간 입력/출력 토큰 합계 (principal_alias별) sum by (principal_alias, token_type) ( increase(iop_openai_usage_tokens_total[30d]) ) ``` > Grafana dashboard에서 범용 aggregation으로 대체 가능: > ```promql > # Grafana 범용 aggregation (PromQL 함수 아님) > # time range를 30일로 설정 후 sum by (principal_alias, token_type) > iop_openai_usage_tokens_total > ``` ### 일일/월간 rollup 활용 시나리오 - `principal_alias` 또는 `principal_ref`를 `by` clause에 추가해 사용자별 일일/월간 토큰 사용량을 산출한다. - `token_type`을 함께 group by하면 input/output/reasoning/cached_input을 구분한다. - `model_group`을 추가하면 모델별 비용 기반 추정 가능하다 (billing 산출은 이 문서 범위를 벗남). --- ## Limit Follow-up: 경계 명시 ### 후속 Milestone으로 남기는 항목 - 사용자별 daily/monthly token **warn** 또는 **reject** enforcement는 이 Milestone의 범위가 아니며 후속 Milestone으로 Planned된다. - billing, price, ROI amount 산출은 별도 ledger/cost model 범위다. - request-level ledger / audit log는 Loki/queriable log축 후속 작업의 대상이다. ### 현재 문서가 제공하는 것 - `principal_ref`, `token_ref`, `model_group`, `token_type` 라벨 기반 daily/monthly rollup PromQL - 사용자별 사용량 조회를 통한 운영 판단 기준 - provider reasoning report 누락 시 `reasoning_observed_total` / `reasoning_chars_total`로 보조 확인 이 rollup 기준은 후속 enforce Milestone에서 Prometheus query를 그대로 재사용할 수 있도록 설계되었다. --- ## Quick Reference: Label Values | Label | 허용 값 | |-------|---------| | `endpoint` | `chat.completions`, `responses` | | `status` | `success`, `error`, `cancel` | | `usage_source` | `provider_reported`, `unavailable` | | `token_type` | `input`, `output`, `reasoning`, `cached_input` | | `response_mode` | `blocking`, `streaming` | --- ## Appendix: Grafana Scrape Target Edge metrics는 보통 `localhost:19092` (local) 또는 해당 Edge metrics port에서 Prometheus scrape된다. Grafana data source에 Prometheus를 추가하고 위 PromQL을 테스트 패널에서 검증한다.