mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
feat(usage): show cancelled and incomplete requests separately
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -23,8 +23,7 @@
|
||||
"empty": "No requests in this range",
|
||||
"errors": "Errors",
|
||||
"noSamples": "No samples",
|
||||
"completionRate": "Completion",
|
||||
"abnormalEnd": "Abnormal"
|
||||
"completionRate": "Completion"
|
||||
},
|
||||
"billing": {
|
||||
"serviceLevel": "Service tier",
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
"empty": "当前范围暂无请求",
|
||||
"errors": "错误",
|
||||
"noSamples": "无样本",
|
||||
"completionRate": "完成率",
|
||||
"abnormalEnd": "非正常结束"
|
||||
"completionRate": "完成率"
|
||||
},
|
||||
"billing": {
|
||||
"serviceLevel": "服务档位",
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
"empty": "當前範圍暫無請求",
|
||||
"errors": "錯誤",
|
||||
"noSamples": "無樣本",
|
||||
"completionRate": "完成率",
|
||||
"abnormalEnd": "非正常結束"
|
||||
"completionRate": "完成率"
|
||||
},
|
||||
"billing": {
|
||||
"serviceLevel": "服務檔位",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { BarSeriesOption, EChartsOption, LineSeriesOption } from 'echarts'
|
||||
import type { EChartsOption } from 'echarts'
|
||||
|
||||
import type { getUsageRecordInsightsOverview } from '@/api'
|
||||
import { ZCard, ZEmpty } from '@codex-proxy/ui'
|
||||
@@ -16,7 +16,6 @@ import { formatLocalizedCompactNumber as formatCompactNumber, formatPercent } fr
|
||||
|
||||
import {
|
||||
usageCategoryAxis,
|
||||
usageGapAwareLineSeries,
|
||||
usageLegend,
|
||||
usageTooltip,
|
||||
usageTooltipItem,
|
||||
@@ -67,28 +66,12 @@ const description = computed(() => props.loading || !granularityText.value
|
||||
const chartOption = computed<EChartsOption>(() => {
|
||||
const theme = palette.value
|
||||
const chartPoints = points.value
|
||||
const activePointCount = chartPoints.filter(point => requestCount(point) > 0).length
|
||||
const successRateSeries = usageGapAwareLineSeries(
|
||||
t('usage.health.serviceSuccessRate'),
|
||||
chartPoints.map(serviceSuccessRate),
|
||||
theme.success,
|
||||
{ yAxisIndex: 1 },
|
||||
)
|
||||
const series: Array<BarSeriesOption | LineSeriesOption> = [
|
||||
const series = [
|
||||
outcomeSeries(t('common.status.success'), chartPoints.map(point => point.successRequests), theme.success),
|
||||
outcomeSeries(t('usage.health.point.serviceFailed'), chartPoints.map(point => point.failedRequests), theme.danger),
|
||||
outcomeSeries(t('usage.status.cancelled'), chartPoints.map(point => point.cancelledRequests), theme.info),
|
||||
outcomeSeries(t('usage.health.notCompleted'), chartPoints.map(point => point.incompleteRequests), theme.warning),
|
||||
outcomeSeries(t('usage.health.point.callerError'), chartPoints.map(point => point.callerErrorRequests), theme.normal),
|
||||
...successRateSeries.map((item, index) => index === 0
|
||||
? {
|
||||
...item,
|
||||
symbol: activePointCount <= 16
|
||||
? 'circle'
|
||||
: 'none',
|
||||
symbolSize: 4,
|
||||
}
|
||||
: item),
|
||||
]
|
||||
|
||||
return {
|
||||
@@ -101,27 +84,13 @@ const chartOption = computed<EChartsOption>(() => {
|
||||
outerBoundsMode: 'same',
|
||||
outerBoundsContain: 'axisLabel',
|
||||
},
|
||||
legend: usageLegend(theme, [
|
||||
t('common.status.success'),
|
||||
t('usage.health.point.serviceFailed'),
|
||||
t('usage.status.cancelled'),
|
||||
t('usage.health.notCompleted'),
|
||||
t('usage.health.point.callerError'),
|
||||
t('usage.health.serviceSuccessRate'),
|
||||
]),
|
||||
legend: usageLegend(theme, series.map(item => item.name)),
|
||||
tooltip: usageTooltip(theme, formatTooltip),
|
||||
xAxis: usageCategoryAxis(
|
||||
chartPoints.map(point => point.label),
|
||||
theme,
|
||||
),
|
||||
yAxis: [
|
||||
usageValueAxis(theme, value => formatCompactNumber(value)),
|
||||
usageValueAxis(theme, value => formatPercent(value), {
|
||||
min: 0,
|
||||
max: 1,
|
||||
splitLine: false,
|
||||
}),
|
||||
],
|
||||
yAxis: usageValueAxis(theme, value => formatCompactNumber(value)),
|
||||
series,
|
||||
}
|
||||
})
|
||||
@@ -130,10 +99,10 @@ function requestCount(point: HealthPoint) {
|
||||
return Math.max(0, point.totalRequests ?? 0)
|
||||
}
|
||||
|
||||
function serviceSuccessRate(point: HealthPoint) {
|
||||
return point.errorRate == null
|
||||
? null
|
||||
: 1 - point.errorRate
|
||||
function serviceSuccessRateText(rate: number | null) {
|
||||
return rate == null
|
||||
? t('usage.noValidSample')
|
||||
: formatPercent(rate)
|
||||
}
|
||||
|
||||
function outcomeSeries(name: string, data: number[], color: string) {
|
||||
@@ -153,7 +122,6 @@ function formatTooltip(params: unknown) {
|
||||
if (!point)
|
||||
return ''
|
||||
|
||||
const successRate = serviceSuccessRate(point)
|
||||
const theme = palette.value
|
||||
|
||||
return chartTooltipContent(point.label, [
|
||||
@@ -165,9 +133,7 @@ function formatTooltip(params: unknown) {
|
||||
usageTooltipItem(t('usage.health.point.callerError'), formatCompactNumber(point.callerErrorRequests), theme.normal),
|
||||
usageTooltipItem(
|
||||
t('usage.health.serviceSuccessRate'),
|
||||
successRate == null
|
||||
? t('usage.health.noSamples')
|
||||
: formatPercent(successRate),
|
||||
serviceSuccessRateText(point.errorRate == null ? null : 1 - point.errorRate),
|
||||
theme.success,
|
||||
),
|
||||
])
|
||||
@@ -183,11 +149,11 @@ function formatTooltip(params: unknown) {
|
||||
>
|
||||
<template #body>
|
||||
<div class="grid min-h-66" :class="hasData ? 'gap-3' : 'h-full'">
|
||||
<div v-if="hasData && health" class="grid grid-cols-3 gap-2 rounded-xl bg-z-fill-quaternary/45 p-2">
|
||||
<div v-if="hasData && health" class="grid grid-cols-2 gap-2 rounded-xl bg-z-fill-quaternary/45 p-2 sm:grid-cols-4">
|
||||
<div class="grid gap-1 px-2">
|
||||
<span class="text-[10px] font-bold text-z-text-quaternary">{{ t('usage.health.serviceSuccessRate') }}</span>
|
||||
<strong class="font-mono text-z-base font-heavy tabular-nums text-z-green-text">
|
||||
{{ formatPercent(health.successRate) }}
|
||||
{{ serviceSuccessRateText(health.successRate) }}
|
||||
</strong>
|
||||
</div>
|
||||
<div class="grid gap-1 px-2">
|
||||
@@ -197,9 +163,15 @@ function formatTooltip(params: unknown) {
|
||||
</strong>
|
||||
</div>
|
||||
<div class="grid gap-1 px-2">
|
||||
<span class="text-[10px] font-bold text-z-text-quaternary">{{ t('usage.health.abnormalEnd') }}</span>
|
||||
<span class="text-[10px] font-bold text-z-text-quaternary">{{ t('usage.status.cancelled') }}</span>
|
||||
<strong class="font-mono text-z-base font-heavy tabular-nums text-z-blue-text">
|
||||
{{ formatCompactNumber(health.cancelledRequests) }}
|
||||
</strong>
|
||||
</div>
|
||||
<div class="grid gap-1 px-2">
|
||||
<span class="text-[10px] font-bold text-z-text-quaternary">{{ t('usage.health.notCompleted') }}</span>
|
||||
<strong class="font-mono text-z-base font-heavy tabular-nums text-z-orange-text">
|
||||
{{ formatCompactNumber(health.cancelledRequests + health.incompleteRequests) }}
|
||||
{{ formatCompactNumber(health.incompleteRequests) }}
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user